diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
new file mode 100644
index 00000000..ce3a708d
--- /dev/null
+++ b/.github/workflows/e2e.yml
@@ -0,0 +1,59 @@
+# Copyright 2024 NVIDIA CORPORATION
+#
+# 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.
+
+name: End-to-end Tests
+
+on:
+ workflow_run:
+ workflows: [Image]
+ types:
+ - completed
+ branches:
+ - main
+ - release-*
+
+jobs:
+ e2e-tests:
+ runs-on: ubuntu-latest
+ if: ${{ github.event.workflow_run.conclusion == 'success' }} && ${{ github.event.workflow_run.event == 'push' }}
+ steps:
+ - uses: actions/checkout@v4
+ name: Check out code
+ - name: Calculate build vars
+ id: vars
+ run: |
+ echo "COMMIT_SHORT_SHA=${GITHUB_SHA:0:8}" >> $GITHUB_ENV
+ - name: Set up Holodeck
+ uses: NVIDIA/holodeck@v0.2.2
+ with:
+ vsphere_username: ${{ secrets.VSPHERE_USERNAME }}
+ vsphere_password: ${{ secrets.VSPHERE_PASSWORD }}
+ vsphere_ssh_key: ${{ secrets.VSPHERE_SSH_KEY }}
+ holodeck_config: "tests/e2e/infra/aws.yaml"
+ - name: Run e2e tests
+ env:
+ KUBECONFIG: ${{ github.workspace }}/kubeconfig
+ E2E_IMAGE_REPO: ghcr.io/nvidia/k8s-nim-operator
+ E2E_IMAGE_TAG: ${COMMIT_SHORT_SHA}
+ LOG_ARTIFACTS: ${{ github.workspace }}/e2e_logs
+ NGC_API_KEY: ${{ secrets.NGC_API_KEY }}
+ run: |
+ ./hack/e2e_tests.sh
+ - name: Archive test logs
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: e2e-test-logs
+ path: ./e2e_logs/
+ retention-days: 15
diff --git a/Makefile b/Makefile
index 59bc39ca..eade9c1c 100644
--- a/Makefile
+++ b/Makefile
@@ -23,6 +23,8 @@ PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
# Import versions
include $(CURDIR)/versions.mk
+GINKGO_VERSION ?= $(shell $(GO_CMD) list -m -f '{{.Version}}' github.com/onsi/ginkgo/v2)
+
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
@@ -229,6 +231,11 @@ golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
$(GOLANGCI_LINT): $(LOCALBIN)
$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,${GOLANGCI_LINT_VERSION})
+GINKGO = $(PROJECT_DIR)/bin/ginkgo
+.PHONY: ginkgo
+ginkgo: ## Download ginkgo locally if necessary.
+ @GOBIN=$(PROJECT_DIR)/bin GO111MODULE=on $(GO_CMD) install github.com/onsi/ginkgo/v2/ginkgo@$(GINKGO_VERSION)
+
# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
# $1 - target path with name of binary (ideally with version)
# $2 - package url which can be installed
diff --git a/go.mod b/go.mod
index 60ec2ad3..32cfcab3 100644
--- a/go.mod
+++ b/go.mod
@@ -7,6 +7,7 @@ toolchain go1.22.5
require (
github.com/Masterminds/sprig/v3 v3.2.3
github.com/NVIDIA/k8s-test-infra v0.0.0-20240806103558-2d7411125519
+ github.com/go-git/go-git/v5 v5.12.0
github.com/go-logr/logr v1.4.2
github.com/mittwald/go-helm-client v0.12.12
github.com/onsi/ginkgo/v2 v2.19.1
@@ -15,6 +16,7 @@ require (
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.75.2
github.com/stretchr/testify v1.9.0
gopkg.in/yaml.v2 v2.4.0
+ helm.sh/helm/v3 v3.15.2
k8s.io/api v0.30.3
k8s.io/apiextensions-apiserver v0.30.2
k8s.io/apimachinery v0.30.3
@@ -25,6 +27,7 @@ require (
)
require (
+ dario.cat/mergo v1.0.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
@@ -32,11 +35,14 @@ require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
+ github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.4 // indirect
+ github.com/ProtonMail/go-crypto v1.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
+ github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/containerd v1.7.12 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
@@ -49,6 +55,7 @@ require (
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.1 // indirect
+ github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
@@ -56,6 +63,8 @@ require (
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-errors/errors v1.5.1 // indirect
+ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
+ github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
@@ -83,9 +92,11 @@ require (
github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
+ github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
@@ -110,6 +121,7 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc6 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
+ github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.18.0 // indirect
@@ -119,11 +131,14 @@ require (
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rubenv/sql-migrate v1.6.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
+ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
+ github.com/skeema/knownhosts v1.2.2 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
+ github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
@@ -137,6 +152,7 @@ require (
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
+ golang.org/x/mod v0.19.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
golang.org/x/sync v0.7.0 // indirect
@@ -152,8 +168,8 @@ require (
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/evanphx/json-patch.v5 v5.7.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
+ gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- helm.sh/helm/v3 v3.15.2 // indirect
k8s.io/apiserver v0.30.2 // indirect
k8s.io/cli-runtime v0.30.0 // indirect
k8s.io/component-base v0.30.2 // indirect
diff --git a/go.sum b/go.sum
index e2eea8c0..a5663770 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,5 @@
+dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
+dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
@@ -17,16 +19,21 @@ github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
+github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
github.com/NVIDIA/k8s-test-infra v0.0.0-20240806103558-2d7411125519 h1:vNFmX59V9hnCU2ssRBrxoiWtjKbpMbRyRLGtdCKJOuc=
github.com/NVIDIA/k8s-test-infra v0.0.0-20240806103558-2d7411125519/go.mod h1:swNnqbpmX/Xke6CaW7C+XbWJPy8hDs3IA//xPIHBV98=
+github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
+github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
@@ -43,10 +50,14 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
+github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
+github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
+github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
+github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0=
@@ -84,8 +95,12 @@ github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQ
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
+github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
+github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/emicklei/go-restful/v3 v3.11.1 h1:S+9bSbua1z3FgCnV0KKOSSZ3mDthb5NyEPL5gEpCvyk=
github.com/emicklei/go-restful/v3 v3.11.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
+github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
@@ -102,8 +117,18 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
+github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
+github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
+github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
+github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
+github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -188,6 +213,8 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -197,14 +224,19 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
+github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/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/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=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
@@ -279,6 +311,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
+github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
+github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -316,14 +350,17 @@ github.com/rubenv/sql-migrate v1.6.0 h1:IZpcTlAx/VKXphWEpwWJ7BaMq05tYtE80zYz+8a5
github.com/rubenv/sql-migrate v1.6.0/go.mod h1:m3ilnKP7sNb4eYkLsp6cGdPOl4OBcXM6rcbzU+Oqc5k=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
-github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
+github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
@@ -337,11 +374,14 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
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=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
+github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -383,7 +423,10 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/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.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
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-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
@@ -391,6 +434,7 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbR
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -400,8 +444,11 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/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.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
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.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=
@@ -412,6 +459,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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-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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -419,8 +467,11 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/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-20210124154548-22da62e12c0c/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-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -428,19 +479,26 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
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.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.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.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-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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
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.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
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.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
@@ -450,6 +508,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/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/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -470,12 +529,15 @@ google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFW
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
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-20190902080502-41f04d3bba15/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/evanphx/json-patch.v5 v5.7.0 h1:dGKGylPlZ/jus2g1YqhhyzfH0gPy2R8/MYUpW/OslTY=
gopkg.in/evanphx/json-patch.v5 v5.7.0/go.mod h1:/kvTRh1TVm5wuM6OkHxqXtE/1nUZZpihg29RtuIyfvk=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
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.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/hack/e2e_test.sh b/hack/e2e_test.sh
new file mode 100755
index 00000000..dd1d401d
--- /dev/null
+++ b/hack/e2e_test.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+
+# Copyright 2022 The Kubernetes 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.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+SOURCE_DIR="$(cd "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
+ROOT_DIR="$SOURCE_DIR/.."
+
+GINKGO="$ROOT_DIR"/bin/ginkgo
+GINKGO_ARGS=${GINKGO_ARGS:-}
+
+ENABLE_NFD=${ENABLE_NFD:-true}
+ENABLE_GPU_OPERATOR=${ENABLE_GPU_OPERATOR:-true}
+ENABLE_LOCAL_PATH_PROVISIONER=${ENABLE_LOCAL_PATH_PROVISIONER:-true}
+
+COLLECT_LOGS_FROM=${COLLECT_LOGS_FROM:-"default"}
+LOG_ARTIFACT_DIR=${LOG_ARTIFACT_DIR:-${ROOT_DIR}/e2e_logs}
+HELM_CHART=${HELM_CHART:-"${ROOT_DIR}/deployments/helm/k8s-nim-operator"}
+
+E2E_IMAGE_REPO=${E2E_IMAGE_REPO:-"ghcr.io/nvidia/k8s-nim-operator"}
+E2E_IMAGE_TAG=${E2E_IMAGE_TAG:-"main"}
+E2E_IMAGE_PULL_POLICY=${E2E_IMAGE_PULL_POLICY:-"IfNotPresent"}
+
+while getopts ":r:t:" opt; do
+ case ${opt} in
+ r )
+ E2E_IMAGE_REPO=$OPTARG
+ ;;
+ t )
+ E2E_IMAGE_TAG=$OPTARG
+ ;;
+ \? )
+ echo "Usage: $0 [-r E2E_IMAGE_REPO] [-t E2E_IMAGE_TAG]"
+ exit 1
+ ;;
+ esac
+done
+
+# check if KUBECONFIG is set
+if [ -z "${KUBECONFIG:-}" ]; then
+ echo "KUBECONFIG is not set"
+ exit 1
+fi
+
+# Set all ENV variables for e2e tests
+export ENABLE_NFD ENABLE_GPU_OPERATOR ENABLE_LOCAL_PATH_PROVISIONER
+export COLLECT_LOGS_FROM LOG_ARTIFACT_DIR HELM_CHART
+export E2E_IMAGE_REPO E2E_IMAGE_TAG E2E_IMAGE_PULL_POLICY
+
+# shellcheck disable=SC2086
+$GINKGO $GINKGO_ARGS -v ./test/e2e/...
diff --git a/test/e2e/Makefile b/test/e2e/Makefile
deleted file mode 100644
index 3b1efa4d..00000000
--- a/test/e2e/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
-#
-# 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_CMD ?= go
-GO_FMT ?= gofmt
-
-include $(CURDIR)/versions.mk
-
-DRIVER_ENABLED ?= true
-
-E2E_IMAGE_REPO ?= $(REGISTRY)/$(MODULE_NAME)
-E2E_IMAGE_TAG ?= $(VERSION)
-E2E_IMAGE_PULL_POLICY ?= IfNotPresent
-HELM_CHART ?= $(CURDIR)/deployments/helm/k8s-nim-operator
-LOG_ARTIFACTS ?= $(CURDIR)/e2e_logs
-
-.PHONY: e2e-test
-e2e-test:
- @if [ -z ${KUBECONFIG} ]; then \
- echo "[ERR] KUBECONFIG missing, must be defined"; \
- exit 1; \
- fi
- cd $(CURDIR)/test/e2e && $(GO_CMD) test -v . -args \
- -kubeconfig=$(KUBECONFIG) \
- -image.repo=$(E2E_IMAGE_REPO) \
- -image.tag=$(E2E_IMAGE_TAG) \
- -image.pull-policy=$(E2E_IMAGE_PULL_POLICY) \
- -log-artifacts=$(LOG_ARTIFACTS) \
- -helm-chart=$(HELM_CHART) \
- -helm-log-file=$(LOG_ARTIFACTS)/helm.log \
- -ginkgo.focus="\[nvidia\]" \
- -test.timeout=1h \
- -ginkgo.v
diff --git a/test/e2e/data/nimcache.yml b/test/e2e/data/nimcache.yml
new file mode 100644
index 00000000..f6360432
--- /dev/null
+++ b/test/e2e/data/nimcache.yml
@@ -0,0 +1,26 @@
+apiVersion: apps.nvidia.com/v1alpha1
+kind: NIMCache
+metadata:
+ labels:
+ app.kubernetes.io/name: k8s-nim-operator
+ name: meta-llama3-8b-instruct
+spec:
+ resources: {}
+ source:
+ ngc:
+ modelPuller: nvcr.io/nim/meta/llama3-8b-instruct:1.0.0
+ pullSecret: ngc-secret
+ authSecret: ngc-api-secret
+ model:
+ profiles: []
+ autoDetect: true
+ precision: "fp8"
+ engine: "tensorrt_llm"
+ qosProfile: "throughput"
+ tensorParallelism: "1"
+ storage:
+ pvc:
+ create: true
+ storageClass: "local-path"
+ size: "50Gi"
+ volumeAccessMode: ReadWriteOnce
diff --git a/test/e2e/data/nimservice.yml b/test/e2e/data/nimservice.yml
new file mode 100644
index 00000000..6787dc31
--- /dev/null
+++ b/test/e2e/data/nimservice.yml
@@ -0,0 +1,25 @@
+apiVersion: apps.nvidia.com/v1alpha1
+kind: NIMService
+metadata:
+ labels:
+ app.kubernetes.io/name: k8s-nim-operator
+ name: meta-llama3-8b-instruct
+spec:
+ image:
+ repository: nvcr.io/nim/meta/llama3-8b-instruct
+ tag: 1.0.0
+ pullPolicy: IfNotPresent
+ pullSecrets:
+ - ngc-secret
+ authSecret: ngc-api-secret
+ nimCache:
+ name: meta-llama3-8b-instruct
+ profile: ''
+ replicas: 1
+ resources:
+ limits:
+ nvidia.com/gpu: 1
+ expose:
+ service:
+ type: ClusterIP
+ openaiPort: 8000
diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go
index 1aba28cb..a7fd976f 100644
--- a/test/e2e/e2e_test.go
+++ b/test/e2e/e2e_test.go
@@ -17,45 +17,403 @@
package e2e
import (
- "flag"
+ "context"
+ "fmt"
"log"
"os"
+ "path/filepath"
+ "strconv"
+ "strings"
"testing"
+ "time"
- "github.com/onsi/ginkgo/v2"
- "github.com/onsi/gomega"
+ "github.com/NVIDIA/k8s-test-infra/pkg/diagnostics"
- "github.com/NVIDIA/k8s-test-infra/pkg/framework"
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+
+ git "github.com/go-git/go-git/v5"
+ "github.com/go-git/go-git/v5/plumbing"
+ helm "github.com/mittwald/go-helm-client"
+ helmValues "github.com/mittwald/go-helm-client/values"
+ "helm.sh/helm/v3/pkg/repo"
+ corev1 "k8s.io/api/core/v1"
+ extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/util/rand"
+ "k8s.io/apimachinery/pkg/util/wait"
+ clientset "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/rest"
+ "k8s.io/client-go/tools/clientcmd"
)
+const (
+ gpuOpHelm = "https://helm.ngc.nvidia.com/nvidia"
+ rancherLocalPathProvisioner = "https://github.com/rancher/local-path-provisioner.git"
+ nfd = "nfd"
+ gpuOperator = "gpu-operator"
+ localPathProvisioner = "local-path-provisioner"
+
+ // DefaultNamespaceDeletionTimeout is timeout duration for waiting for a namespace deletion.
+ DefaultNamespaceDeletionTimeout = 5 * time.Minute
+ // PollInterval is how often to Poll pods, nodes and claims.
+ PollInterval = 2 * time.Second
+)
+
+// Test context
var (
- HelmChart = flag.String("helm-chart", "", "Helm chart to use")
- LogArtifactDir = flag.String("log-artifacts", "", "Directory to store logs")
- ImageRepo = flag.String("image.repo", "", "Image repository to fetch image from")
- ImageTag = flag.String("image.tag", "", "Image tag to use")
- ImagePullPolicy = flag.String("image.pull-policy", "IfNotPresent", "Image pull policy")
- CollectLogsFrom = flag.String("collect-logs-from", "default", "Comma separated list of objects to collect logs from after test")
+ KUBECONFIG string
+
+ EnableNFD bool
+ EnableGPUOperator bool
+ EnableLocalPathProvisioner bool
+ LogArtifactDir string
+ ImageRepo string
+ ImageTag string
+ ImagePullPolicy string
+ CollectLogsFrom string
+
+ // k8s clients
+ clientConfig *rest.Config
+ clientSet clientset.Interface
+ extClient *extclient.Clientset
+
+ testNamespace *corev1.Namespace // Every test has at least one namespace unless creation is skipped
+
+ // Helm
+ helmChart string
+ helmClient helm.Client
+ helmLogFile *os.File
+ helmArtifactDir string
+ helmLogger *log.Logger
+ helmReleaseName string
+
+ ctx context.Context
+ cwd string
+
+ diagnosticsCollector *diagnostics.Diagnostic
+ collectLogsFrom []string
+ defaultCollectorObjects = []string{
+ "pods",
+ "nodes",
+ "namespaces",
+ "deployments",
+ "daemonsets",
+ }
)
-func TestMain(m *testing.M) {
- // Register test flags, then parse flags.
- framework.RegisterClusterFlags(flag.CommandLine)
- flag.Parse()
+func TestMain(t *testing.T) {
+ suiteName := "E2E K8s NIM Operator"
+
+ RegisterFailHandler(Fail)
+ RunSpecs(t,
+ suiteName,
+ )
+}
+
+// BeforeSuite runs before the test suite
+var _ = BeforeSuite(func() {
+ var err error
+ ctx = context.Background()
+
+ // Init
+ getTestEnv()
+
+ // Get k8s clients
+ getK8sClients()
+
+ // Create clients for apiextensions and our CRD api
+ extClient = extclient.NewForConfigOrDie(clientConfig)
+
+ // Create a namespace for the test
+ testNamespace, err = CreateTestingNS("k8s-nim-operator", clientSet, nil)
+ Expect(err).NotTo(HaveOccurred())
+
+ // Get Helm client
+ helmReleaseName = "nim-op-e2e-test" + rand.String(5)
+ getHelmClient()
+
+ // check Collector objects
+ collectLogsFrom = defaultCollectorObjects
+ if CollectLogsFrom != "" && CollectLogsFrom != "default" {
+ collectLogsFrom = strings.Split(CollectLogsFrom, ",")
+ }
+
+ deployDependencies(ctx)
+})
+
+// AfterSuite runs after the test suite
+var _ = AfterSuite(func() {
+ // Clean up CRs so they are garbage collected by their controllers
+ cleanUpCRs()
+ // Clean up Helm deployments
+ cleanup()
+ // Remove CRDs
+ cleanuoCRDs()
+ // Delete Test Namespace
+ DeleteNamespace()
+})
+
+// cleanup cleans up the test environment
+func deployDependencies(ctx context.Context) {
+ // Install dependencies if needed
+ if EnableNFD {
+ // Add or Update Helm repo
+ helmRepo := repo.Entry{
+ Name: nfd,
+ URL: "https://kubernetes-sigs.github.io/node-feature-discovery/charts",
+ }
+ err := helmClient.AddOrUpdateChartRepo(helmRepo)
+ Expect(err).NotTo(HaveOccurred())
+
+ err = helmClient.UpdateChartRepos()
+ Expect(err).NotTo(HaveOccurred())
+
+ // Install NFD
+ chartSpec := &helm.ChartSpec{
+ ReleaseName: nfd,
+ ChartName: "nfd/node-feature-discovery",
+ Namespace: testNamespace.Name,
+ CreateNamespace: false,
+ Wait: true,
+ Timeout: 5 * time.Minute,
+ CleanupOnFail: true,
+ }
+ _, err = helmClient.InstallOrUpgradeChart(ctx, chartSpec, nil)
+ Expect(err).NotTo(HaveOccurred())
+ }
+
+ if EnableGPUOperator {
+ // Add or Update Helm repo
+ helmRepo := repo.Entry{
+ Name: "nvidia",
+ URL: gpuOpHelm,
+ }
+ err := helmClient.AddOrUpdateChartRepo(helmRepo)
+ Expect(err).NotTo(HaveOccurred())
+
+ err = helmClient.UpdateChartRepos()
+ Expect(err).NotTo(HaveOccurred())
+
+ // Install GPU Operator
+ values := helmValues.Options{
+ Values: []string{
+ fmt.Sprintf("nfd.enabled=%v", false), // we install NFD separately
+ },
+ }
+ chartSpec := &helm.ChartSpec{
+ ReleaseName: gpuOperator,
+ ChartName: "nvidia/gpu-operator",
+ Namespace: testNamespace.Name,
+ CreateNamespace: false,
+ Wait: true,
+ WaitForJobs: true,
+ Timeout: 10 * time.Minute, // Give it time to build the driver
+ CleanupOnFail: true,
+ ValuesOptions: values}
+ _, err = helmClient.InstallOrUpgradeChart(ctx, chartSpec, nil)
+ Expect(err).NotTo(HaveOccurred())
+ }
+
+ if EnableLocalPathProvisioner {
+ // Clone the repository
+ if _, err := os.Stat(filepath.Join(cwd, localPathProvisioner)); os.IsNotExist(err) {
+ tag := "v0.0.28"
+ _, err := git.PlainClone(filepath.Join(cwd, localPathProvisioner), false, &git.CloneOptions{
+ URL: rancherLocalPathProvisioner,
+ ReferenceName: plumbing.NewTagReferenceName(tag),
+ Progress: nil,
+ })
+ Expect(err).NotTo(HaveOccurred())
+ }
+ // Set chartPath to the correct location
+ chartPath := filepath.Join(localPathProvisioner, "deploy", "chart", localPathProvisioner)
+ // Load the chart
+ chartSpec := &helm.ChartSpec{
+ ReleaseName: localPathProvisioner,
+ ChartName: chartPath,
+ Namespace: testNamespace.Name,
+ Wait: true,
+ Timeout: 1 * time.Minute,
+ CleanupOnFail: true,
+ CreateNamespace: false,
+ }
+ // Install the local-path-provisioner
+ _, err := helmClient.InstallChart(ctx, chartSpec, nil)
+ Expect(err).NotTo(HaveOccurred())
+ }
+}
+
+// cleanup cleans up the test environment
+func getK8sClients() {
+ var err error
- // check if flags are set and if not cancel the test run
- if *ImageRepo == "" || *ImageTag == "" || *HelmChart == "" {
- log.Fatal("Required flags not set. Please set -image.repo, -image.tag and -helm-chart")
+ // get config from kubeconfig
+ c, err := clientcmd.LoadFromFile(KUBECONFIG)
+ Expect(err).NotTo(HaveOccurred())
+
+ // get client config
+ clientConfig, err = clientcmd.NewDefaultClientConfig(*c, &clientcmd.ConfigOverrides{}).ClientConfig()
+ Expect(err).NotTo(HaveOccurred())
+
+ clientSet, err = clientset.NewForConfig(clientConfig)
+ Expect(err).NotTo(HaveOccurred())
+}
+
+// cleanup cleans up the test environment
+func getHelmClient() {
+ var err error
+
+ // Set Helm log file
+ helmArtifactDir = filepath.Join(LogArtifactDir, "helm")
+
+ // Create a Helm client
+ err = os.MkdirAll(helmArtifactDir, 0755)
+ Expect(err).NotTo(HaveOccurred())
+
+ helmLogFile, err = os.OpenFile(filepath.Join(LogArtifactDir, "helm_logs"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+ Expect(err).NotTo(HaveOccurred())
+
+ helmLogger = log.New(helmLogFile, fmt.Sprintf("%s\t", testNamespace.Name), log.Ldate|log.Ltime)
+
+ helmRestConf := &helm.RestConfClientOptions{
+ Options: &helm.Options{
+ Namespace: testNamespace.Name,
+ RepositoryCache: "/tmp/.helmcache",
+ RepositoryConfig: "/tmp/.helmrepo",
+ Debug: true,
+ DebugLog: helmLogger.Printf,
+ },
+ RestConfig: clientConfig,
}
- os.Exit(m.Run())
+ helmClient, err = helm.NewClientFromRestConf(helmRestConf)
+ Expect(err).NotTo(HaveOccurred())
}
-func TestE2E(t *testing.T) {
- gomega.RegisterFailHandler(ginkgo.Fail)
- // Run tests through the Ginkgo runner with output to console + JUnit for Jenkins
- suiteConfig, reporterConfig := ginkgo.GinkgoConfiguration()
- // Randomize specs as well as suites
- suiteConfig.RandomizeAllSpecs = true
+// cleanup cleans up the test environment
+func getTestEnv() {
+ var err error
+
+ KUBECONFIG = os.Getenv("KUBECONFIG")
+ Expect(KUBECONFIG).NotTo(BeEmpty(), "KUBECONFIG must be set")
+
+ EnableNFD = getBoolEnvVar("ENABLE_NFD", false)
+ EnableGPUOperator = getBoolEnvVar("ENABLE_GPU_OPERATOR", false)
+ EnableLocalPathProvisioner = getBoolEnvVar("ENABLE_LOCAL_PATH_PROVISIONER", false)
+
+ helmChart = os.Getenv("HELM_CHART")
+ Expect(helmChart).NotTo(BeEmpty(), "HELM_CHART must be set")
+
+ LogArtifactDir = os.Getenv("LOG_ARTIFACT_DIR")
+ ImageRepo = os.Getenv("E2E_IMAGE_REPO")
+ Expect(ImageRepo).NotTo(BeEmpty(), "IMAGE_REPO must be set")
+
+ ImageTag = os.Getenv("E2E_IMAGE_TAG")
+ Expect(ImageTag).NotTo(BeEmpty(), "IMAGE_TAG must be set")
+
+ ImagePullPolicy = os.Getenv("E2E_IMAGE_PULL_POLICY")
+ Expect(ImagePullPolicy).NotTo(BeEmpty(), "IMAGE_PULL_POLICY must be set")
+
+ CollectLogsFrom = os.Getenv("COLLECT_LOGS_FROM")
+
+ // Get current working directory
+ cwd, err = os.Getwd()
+ Expect(err).NotTo(HaveOccurred())
+}
+
+// getBoolEnvVar returns the boolean value of the environment variable or the default value if not set.
+func getBoolEnvVar(key string, defaultValue bool) bool {
+ value := os.Getenv(key)
+ if value == "" {
+ return defaultValue
+ }
+ boolValue, err := strconv.ParseBool(value)
+ if err != nil {
+ return defaultValue
+ }
+ return boolValue
+}
+
+// CreateTestingNS should be used by every test, note that we append a common prefix to the provided test name.
+// Please see NewFramework instead of using this directly.
+func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]string) (*corev1.Namespace, error) {
+ uid := RandomSuffix()
+ if labels == nil {
+ labels = map[string]string{}
+ }
+ labels["e2e-run"] = uid
+
+ // We don't use ObjectMeta.GenerateName feature, as in case of API call
+ // failure we don't know whether the namespace was created and what is its
+ // name.
+ name := fmt.Sprintf("%v-%v", baseName, uid)
+
+ namespaceObj := &corev1.Namespace{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: "",
+ Labels: labels,
+ },
+ Status: corev1.NamespaceStatus{},
+ }
+ // Be robust about making the namespace creation call.
+ var got *corev1.Namespace
+ if err := wait.PollUntilContextTimeout(ctx, PollInterval, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+ var err error
+ got, err = c.CoreV1().Namespaces().Create(ctx, namespaceObj, metav1.CreateOptions{})
+ if err != nil {
+ if apierrors.IsAlreadyExists(err) {
+ // regenerate on conflict
+ namespaceObj.Name = fmt.Sprintf("%v-%v", baseName, uid)
+ }
+ return false, nil
+ }
+ return true, nil
+ }); err != nil {
+ return nil, err
+ }
+
+ return got, nil
+}
+
+// DeleteNamespace can be used to delete a namespace
+func DeleteNamespace() {
+ defer func() {
+ err := clientSet.CoreV1().Namespaces().Delete(ctx, testNamespace.Name, metav1.DeleteOptions{})
+ if err != nil && !apierrors.IsNotFound(err) {
+ Expect(err).NotTo(HaveOccurred())
+ }
+ err = WaitForNamespacesDeleted(clientSet, []string{testNamespace.Name}, DefaultNamespaceDeletionTimeout)
+ Expect(err).NotTo(HaveOccurred())
+ }()
+}
+
+// WaitForNamespacesDeleted waits for the namespaces to be deleted.
+func WaitForNamespacesDeleted(c clientset.Interface, namespaces []string, timeout time.Duration) error {
+ By(fmt.Sprintf("Waiting for namespace %+v deletion", namespaces))
+ nsMap := map[string]bool{}
+ for _, ns := range namespaces {
+ nsMap[ns] = true
+ }
+ // Now POLL until all namespaces have been eradicated.
+ return wait.PollUntilContextTimeout(ctx, 2*time.Second, timeout, true,
+ func(ctx context.Context) (bool, error) {
+ nsList, err := c.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
+ if err != nil {
+ return false, err
+ }
+ for _, item := range nsList.Items {
+ if _, ok := nsMap[item.Name]; ok {
+ return false, nil
+ }
+ }
+ return true, nil
+ })
+}
- ginkgo.RunSpecs(t, "nvidia k8s-nim-operator e2e suite", suiteConfig, reporterConfig)
+// RandomSuffix provides a random sequence to append to pods,services,rcs.
+func RandomSuffix() string {
+ return strconv.Itoa(rand.Intn(10000))
}
diff --git a/test/e2e/framework.go b/test/e2e/framework.go
deleted file mode 100644
index d265f3c0..00000000
--- a/test/e2e/framework.go
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
- *
- * 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 e2e
-
-import (
- "github.com/onsi/ginkgo/v2"
-)
-
-// NVDescribe annotates the test with the NVIDIA label.
-func NVDescribe(text string, body func()) bool {
- return ginkgo.Describe("[nvidia] "+text, body)
-}
diff --git a/test/e2e/gomega.go b/test/e2e/gomega.go
deleted file mode 100644
index 30c33d6c..00000000
--- a/test/e2e/gomega.go
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
- *
- * 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 e2e
-
-import (
- "context"
- "fmt"
- "regexp"
- "strings"
-
- gomegatypes "github.com/onsi/gomega/types"
-
- corev1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- clientset "k8s.io/client-go/kubernetes"
-)
-
-type k8sLabels map[string]string
-
-// MatchLabels returns a specialized Gomega matcher for checking if a list of
-// nodes are labeled as expected.
-func MatchLabels(expectedNew map[string]k8sLabels, oldNodes []corev1.Node) gomegatypes.GomegaMatcher {
- return &nodeListPropertyRegexpMatcher[k8sLabels]{
- propertyName: "labels",
- expected: expectedNew,
- oldNodes: oldNodes,
- }
-}
-
-// MatchCapacity returns a specialized Gomega matcher for checking if a list of
-// nodes are configured as expected.
-func MatchCapacity(expectedNew map[string]k8sLabels, oldNodes []corev1.Node) gomegatypes.GomegaMatcher {
- return &nodeListPropertyRegexpMatcher[k8sLabels]{
- propertyName: "capacity",
- expected: expectedNew,
- oldNodes: oldNodes,
- }
-}
-
-// nodeListPropertyRegexpMatcher is a generic Gomega matcher for asserting one property a group of nodes.
-type nodeListPropertyRegexpMatcher[T any] struct {
- expected map[string]k8sLabels
- oldNodes []corev1.Node
-
- propertyName string
- node *corev1.Node //nolint:unused
- missing []string //nolint:unused
- invalidValue []string //nolint:unused
-}
-
-// Match method of the GomegaMatcher interface.
-func (m *nodeListPropertyRegexpMatcher[T]) Match(actual interface{}) (bool, error) {
- nodes, ok := actual.([]corev1.Node)
- if !ok {
- return false, fmt.Errorf("expected []corev1.Node, got: %T", actual)
- }
-
- switch m.propertyName {
- case "labels":
- return m.matchLabels(nodes), nil
- case "capacity":
- return m.matchCapacity(nodes), nil
- default:
- return true, nil
- }
-
-}
-
-func (m *nodeListPropertyRegexpMatcher[T]) matchLabels(nodes []corev1.Node) bool {
- targetNode := corev1.Node{}
- for _, node := range nodes {
- _, ok := m.expected[node.Name]
- if !ok {
- continue
- }
- targetNode = node
- break
- }
-
- m.node = &targetNode
-
- for labelKey, labelValue := range m.expected[targetNode.Name] {
- // missing key
- if _, ok := targetNode.Labels[labelKey]; !ok {
- m.missing = append(m.missing, labelKey)
- continue
- }
- // invalid value
- regexMatcher := regexp.MustCompile(labelValue)
- if !regexMatcher.MatchString(targetNode.Labels[labelKey]) {
- m.invalidValue = append(m.invalidValue, fmt.Sprintf("%s: %s", labelKey, targetNode.Labels[labelKey]))
- return false
- }
- }
-
- return true
-}
-
-func (m *nodeListPropertyRegexpMatcher[T]) matchCapacity(nodes []corev1.Node) bool {
- targetNode := corev1.Node{}
- for _, node := range nodes {
- _, ok := m.expected[node.Name]
- if !ok {
- continue
- }
- targetNode = node
- break
- }
-
- m.node = &targetNode
-
- for labelKey, labelValue := range m.expected[targetNode.Name] {
- // missing key
- rn := corev1.ResourceName(labelKey)
- if _, ok := targetNode.Status.Capacity[rn]; !ok {
- m.missing = append(m.missing, labelKey)
- continue
- }
- // invalid value
- capacity := targetNode.Status.Capacity[rn]
- regexMatcher := regexp.MustCompile(labelValue)
- if !regexMatcher.MatchString(capacity.String()) {
- m.invalidValue = append(m.invalidValue, fmt.Sprintf("%s: %s", labelKey, capacity.String()))
- return false
- }
- }
-
- return true
-}
-
-// FailureMessage method of the GomegaMatcher interface.
-func (m *nodeListPropertyRegexpMatcher[T]) FailureMessage(actual interface{}) string {
- return m.message()
-}
-
-// NegatedFailureMessage method of the GomegaMatcher interface.
-func (m *nodeListPropertyRegexpMatcher[T]) NegatedFailureMessage(actual interface{}) string {
- return fmt.Sprintf("Node %q matched unexpectedly", m.node.Name)
-}
-
-// TODO remove nolint when golangci-lint is able to cope with generics
-//
-//nolint:unused
-func (m *nodeListPropertyRegexpMatcher[T]) message() string {
- msg := fmt.Sprintf("Node %q %s did not match:", m.node.Name, m.propertyName)
- if len(m.missing) > 0 {
- msg += fmt.Sprintf("\n missing:\n %s", strings.Join(m.missing, "\n "))
- }
- if len(m.invalidValue) > 0 {
- msg += fmt.Sprintf("\n invalid value:\n %s", strings.Join(m.invalidValue, "\n "))
- }
- return msg
-}
-
-// JobIsCompleted checks if a job is completed
-func JobIsCompleted(ctx context.Context, cli clientset.Interface, namespace, podName string) bool {
- pod, err := cli.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{})
- if err != nil {
- return false
- }
- // Check if the pod's phase is Succeeded.
- if pod.Status.Phase == "Succeeded" {
- return true
- }
- return false
-}
diff --git a/test/e2e/infra/vsphere.yml b/test/e2e/infra/vsphere.yml
new file mode 100644
index 00000000..86987d12
--- /dev/null
+++ b/test/e2e/infra/vsphere.yml
@@ -0,0 +1,30 @@
+apiVersion: holodeck.nvidia.com/v1alpha1
+kind: Environment
+metadata:
+ name: holodeck-vsphere-e2e-test
+ description: "end-to-end test infrastructure"
+spec:
+ provider: vsphere
+ auth:
+ keyName: cnt-ci
+ privateKey: /home/nvidia/.ssh/gpu_runner
+ VsphereVirtualMachine:
+ vCenterURL: "pdx01egxvc01.nvidia.com"
+ datacenter: "PDX01"
+ datastore: "PDX01EGX_vSAN_001"
+ cluster: "PDX01EGX001"
+ network: "PDX01EGXDVS001_Internal_307_10.185.111.0_24"
+ vmFolder: "GitHub ARC"
+ resoursePool: "CNT-ARC"
+ templateImage: "GPU_UBUNTU_TEMPLATE"
+ containerRuntime:
+ install: true
+ name: containerd
+ nvidiaContainerToolkit:
+ install: true
+ nvidiaDriver:
+ install: true
+ kubernetes:
+ install: true
+ installer: kubeadm
+ version: v1.20.3
diff --git a/test/e2e/nim-operator_test.go b/test/e2e/nim-operator_test.go
index 91eaef5f..72b058db 100644
--- a/test/e2e/nim-operator_test.go
+++ b/test/e2e/nim-operator_test.go
@@ -18,8 +18,10 @@ package e2e
import (
"context"
+ "encoding/base64"
"fmt"
- "strings"
+ "os"
+ "path/filepath"
"time"
. "github.com/onsi/ginkgo/v2"
@@ -27,139 +29,250 @@ import (
helm "github.com/mittwald/go-helm-client"
helmValues "github.com/mittwald/go-helm-client/values"
- extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
+ corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/util/rand"
+ "sigs.k8s.io/yaml"
+ "github.com/NVIDIA/k8s-nim-operator/api/apps/v1alpha1"
+ "github.com/NVIDIA/k8s-nim-operator/api/versioned"
"github.com/NVIDIA/k8s-test-infra/pkg/diagnostics"
- "github.com/NVIDIA/k8s-test-infra/pkg/framework"
)
// Actual test suite
-var _ = NVDescribe("NIM Operator", func() {
- f := framework.NewFramework("k8s-nim-operator")
+var _ = Describe("NIM Operator", func() {
+ JustBeforeEach(func(ctx context.Context) {
+ // Values
+ values := helmValues.Options{
+ Values: []string{
+ fmt.Sprintf("operator.image.repository=%s", ImageRepo),
+ fmt.Sprintf("operator.image.tag=%s", ImageTag),
+ fmt.Sprintf("operator.image.pullPolicy=%s", ImagePullPolicy),
+ },
+ }
- Context("When deploying k8s-nim-operator", Ordered, func() {
- // helm-chart is required
- if *HelmChart == "" {
- Fail("No helm-chart for k8s-nim-operator specified")
+ // Chart spec
+ chartSpec := &helm.ChartSpec{
+ ReleaseName: helmReleaseName,
+ ChartName: helmChart,
+ Namespace: testNamespace.Name,
+ CreateNamespace: true,
+ Wait: true,
+ Timeout: 10 * time.Minute, // pull time is long
+ ValuesOptions: values,
+ CleanupOnFail: true,
}
- // Init global suite vars vars
- var (
- crds []string
- extClient *extclient.Clientset
+ By("Installing k8s-nim-operator Helm chart")
+ _, err := helmClient.InstallOrUpgradeChart(ctx, chartSpec, nil)
+ Expect(err).NotTo(HaveOccurred())
+ })
- helmReleaseName string
- chartSpec helm.ChartSpec
+ AfterEach(func(ctx context.Context) {
+ // Run diagnostic collector if test failed
+ if CurrentSpecReport().Failed() {
+ var err error
+ diagnosticsCollector, err = diagnostics.New(
+ diagnostics.WithNamespace(testNamespace.Name),
+ diagnostics.WithArtifactDir(LogArtifactDir),
+ diagnostics.WithKubernetesClient(clientSet),
+ diagnostics.WithObjects(collectLogsFrom...),
+ )
+ Expect(err).NotTo(HaveOccurred())
- collectLogsFrom []string
- diagnosticsCollector *diagnostics.Diagnostic
- )
+ err = diagnosticsCollector.Collect(ctx)
+ Expect(err).NotTo(HaveOccurred())
- defaultCollectorObjects := []string{
- "pods",
- "nodes",
- "namespaces",
- "deployments",
- "daemonsets",
+ cleanup()
}
+ // Clean up
+ cleanUpCRs()
+ cleanup()
+ })
- crds = []string{
- "nimcaches.apps.nvidia.com",
- "nimservices.apps.nvidia.com",
- "nimpipelines.apps.nvidia.com",
- }
+ When("deploying the K8s-NIM-Operator via Helm", Ordered, func() {
+ It("it should create a NIMCache and NIMService in READY state", func(ctx context.Context) {
+ // Create pull secrets
+ createPullSecrets()
- values := helmValues.Options{
- Values: []string{
- fmt.Sprintf("operator.image.repository=%s", *ImageRepo),
- fmt.Sprintf("operator.image.tag=%s", *ImageTag),
- fmt.Sprintf("operator.image.pullPolicy=%s", *ImagePullPolicy),
- },
- }
+ // Create a NIMCache object
+ By("Creating a NIMCache object")
+ cli, err := versioned.NewForConfig(clientConfig)
+ Expect(err).NotTo(HaveOccurred())
- // check Collector objects
- collectLogsFrom = defaultCollectorObjects
- if *CollectLogsFrom != "" && *CollectLogsFrom != "default" {
- collectLogsFrom = strings.Split(*CollectLogsFrom, ",")
- }
+ nimCache := &v1alpha1.NIMCache{}
+ data, err := os.ReadFile(filepath.Join(cwd, "data", "nimcache.yml"))
+ Expect(err).NotTo(HaveOccurred())
- BeforeAll(func(ctx context.Context) {
- // Create clients for apiextensions and our CRD api
- extClient = extclient.NewForConfigOrDie(f.ClientConfig())
- helmReleaseName = "nim-op-e2e-test" + rand.String(5)
- })
+ err = yaml.Unmarshal(data, nimCache)
+ Expect(err).NotTo(HaveOccurred())
- JustBeforeEach(func(ctx context.Context) {
- // reset Helm Client
- chartSpec = helm.ChartSpec{
- ReleaseName: helmReleaseName,
- ChartName: *HelmChart,
- Namespace: f.Namespace.Name,
- Wait: true,
- Timeout: 1 * time.Minute,
- ValuesOptions: values,
- CleanupOnFail: true,
- }
+ _, err = cli.AppsV1alpha1().NIMCaches(testNamespace.Name).Create(ctx, nimCache, metav1.CreateOptions{})
+ Expect(err).NotTo(HaveOccurred())
- By("Installing k8s-nim-operator Helm chart")
- _, err := f.HelmClient.InstallChart(ctx, &chartSpec, nil)
+ By("Checking the NIMCache object state is ready")
+ Eventually(func() bool {
+ nimCacheObject, _ := cli.AppsV1alpha1().NIMCaches(testNamespace.Name).Get(ctx, nimCache.Name, metav1.GetOptions{})
+ return nimCacheObject.Status.State == v1alpha1.NimCacheStatusReady
+ }, /*10 minutes*/ 10*time.Minute, 5*time.Second).Should(BeTrue())
+
+ // Create a NIMService object
+ By("Creating a NIMService object")
+ nimService := &v1alpha1.NIMService{}
+ data, err = os.ReadFile(filepath.Join(cwd, "data", "nimservice.yml"))
Expect(err).NotTo(HaveOccurred())
- })
- AfterEach(func(ctx context.Context) {
- // Run diagnostic collector if test failed
- if CurrentSpecReport().Failed() {
- var err error
- diagnosticsCollector, err = diagnostics.New(
- diagnostics.WithNamespace(f.Namespace.Name),
- diagnostics.WithArtifactDir(*LogArtifactDir),
- diagnostics.WithKubernetesClient(f.ClientSet),
- diagnostics.WithObjects(collectLogsFrom...),
- )
- Expect(err).NotTo(HaveOccurred())
-
- err = diagnosticsCollector.Collect(ctx)
- Expect(err).NotTo(HaveOccurred())
- }
- // Cleanup before next test run
- // Delete Helm release
- err := f.HelmClient.UninstallReleaseByName(helmReleaseName)
+ err = yaml.Unmarshal(data, nimService)
Expect(err).NotTo(HaveOccurred())
- })
- // Clean up
- AfterAll(func(ctx context.Context) {
- // Delete CRDs
- for _, crd := range crds {
- err := extClient.ApiextensionsV1().CustomResourceDefinitions().Delete(ctx, crd, metav1.DeleteOptions{})
- Expect(err).NotTo(HaveOccurred())
- }
- })
+ _, err = cli.AppsV1alpha1().NIMServices(testNamespace.Name).Create(ctx, nimService, metav1.CreateOptions{})
+ Expect(err).NotTo(HaveOccurred())
- Context("and the NIM Operator is deployed", func() {
- It("it should create *.apps.nvidia.com CRD's", func(ctx context.Context) {
- crdl, err := f.ApiExtClient.ApiextensionsV1().CustomResourceDefinitions().List(ctx, metav1.ListOptions{})
- Expect(err).NotTo(HaveOccurred())
-
- // Look for the 3 NIMCache, NIMService and NIMPipeline CRDs
- nimCrds := map[string]bool{
- "nimcaches.apps.nvidia.com": false,
- "nimservices.apps.nvidia.com": false,
- "nimpipelines.apps.nvidia.com": false,
- }
-
- for _, crd := range crdl.Items {
- if _, ok := nimCrds[crd.Name]; ok {
- nimCrds[crd.Name] = true
- }
- }
-
- for crdName, found := range nimCrds {
- Expect(found).To(BeTrue(), "CRD %q not found", crdName)
- }
- })
+ By("Checking the NIMService object state is ready")
+ Eventually(func() bool {
+ nimServiceObject, _ := cli.AppsV1alpha1().NIMServices(testNamespace.Name).Get(ctx, nimService.Name, metav1.GetOptions{})
+ return nimServiceObject.Status.State == v1alpha1.NIMServiceStatusReady
+ // TODO - Update the status to Ready
+ }, /*10 minutes*/ 10*time.Minute, 5*time.Second).Should(BeTrue())
})
})
})
+
+func cleanup() {
+ cwd, err := os.Getwd()
+ Expect(err).NotTo(HaveOccurred())
+
+ deployed, err := helmClient.ListDeployedReleases()
+ Expect(err).NotTo(HaveOccurred())
+
+ for _, release := range deployed {
+ switch release.Name {
+ case nfd, gpuOperator:
+ err := helmClient.UninstallReleaseByName(release.Name)
+ Expect(err).NotTo(HaveOccurred())
+ case localPathProvisioner:
+ err := os.RemoveAll(filepath.Join(cwd, localPathProvisioner))
+ Expect(err).NotTo(HaveOccurred())
+
+ err = helmClient.UninstallReleaseByName(release.Name)
+ Expect(err).NotTo(HaveOccurred())
+ case helmReleaseName:
+ err := helmClient.UninstallReleaseByName(helmReleaseName)
+ Expect(err).NotTo(HaveOccurred())
+ }
+ }
+}
+
+func cleanUpCRs() {
+ cli, err := versioned.NewForConfig(clientConfig)
+ Expect(err).NotTo(HaveOccurred())
+
+ // List all NIMCache CRs
+ nimCacheList, err := cli.AppsV1alpha1().NIMCaches(testNamespace.Name).List(ctx, metav1.ListOptions{})
+ Expect(err).NotTo(HaveOccurred())
+
+ // Delete all NIMCache CRs
+ if len(nimCacheList.Items) != 0 {
+ By("Deleting all NIMCache CRs")
+ for _, nimCache := range nimCacheList.Items {
+ err := cli.AppsV1alpha1().NIMCaches(testNamespace.Name).Delete(ctx, nimCache.Name, metav1.DeleteOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ }
+ }
+
+ // List all NIMService CRs
+ nimServiceList, err := cli.AppsV1alpha1().NIMServices(testNamespace.Name).List(ctx, metav1.ListOptions{})
+ Expect(err).NotTo(HaveOccurred())
+
+ // Delete all NIMService CRs
+ if len(nimServiceList.Items) != 0 {
+ By("Deleting all NIMService CRs")
+ for _, nimService := range nimServiceList.Items {
+ err := cli.AppsV1alpha1().NIMServices(testNamespace.Name).Delete(ctx, nimService.Name, metav1.DeleteOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ }
+ }
+
+ // List all NIMPipeline CRs
+ nimPipelineList, err := cli.AppsV1alpha1().NIMPipelines(testNamespace.Name).List(ctx, metav1.ListOptions{})
+ Expect(err).NotTo(HaveOccurred())
+
+ // Delete all NIMPipeline CRs
+ if len(nimPipelineList.Items) != 0 {
+ By("Deleting all NIMPipeline CRs")
+ for _, nimPipeline := range nimPipelineList.Items {
+ err := cli.AppsV1alpha1().NIMPipelines(testNamespace.Name).Delete(ctx, nimPipeline.Name, metav1.DeleteOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ }
+ }
+}
+
+func cleanuoCRDs() {
+ crds := []string{
+ "nimcaches.apps.nvidia.com",
+ "nimservices.apps.nvidia.com",
+ "nimpipelines.apps.nvidia.com",
+ "clusterpolicies.nvidia.com",
+ "nvidiadrivers.nvidia.com",
+ "nodefeatures.nfd.k8s-sigs.io",
+ "nodefeaturerules.nfd.k8s-sigs.io",
+ "nodefeaturegroups.nfd.k8s-sigs.io",
+ }
+ // Delete CRDs
+ for _, crd := range crds {
+ err := extClient.ApiextensionsV1().CustomResourceDefinitions().Delete(ctx, crd, metav1.DeleteOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ }
+}
+
+func createPullSecrets() {
+ // Get the NGC_API_KEY
+ NGC_API_KEY := os.Getenv("NGC_API_KEY")
+
+ // Create a secret for pulling the image
+ ngcAPIsecret := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "ngc-api-secret",
+ Namespace: testNamespace.Name,
+ },
+ Type: corev1.SecretTypeOpaque,
+ StringData: map[string]string{
+ "NGC_API_KEY": NGC_API_KEY,
+ },
+ }
+
+ _, err := clientSet.CoreV1().Secrets(testNamespace.Name).Create(ctx, ngcAPIsecret, metav1.CreateOptions{})
+ Expect(err).NotTo(HaveOccurred())
+
+ // Create the dockerconfigjson type secret
+ dockerServer := "nvcr.io"
+ dockerUsername := `$oauthtoken`
+ auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", dockerUsername, NGC_API_KEY)))
+
+ dockerConfigJson := `{
+ "auths": {
+ "` + dockerServer + `": {
+ "username": "` + dockerUsername + `",
+ "password": "` + NGC_API_KEY + `",
+ "auth": "` + auth + `"
+ }
+ }
+ }`
+
+ ngcSecret := &corev1.Secret{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "v1",
+ Kind: "Secret",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "ngc-secret",
+ Namespace: testNamespace.Name,
+ CreationTimestamp: metav1.Time{Time: time.Now()},
+ },
+ Data: map[string][]byte{
+ corev1.DockerConfigJsonKey: []byte(dockerConfigJson),
+ },
+ Type: corev1.SecretTypeDockerConfigJson,
+ }
+ _, err = clientSet.CoreV1().Secrets(testNamespace.Name).Create(ctx, ngcSecret, metav1.CreateOptions{})
+ Expect(err).NotTo(HaveOccurred())
+}
diff --git a/vendor/dario.cat/mergo/.deepsource.toml b/vendor/dario.cat/mergo/.deepsource.toml
new file mode 100644
index 00000000..a8bc979e
--- /dev/null
+++ b/vendor/dario.cat/mergo/.deepsource.toml
@@ -0,0 +1,12 @@
+version = 1
+
+test_patterns = [
+ "*_test.go"
+]
+
+[[analyzers]]
+name = "go"
+enabled = true
+
+ [analyzers.meta]
+ import_path = "dario.cat/mergo"
\ No newline at end of file
diff --git a/vendor/dario.cat/mergo/.gitignore b/vendor/dario.cat/mergo/.gitignore
new file mode 100644
index 00000000..529c3412
--- /dev/null
+++ b/vendor/dario.cat/mergo/.gitignore
@@ -0,0 +1,33 @@
+#### joe made this: http://goel.io/joe
+
+#### go ####
+# Binaries for programs and plugins
+*.exe
+*.dll
+*.so
+*.dylib
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
+.glide/
+
+#### vim ####
+# Swap
+[._]*.s[a-v][a-z]
+[._]*.sw[a-p]
+[._]s[a-v][a-z]
+[._]sw[a-p]
+
+# Session
+Session.vim
+
+# Temporary
+.netrwhist
+*~
+# Auto-generated tag files
+tags
diff --git a/vendor/dario.cat/mergo/.travis.yml b/vendor/dario.cat/mergo/.travis.yml
new file mode 100644
index 00000000..d324c43b
--- /dev/null
+++ b/vendor/dario.cat/mergo/.travis.yml
@@ -0,0 +1,12 @@
+language: go
+arch:
+ - amd64
+ - ppc64le
+install:
+ - go get -t
+ - go get golang.org/x/tools/cmd/cover
+ - go get github.com/mattn/goveralls
+script:
+ - go test -race -v ./...
+after_script:
+ - $HOME/gopath/bin/goveralls -service=travis-ci -repotoken $COVERALLS_TOKEN
diff --git a/vendor/dario.cat/mergo/CODE_OF_CONDUCT.md b/vendor/dario.cat/mergo/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..469b4490
--- /dev/null
+++ b/vendor/dario.cat/mergo/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at i@dario.im. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/vendor/dario.cat/mergo/CONTRIBUTING.md b/vendor/dario.cat/mergo/CONTRIBUTING.md
new file mode 100644
index 00000000..0a1ff9f9
--- /dev/null
+++ b/vendor/dario.cat/mergo/CONTRIBUTING.md
@@ -0,0 +1,112 @@
+
+# Contributing to mergo
+
+First off, thanks for taking the time to contribute! ❤️
+
+All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉
+
+> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
+> - Star the project
+> - Tweet about it
+> - Refer this project in your project's readme
+> - Mention the project at local meetups and tell your friends/colleagues
+
+
+## Table of Contents
+
+- [Code of Conduct](#code-of-conduct)
+- [I Have a Question](#i-have-a-question)
+- [I Want To Contribute](#i-want-to-contribute)
+- [Reporting Bugs](#reporting-bugs)
+- [Suggesting Enhancements](#suggesting-enhancements)
+
+## Code of Conduct
+
+This project and everyone participating in it is governed by the
+[mergo Code of Conduct](https://github.com/imdario/mergoblob/master/CODE_OF_CONDUCT.md).
+By participating, you are expected to uphold this code. Please report unacceptable behavior
+to <>.
+
+
+## I Have a Question
+
+> If you want to ask a question, we assume that you have read the available [Documentation](https://pkg.go.dev/github.com/imdario/mergo).
+
+Before you ask a question, it is best to search for existing [Issues](https://github.com/imdario/mergo/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first.
+
+If you then still feel the need to ask a question and need clarification, we recommend the following:
+
+- Open an [Issue](https://github.com/imdario/mergo/issues/new).
+- Provide as much context as you can about what you're running into.
+- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant.
+
+We will then take care of the issue as soon as possible.
+
+## I Want To Contribute
+
+> ### Legal Notice
+> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
+
+### Reporting Bugs
+
+
+#### Before Submitting a Bug Report
+
+A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.
+
+- Make sure that you are using the latest version.
+- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](). If you are looking for support, you might want to check [this section](#i-have-a-question)).
+- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/imdario/mergoissues?q=label%3Abug).
+- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue.
+- Collect information about the bug:
+- Stack trace (Traceback)
+- OS, Platform and Version (Windows, Linux, macOS, x86, ARM)
+- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
+- Possibly your input and the output
+- Can you reliably reproduce the issue? And can you also reproduce it with older versions?
+
+
+#### How Do I Submit a Good Bug Report?
+
+> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to .
+
+
+We use GitHub issues to track bugs and errors. If you run into an issue with the project:
+
+- Open an [Issue](https://github.com/imdario/mergo/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.)
+- Explain the behavior you would expect and the actual behavior.
+- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case.
+- Provide the information you collected in the previous section.
+
+Once it's filed:
+
+- The project team will label the issue accordingly.
+- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced.
+- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be implemented by someone.
+
+### Suggesting Enhancements
+
+This section guides you through submitting an enhancement suggestion for mergo, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.
+
+
+#### Before Submitting an Enhancement
+
+- Make sure that you are using the latest version.
+- Read the [documentation]() carefully and find out if the functionality is already covered, maybe by an individual configuration.
+- Perform a [search](https://github.com/imdario/mergo/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
+- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.
+
+
+#### How Do I Submit a Good Enhancement Suggestion?
+
+Enhancement suggestions are tracked as [GitHub issues](https://github.com/imdario/mergo/issues).
+
+- Use a **clear and descriptive title** for the issue to identify the suggestion.
+- Provide a **step-by-step description of the suggested enhancement** in as many details as possible.
+- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you.
+- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.
+- **Explain why this enhancement would be useful** to most mergo users. You may also want to point out the other projects that solved it better and which could serve as inspiration.
+
+
+## Attribution
+This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)!
diff --git a/vendor/dario.cat/mergo/LICENSE b/vendor/dario.cat/mergo/LICENSE
new file mode 100644
index 00000000..68668029
--- /dev/null
+++ b/vendor/dario.cat/mergo/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2013 Dario Castañé. All rights reserved.
+Copyright (c) 2012 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/dario.cat/mergo/README.md b/vendor/dario.cat/mergo/README.md
new file mode 100644
index 00000000..7d0cf9f3
--- /dev/null
+++ b/vendor/dario.cat/mergo/README.md
@@ -0,0 +1,248 @@
+# Mergo
+
+[![GitHub release][5]][6]
+[![GoCard][7]][8]
+[![Test status][1]][2]
+[![OpenSSF Scorecard][21]][22]
+[![OpenSSF Best Practices][19]][20]
+[![Coverage status][9]][10]
+[![Sourcegraph][11]][12]
+[![FOSSA status][13]][14]
+
+[![GoDoc][3]][4]
+[![Become my sponsor][15]][16]
+[![Tidelift][17]][18]
+
+[1]: https://github.com/imdario/mergo/workflows/tests/badge.svg?branch=master
+[2]: https://github.com/imdario/mergo/actions/workflows/tests.yml
+[3]: https://godoc.org/github.com/imdario/mergo?status.svg
+[4]: https://godoc.org/github.com/imdario/mergo
+[5]: https://img.shields.io/github/release/imdario/mergo.svg
+[6]: https://github.com/imdario/mergo/releases
+[7]: https://goreportcard.com/badge/imdario/mergo
+[8]: https://goreportcard.com/report/github.com/imdario/mergo
+[9]: https://coveralls.io/repos/github/imdario/mergo/badge.svg?branch=master
+[10]: https://coveralls.io/github/imdario/mergo?branch=master
+[11]: https://sourcegraph.com/github.com/imdario/mergo/-/badge.svg
+[12]: https://sourcegraph.com/github.com/imdario/mergo?badge
+[13]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield
+[14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield
+[15]: https://img.shields.io/github/sponsors/imdario
+[16]: https://github.com/sponsors/imdario
+[17]: https://tidelift.com/badges/package/go/github.com%2Fimdario%2Fmergo
+[18]: https://tidelift.com/subscription/pkg/go-github.com-imdario-mergo
+[19]: https://bestpractices.coreinfrastructure.org/projects/7177/badge
+[20]: https://bestpractices.coreinfrastructure.org/projects/7177
+[21]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo/badge
+[22]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo
+
+A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
+
+Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
+
+Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche.
+
+## Status
+
+It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, Microsoft, etc](https://github.com/imdario/mergo#mergo-in-the-wild).
+
+### Important notes
+
+#### 1.0.0
+
+In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`.
+
+#### 0.3.9
+
+Please keep in mind that a problematic PR broke [0.3.9](//github.com/imdario/mergo/releases/tag/0.3.9). I reverted it in [0.3.10](//github.com/imdario/mergo/releases/tag/0.3.10), and I consider it stable but not bug-free. Also, this version adds support for go modules.
+
+Keep in mind that in [0.3.2](//github.com/imdario/mergo/releases/tag/0.3.2), Mergo changed `Merge()`and `Map()` signatures to support [transformers](#transformers). I added an optional/variadic argument so that it won't break the existing code.
+
+If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with ```go get -u dario.cat/mergo```. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).
+
+### Donations
+
+If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:
+
+
+
+
+
+### Mergo in the wild
+
+- [moby/moby](https://github.com/moby/moby)
+- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
+- [vmware/dispatch](https://github.com/vmware/dispatch)
+- [Shopify/themekit](https://github.com/Shopify/themekit)
+- [imdario/zas](https://github.com/imdario/zas)
+- [matcornic/hermes](https://github.com/matcornic/hermes)
+- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go)
+- [kataras/iris](https://github.com/kataras/iris)
+- [michaelsauter/crane](https://github.com/michaelsauter/crane)
+- [go-task/task](https://github.com/go-task/task)
+- [sensu/uchiwa](https://github.com/sensu/uchiwa)
+- [ory/hydra](https://github.com/ory/hydra)
+- [sisatech/vcli](https://github.com/sisatech/vcli)
+- [dairycart/dairycart](https://github.com/dairycart/dairycart)
+- [projectcalico/felix](https://github.com/projectcalico/felix)
+- [resin-os/balena](https://github.com/resin-os/balena)
+- [go-kivik/kivik](https://github.com/go-kivik/kivik)
+- [Telefonica/govice](https://github.com/Telefonica/govice)
+- [supergiant/supergiant](supergiant/supergiant)
+- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce)
+- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy)
+- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel)
+- [EagerIO/Stout](https://github.com/EagerIO/Stout)
+- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api)
+- [russross/canvasassignments](https://github.com/russross/canvasassignments)
+- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api)
+- [casualjim/exeggutor](https://github.com/casualjim/exeggutor)
+- [divshot/gitling](https://github.com/divshot/gitling)
+- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl)
+- [andrerocker/deploy42](https://github.com/andrerocker/deploy42)
+- [elwinar/rambler](https://github.com/elwinar/rambler)
+- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman)
+- [jfbus/impressionist](https://github.com/jfbus/impressionist)
+- [Jmeyering/zealot](https://github.com/Jmeyering/zealot)
+- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host)
+- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go)
+- [thoas/picfit](https://github.com/thoas/picfit)
+- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
+- [jnuthong/item_search](https://github.com/jnuthong/item_search)
+- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
+- [containerssh/containerssh](https://github.com/containerssh/containerssh)
+- [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
+- [tjpnz/structbot](https://github.com/tjpnz/structbot)
+
+## Install
+
+ go get dario.cat/mergo
+
+ // use in your .go code
+ import (
+ "dario.cat/mergo"
+ )
+
+## Usage
+
+You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as [they are zero values](https://golang.org/ref/spec#The_zero_value) too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
+
+```go
+if err := mergo.Merge(&dst, src); err != nil {
+ // ...
+}
+```
+
+Also, you can merge overwriting values using the transformer `WithOverride`.
+
+```go
+if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
+ // ...
+}
+```
+
+Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.
+
+```go
+if err := mergo.Map(&dst, srcMap); err != nil {
+ // ...
+}
+```
+
+Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as `map[string]interface{}`. They will be just assigned as values.
+
+Here is a nice example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "dario.cat/mergo"
+)
+
+type Foo struct {
+ A string
+ B int64
+}
+
+func main() {
+ src := Foo{
+ A: "one",
+ B: 2,
+ }
+ dest := Foo{
+ A: "two",
+ }
+ mergo.Merge(&dest, src)
+ fmt.Println(dest)
+ // Will print
+ // {two 2}
+}
+```
+
+Note: if test are failing due missing package, please execute:
+
+ go get gopkg.in/yaml.v3
+
+### Transformers
+
+Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?
+
+```go
+package main
+
+import (
+ "fmt"
+ "dario.cat/mergo"
+ "reflect"
+ "time"
+)
+
+type timeTransformer struct {
+}
+
+func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
+ if typ == reflect.TypeOf(time.Time{}) {
+ return func(dst, src reflect.Value) error {
+ if dst.CanSet() {
+ isZero := dst.MethodByName("IsZero")
+ result := isZero.Call([]reflect.Value{})
+ if result[0].Bool() {
+ dst.Set(src)
+ }
+ }
+ return nil
+ }
+ }
+ return nil
+}
+
+type Snapshot struct {
+ Time time.Time
+ // ...
+}
+
+func main() {
+ src := Snapshot{time.Now()}
+ dest := Snapshot{}
+ mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
+ fmt.Println(dest)
+ // Will print
+ // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
+}
+```
+
+## Contact me
+
+If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): [@im_dario](https://twitter.com/im_dario)
+
+## About
+
+Written by [Dario Castañé](http://dario.im).
+
+## License
+
+[BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE).
+
+[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_large)
diff --git a/vendor/dario.cat/mergo/SECURITY.md b/vendor/dario.cat/mergo/SECURITY.md
new file mode 100644
index 00000000..a5de61f7
--- /dev/null
+++ b/vendor/dario.cat/mergo/SECURITY.md
@@ -0,0 +1,14 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported |
+| ------- | ------------------ |
+| 0.3.x | :white_check_mark: |
+| < 0.3 | :x: |
+
+## Security contact information
+
+To report a security vulnerability, please use the
+[Tidelift security contact](https://tidelift.com/security).
+Tidelift will coordinate the fix and disclosure.
diff --git a/vendor/dario.cat/mergo/doc.go b/vendor/dario.cat/mergo/doc.go
new file mode 100644
index 00000000..7d96ec05
--- /dev/null
+++ b/vendor/dario.cat/mergo/doc.go
@@ -0,0 +1,148 @@
+// Copyright 2013 Dario Castañé. All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
+
+Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
+
+# Status
+
+It is ready for production use. It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc.
+
+# Important notes
+
+1.0.0
+
+In 1.0.0 Mergo moves to a vanity URL `dario.cat/mergo`.
+
+0.3.9
+
+Please keep in mind that a problematic PR broke 0.3.9. We reverted it in 0.3.10. We consider 0.3.10 as stable but not bug-free. . Also, this version adds suppot for go modules.
+
+Keep in mind that in 0.3.2, Mergo changed Merge() and Map() signatures to support transformers. We added an optional/variadic argument so that it won't break the existing code.
+
+If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with go get -u dario.cat/mergo. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).
+
+# Install
+
+Do your usual installation procedure:
+
+ go get dario.cat/mergo
+
+ // use in your .go code
+ import (
+ "dario.cat/mergo"
+ )
+
+# Usage
+
+You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as they are zero values too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
+
+ if err := mergo.Merge(&dst, src); err != nil {
+ // ...
+ }
+
+Also, you can merge overwriting values using the transformer WithOverride.
+
+ if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
+ // ...
+ }
+
+Additionally, you can map a map[string]interface{} to a struct (and otherwise, from struct to map), following the same restrictions as in Merge(). Keys are capitalized to find each corresponding exported field.
+
+ if err := mergo.Map(&dst, srcMap); err != nil {
+ // ...
+ }
+
+Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as map[string]interface{}. They will be just assigned as values.
+
+Here is a nice example:
+
+ package main
+
+ import (
+ "fmt"
+ "dario.cat/mergo"
+ )
+
+ type Foo struct {
+ A string
+ B int64
+ }
+
+ func main() {
+ src := Foo{
+ A: "one",
+ B: 2,
+ }
+ dest := Foo{
+ A: "two",
+ }
+ mergo.Merge(&dest, src)
+ fmt.Println(dest)
+ // Will print
+ // {two 2}
+ }
+
+# Transformers
+
+Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, time.Time is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero time.Time?
+
+ package main
+
+ import (
+ "fmt"
+ "dario.cat/mergo"
+ "reflect"
+ "time"
+ )
+
+ type timeTransformer struct {
+ }
+
+ func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
+ if typ == reflect.TypeOf(time.Time{}) {
+ return func(dst, src reflect.Value) error {
+ if dst.CanSet() {
+ isZero := dst.MethodByName("IsZero")
+ result := isZero.Call([]reflect.Value{})
+ if result[0].Bool() {
+ dst.Set(src)
+ }
+ }
+ return nil
+ }
+ }
+ return nil
+ }
+
+ type Snapshot struct {
+ Time time.Time
+ // ...
+ }
+
+ func main() {
+ src := Snapshot{time.Now()}
+ dest := Snapshot{}
+ mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
+ fmt.Println(dest)
+ // Will print
+ // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
+ }
+
+# Contact me
+
+If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): https://twitter.com/im_dario
+
+# About
+
+Written by Dario Castañé: https://da.rio.hn
+
+# License
+
+BSD 3-Clause license, as Go language.
+*/
+package mergo
diff --git a/vendor/dario.cat/mergo/map.go b/vendor/dario.cat/mergo/map.go
new file mode 100644
index 00000000..b50d5c2a
--- /dev/null
+++ b/vendor/dario.cat/mergo/map.go
@@ -0,0 +1,178 @@
+// Copyright 2014 Dario Castañé. All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Based on src/pkg/reflect/deepequal.go from official
+// golang's stdlib.
+
+package mergo
+
+import (
+ "fmt"
+ "reflect"
+ "unicode"
+ "unicode/utf8"
+)
+
+func changeInitialCase(s string, mapper func(rune) rune) string {
+ if s == "" {
+ return s
+ }
+ r, n := utf8.DecodeRuneInString(s)
+ return string(mapper(r)) + s[n:]
+}
+
+func isExported(field reflect.StructField) bool {
+ r, _ := utf8.DecodeRuneInString(field.Name)
+ return r >= 'A' && r <= 'Z'
+}
+
+// Traverses recursively both values, assigning src's fields values to dst.
+// The map argument tracks comparisons that have already been seen, which allows
+// short circuiting on recursive types.
+func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {
+ overwrite := config.Overwrite
+ if dst.CanAddr() {
+ addr := dst.UnsafeAddr()
+ h := 17 * addr
+ seen := visited[h]
+ typ := dst.Type()
+ for p := seen; p != nil; p = p.next {
+ if p.ptr == addr && p.typ == typ {
+ return nil
+ }
+ }
+ // Remember, remember...
+ visited[h] = &visit{typ, seen, addr}
+ }
+ zeroValue := reflect.Value{}
+ switch dst.Kind() {
+ case reflect.Map:
+ dstMap := dst.Interface().(map[string]interface{})
+ for i, n := 0, src.NumField(); i < n; i++ {
+ srcType := src.Type()
+ field := srcType.Field(i)
+ if !isExported(field) {
+ continue
+ }
+ fieldName := field.Name
+ fieldName = changeInitialCase(fieldName, unicode.ToLower)
+ if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v), !config.ShouldNotDereference) || overwrite) {
+ dstMap[fieldName] = src.Field(i).Interface()
+ }
+ }
+ case reflect.Ptr:
+ if dst.IsNil() {
+ v := reflect.New(dst.Type().Elem())
+ dst.Set(v)
+ }
+ dst = dst.Elem()
+ fallthrough
+ case reflect.Struct:
+ srcMap := src.Interface().(map[string]interface{})
+ for key := range srcMap {
+ config.overwriteWithEmptyValue = true
+ srcValue := srcMap[key]
+ fieldName := changeInitialCase(key, unicode.ToUpper)
+ dstElement := dst.FieldByName(fieldName)
+ if dstElement == zeroValue {
+ // We discard it because the field doesn't exist.
+ continue
+ }
+ srcElement := reflect.ValueOf(srcValue)
+ dstKind := dstElement.Kind()
+ srcKind := srcElement.Kind()
+ if srcKind == reflect.Ptr && dstKind != reflect.Ptr {
+ srcElement = srcElement.Elem()
+ srcKind = reflect.TypeOf(srcElement.Interface()).Kind()
+ } else if dstKind == reflect.Ptr {
+ // Can this work? I guess it can't.
+ if srcKind != reflect.Ptr && srcElement.CanAddr() {
+ srcPtr := srcElement.Addr()
+ srcElement = reflect.ValueOf(srcPtr)
+ srcKind = reflect.Ptr
+ }
+ }
+
+ if !srcElement.IsValid() {
+ continue
+ }
+ if srcKind == dstKind {
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ } else if dstKind == reflect.Interface && dstElement.Kind() == reflect.Interface {
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ } else if srcKind == reflect.Map {
+ if err = deepMap(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ } else {
+ return fmt.Errorf("type mismatch on %s field: found %v, expected %v", fieldName, srcKind, dstKind)
+ }
+ }
+ }
+ return
+}
+
+// Map sets fields' values in dst from src.
+// src can be a map with string keys or a struct. dst must be the opposite:
+// if src is a map, dst must be a valid pointer to struct. If src is a struct,
+// dst must be map[string]interface{}.
+// It won't merge unexported (private) fields and will do recursively
+// any exported field.
+// If dst is a map, keys will be src fields' names in lower camel case.
+// Missing key in src that doesn't match a field in dst will be skipped. This
+// doesn't apply if dst is a map.
+// This is separated method from Merge because it is cleaner and it keeps sane
+// semantics: merging equal types, mapping different (restricted) types.
+func Map(dst, src interface{}, opts ...func(*Config)) error {
+ return _map(dst, src, opts...)
+}
+
+// MapWithOverwrite will do the same as Map except that non-empty dst attributes will be overridden by
+// non-empty src attribute values.
+// Deprecated: Use Map(…) with WithOverride
+func MapWithOverwrite(dst, src interface{}, opts ...func(*Config)) error {
+ return _map(dst, src, append(opts, WithOverride)...)
+}
+
+func _map(dst, src interface{}, opts ...func(*Config)) error {
+ if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr {
+ return ErrNonPointerArgument
+ }
+ var (
+ vDst, vSrc reflect.Value
+ err error
+ )
+ config := &Config{}
+
+ for _, opt := range opts {
+ opt(config)
+ }
+
+ if vDst, vSrc, err = resolveValues(dst, src); err != nil {
+ return err
+ }
+ // To be friction-less, we redirect equal-type arguments
+ // to deepMerge. Only because arguments can be anything.
+ if vSrc.Kind() == vDst.Kind() {
+ return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
+ }
+ switch vSrc.Kind() {
+ case reflect.Struct:
+ if vDst.Kind() != reflect.Map {
+ return ErrExpectedMapAsDestination
+ }
+ case reflect.Map:
+ if vDst.Kind() != reflect.Struct {
+ return ErrExpectedStructAsDestination
+ }
+ default:
+ return ErrNotSupported
+ }
+ return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, config)
+}
diff --git a/vendor/dario.cat/mergo/merge.go b/vendor/dario.cat/mergo/merge.go
new file mode 100644
index 00000000..0ef9b213
--- /dev/null
+++ b/vendor/dario.cat/mergo/merge.go
@@ -0,0 +1,409 @@
+// Copyright 2013 Dario Castañé. All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Based on src/pkg/reflect/deepequal.go from official
+// golang's stdlib.
+
+package mergo
+
+import (
+ "fmt"
+ "reflect"
+)
+
+func hasMergeableFields(dst reflect.Value) (exported bool) {
+ for i, n := 0, dst.NumField(); i < n; i++ {
+ field := dst.Type().Field(i)
+ if field.Anonymous && dst.Field(i).Kind() == reflect.Struct {
+ exported = exported || hasMergeableFields(dst.Field(i))
+ } else if isExportedComponent(&field) {
+ exported = exported || len(field.PkgPath) == 0
+ }
+ }
+ return
+}
+
+func isExportedComponent(field *reflect.StructField) bool {
+ pkgPath := field.PkgPath
+ if len(pkgPath) > 0 {
+ return false
+ }
+ c := field.Name[0]
+ if 'a' <= c && c <= 'z' || c == '_' {
+ return false
+ }
+ return true
+}
+
+type Config struct {
+ Transformers Transformers
+ Overwrite bool
+ ShouldNotDereference bool
+ AppendSlice bool
+ TypeCheck bool
+ overwriteWithEmptyValue bool
+ overwriteSliceWithEmptyValue bool
+ sliceDeepCopy bool
+ debug bool
+}
+
+type Transformers interface {
+ Transformer(reflect.Type) func(dst, src reflect.Value) error
+}
+
+// Traverses recursively both values, assigning src's fields values to dst.
+// The map argument tracks comparisons that have already been seen, which allows
+// short circuiting on recursive types.
+func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {
+ overwrite := config.Overwrite
+ typeCheck := config.TypeCheck
+ overwriteWithEmptySrc := config.overwriteWithEmptyValue
+ overwriteSliceWithEmptySrc := config.overwriteSliceWithEmptyValue
+ sliceDeepCopy := config.sliceDeepCopy
+
+ if !src.IsValid() {
+ return
+ }
+ if dst.CanAddr() {
+ addr := dst.UnsafeAddr()
+ h := 17 * addr
+ seen := visited[h]
+ typ := dst.Type()
+ for p := seen; p != nil; p = p.next {
+ if p.ptr == addr && p.typ == typ {
+ return nil
+ }
+ }
+ // Remember, remember...
+ visited[h] = &visit{typ, seen, addr}
+ }
+
+ if config.Transformers != nil && !isReflectNil(dst) && dst.IsValid() {
+ if fn := config.Transformers.Transformer(dst.Type()); fn != nil {
+ err = fn(dst, src)
+ return
+ }
+ }
+
+ switch dst.Kind() {
+ case reflect.Struct:
+ if hasMergeableFields(dst) {
+ for i, n := 0, dst.NumField(); i < n; i++ {
+ if err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1, config); err != nil {
+ return
+ }
+ }
+ } else {
+ if dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc) {
+ dst.Set(src)
+ }
+ }
+ case reflect.Map:
+ if dst.IsNil() && !src.IsNil() {
+ if dst.CanSet() {
+ dst.Set(reflect.MakeMap(dst.Type()))
+ } else {
+ dst = src
+ return
+ }
+ }
+
+ if src.Kind() != reflect.Map {
+ if overwrite && dst.CanSet() {
+ dst.Set(src)
+ }
+ return
+ }
+
+ for _, key := range src.MapKeys() {
+ srcElement := src.MapIndex(key)
+ if !srcElement.IsValid() {
+ continue
+ }
+ dstElement := dst.MapIndex(key)
+ switch srcElement.Kind() {
+ case reflect.Chan, reflect.Func, reflect.Map, reflect.Interface, reflect.Slice:
+ if srcElement.IsNil() {
+ if overwrite {
+ dst.SetMapIndex(key, srcElement)
+ }
+ continue
+ }
+ fallthrough
+ default:
+ if !srcElement.CanInterface() {
+ continue
+ }
+ switch reflect.TypeOf(srcElement.Interface()).Kind() {
+ case reflect.Struct:
+ fallthrough
+ case reflect.Ptr:
+ fallthrough
+ case reflect.Map:
+ srcMapElm := srcElement
+ dstMapElm := dstElement
+ if srcMapElm.CanInterface() {
+ srcMapElm = reflect.ValueOf(srcMapElm.Interface())
+ if dstMapElm.IsValid() {
+ dstMapElm = reflect.ValueOf(dstMapElm.Interface())
+ }
+ }
+ if err = deepMerge(dstMapElm, srcMapElm, visited, depth+1, config); err != nil {
+ return
+ }
+ case reflect.Slice:
+ srcSlice := reflect.ValueOf(srcElement.Interface())
+
+ var dstSlice reflect.Value
+ if !dstElement.IsValid() || dstElement.IsNil() {
+ dstSlice = reflect.MakeSlice(srcSlice.Type(), 0, srcSlice.Len())
+ } else {
+ dstSlice = reflect.ValueOf(dstElement.Interface())
+ }
+
+ if (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) && !config.AppendSlice && !sliceDeepCopy {
+ if typeCheck && srcSlice.Type() != dstSlice.Type() {
+ return fmt.Errorf("cannot override two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type())
+ }
+ dstSlice = srcSlice
+ } else if config.AppendSlice {
+ if srcSlice.Type() != dstSlice.Type() {
+ return fmt.Errorf("cannot append two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type())
+ }
+ dstSlice = reflect.AppendSlice(dstSlice, srcSlice)
+ } else if sliceDeepCopy {
+ i := 0
+ for ; i < srcSlice.Len() && i < dstSlice.Len(); i++ {
+ srcElement := srcSlice.Index(i)
+ dstElement := dstSlice.Index(i)
+
+ if srcElement.CanInterface() {
+ srcElement = reflect.ValueOf(srcElement.Interface())
+ }
+ if dstElement.CanInterface() {
+ dstElement = reflect.ValueOf(dstElement.Interface())
+ }
+
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ }
+
+ }
+ dst.SetMapIndex(key, dstSlice)
+ }
+ }
+
+ if dstElement.IsValid() && !isEmptyValue(dstElement, !config.ShouldNotDereference) {
+ if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice {
+ continue
+ }
+ if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map && reflect.TypeOf(dstElement.Interface()).Kind() == reflect.Map {
+ continue
+ }
+ }
+
+ if srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement, !config.ShouldNotDereference)) {
+ if dst.IsNil() {
+ dst.Set(reflect.MakeMap(dst.Type()))
+ }
+ dst.SetMapIndex(key, srcElement)
+ }
+ }
+
+ // Ensure that all keys in dst are deleted if they are not in src.
+ if overwriteWithEmptySrc {
+ for _, key := range dst.MapKeys() {
+ srcElement := src.MapIndex(key)
+ if !srcElement.IsValid() {
+ dst.SetMapIndex(key, reflect.Value{})
+ }
+ }
+ }
+ case reflect.Slice:
+ if !dst.CanSet() {
+ break
+ }
+ if (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) && !config.AppendSlice && !sliceDeepCopy {
+ dst.Set(src)
+ } else if config.AppendSlice {
+ if src.Type() != dst.Type() {
+ return fmt.Errorf("cannot append two slice with different type (%s, %s)", src.Type(), dst.Type())
+ }
+ dst.Set(reflect.AppendSlice(dst, src))
+ } else if sliceDeepCopy {
+ for i := 0; i < src.Len() && i < dst.Len(); i++ {
+ srcElement := src.Index(i)
+ dstElement := dst.Index(i)
+ if srcElement.CanInterface() {
+ srcElement = reflect.ValueOf(srcElement.Interface())
+ }
+ if dstElement.CanInterface() {
+ dstElement = reflect.ValueOf(dstElement.Interface())
+ }
+
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ }
+ }
+ case reflect.Ptr:
+ fallthrough
+ case reflect.Interface:
+ if isReflectNil(src) {
+ if overwriteWithEmptySrc && dst.CanSet() && src.Type().AssignableTo(dst.Type()) {
+ dst.Set(src)
+ }
+ break
+ }
+
+ if src.Kind() != reflect.Interface {
+ if dst.IsNil() || (src.Kind() != reflect.Ptr && overwrite) {
+ if dst.CanSet() && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) {
+ dst.Set(src)
+ }
+ } else if src.Kind() == reflect.Ptr {
+ if !config.ShouldNotDereference {
+ if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
+ return
+ }
+ } else {
+ if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() {
+ dst.Set(src)
+ }
+ }
+ } else if dst.Elem().Type() == src.Type() {
+ if err = deepMerge(dst.Elem(), src, visited, depth+1, config); err != nil {
+ return
+ }
+ } else {
+ return ErrDifferentArgumentsTypes
+ }
+ break
+ }
+
+ if dst.IsNil() || overwrite {
+ if dst.CanSet() && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) {
+ dst.Set(src)
+ }
+ break
+ }
+
+ if dst.Elem().Kind() == src.Elem().Kind() {
+ if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
+ return
+ }
+ break
+ }
+ default:
+ mustSet := (isEmptyValue(dst, !config.ShouldNotDereference) || overwrite) && (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc)
+ if mustSet {
+ if dst.CanSet() {
+ dst.Set(src)
+ } else {
+ dst = src
+ }
+ }
+ }
+
+ return
+}
+
+// Merge will fill any empty for value type attributes on the dst struct using corresponding
+// src attributes if they themselves are not empty. dst and src must be valid same-type structs
+// and dst must be a pointer to struct.
+// It won't merge unexported (private) fields and will do recursively any exported field.
+func Merge(dst, src interface{}, opts ...func(*Config)) error {
+ return merge(dst, src, opts...)
+}
+
+// MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overridden by
+// non-empty src attribute values.
+// Deprecated: use Merge(…) with WithOverride
+func MergeWithOverwrite(dst, src interface{}, opts ...func(*Config)) error {
+ return merge(dst, src, append(opts, WithOverride)...)
+}
+
+// WithTransformers adds transformers to merge, allowing to customize the merging of some types.
+func WithTransformers(transformers Transformers) func(*Config) {
+ return func(config *Config) {
+ config.Transformers = transformers
+ }
+}
+
+// WithOverride will make merge override non-empty dst attributes with non-empty src attributes values.
+func WithOverride(config *Config) {
+ config.Overwrite = true
+}
+
+// WithOverwriteWithEmptyValue will make merge override non empty dst attributes with empty src attributes values.
+func WithOverwriteWithEmptyValue(config *Config) {
+ config.Overwrite = true
+ config.overwriteWithEmptyValue = true
+}
+
+// WithOverrideEmptySlice will make merge override empty dst slice with empty src slice.
+func WithOverrideEmptySlice(config *Config) {
+ config.overwriteSliceWithEmptyValue = true
+}
+
+// WithoutDereference prevents dereferencing pointers when evaluating whether they are empty
+// (i.e. a non-nil pointer is never considered empty).
+func WithoutDereference(config *Config) {
+ config.ShouldNotDereference = true
+}
+
+// WithAppendSlice will make merge append slices instead of overwriting it.
+func WithAppendSlice(config *Config) {
+ config.AppendSlice = true
+}
+
+// WithTypeCheck will make merge check types while overwriting it (must be used with WithOverride).
+func WithTypeCheck(config *Config) {
+ config.TypeCheck = true
+}
+
+// WithSliceDeepCopy will merge slice element one by one with Overwrite flag.
+func WithSliceDeepCopy(config *Config) {
+ config.sliceDeepCopy = true
+ config.Overwrite = true
+}
+
+func merge(dst, src interface{}, opts ...func(*Config)) error {
+ if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr {
+ return ErrNonPointerArgument
+ }
+ var (
+ vDst, vSrc reflect.Value
+ err error
+ )
+
+ config := &Config{}
+
+ for _, opt := range opts {
+ opt(config)
+ }
+
+ if vDst, vSrc, err = resolveValues(dst, src); err != nil {
+ return err
+ }
+ if vDst.Type() != vSrc.Type() {
+ return ErrDifferentArgumentsTypes
+ }
+ return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
+}
+
+// IsReflectNil is the reflect value provided nil
+func isReflectNil(v reflect.Value) bool {
+ k := v.Kind()
+ switch k {
+ case reflect.Interface, reflect.Slice, reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr:
+ // Both interface and slice are nil if first word is 0.
+ // Both are always bigger than a word; assume flagIndir.
+ return v.IsNil()
+ default:
+ return false
+ }
+}
diff --git a/vendor/dario.cat/mergo/mergo.go b/vendor/dario.cat/mergo/mergo.go
new file mode 100644
index 00000000..0a721e2d
--- /dev/null
+++ b/vendor/dario.cat/mergo/mergo.go
@@ -0,0 +1,81 @@
+// Copyright 2013 Dario Castañé. All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Based on src/pkg/reflect/deepequal.go from official
+// golang's stdlib.
+
+package mergo
+
+import (
+ "errors"
+ "reflect"
+)
+
+// Errors reported by Mergo when it finds invalid arguments.
+var (
+ ErrNilArguments = errors.New("src and dst must not be nil")
+ ErrDifferentArgumentsTypes = errors.New("src and dst must be of same type")
+ ErrNotSupported = errors.New("only structs, maps, and slices are supported")
+ ErrExpectedMapAsDestination = errors.New("dst was expected to be a map")
+ ErrExpectedStructAsDestination = errors.New("dst was expected to be a struct")
+ ErrNonPointerArgument = errors.New("dst must be a pointer")
+)
+
+// During deepMerge, must keep track of checks that are
+// in progress. The comparison algorithm assumes that all
+// checks in progress are true when it reencounters them.
+// Visited are stored in a map indexed by 17 * a1 + a2;
+type visit struct {
+ typ reflect.Type
+ next *visit
+ ptr uintptr
+}
+
+// From src/pkg/encoding/json/encode.go.
+func isEmptyValue(v reflect.Value, shouldDereference bool) bool {
+ switch v.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:
+ if v.IsNil() {
+ return true
+ }
+ if shouldDereference {
+ return isEmptyValue(v.Elem(), shouldDereference)
+ }
+ return false
+ case reflect.Func:
+ return v.IsNil()
+ case reflect.Invalid:
+ return true
+ }
+ return false
+}
+
+func resolveValues(dst, src interface{}) (vDst, vSrc reflect.Value, err error) {
+ if dst == nil || src == nil {
+ err = ErrNilArguments
+ return
+ }
+ vDst = reflect.ValueOf(dst).Elem()
+ if vDst.Kind() != reflect.Struct && vDst.Kind() != reflect.Map && vDst.Kind() != reflect.Slice {
+ err = ErrNotSupported
+ return
+ }
+ vSrc = reflect.ValueOf(src)
+ // We check if vSrc is a pointer to dereference it.
+ if vSrc.Kind() == reflect.Ptr {
+ vSrc = vSrc.Elem()
+ }
+ return
+}
diff --git a/vendor/github.com/Microsoft/go-winio/.gitattributes b/vendor/github.com/Microsoft/go-winio/.gitattributes
new file mode 100644
index 00000000..94f480de
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/.gitattributes
@@ -0,0 +1 @@
+* text=auto eol=lf
\ No newline at end of file
diff --git a/vendor/github.com/Microsoft/go-winio/.gitignore b/vendor/github.com/Microsoft/go-winio/.gitignore
new file mode 100644
index 00000000..815e2066
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/.gitignore
@@ -0,0 +1,10 @@
+.vscode/
+
+*.exe
+
+# testing
+testdata
+
+# go workspaces
+go.work
+go.work.sum
diff --git a/vendor/github.com/Microsoft/go-winio/.golangci.yml b/vendor/github.com/Microsoft/go-winio/.golangci.yml
new file mode 100644
index 00000000..7b503d26
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/.golangci.yml
@@ -0,0 +1,149 @@
+run:
+ skip-dirs:
+ - pkg/etw/sample
+
+linters:
+ enable:
+ # style
+ - containedctx # struct contains a context
+ - dupl # duplicate code
+ - errname # erorrs are named correctly
+ - nolintlint # "//nolint" directives are properly explained
+ - revive # golint replacement
+ - unconvert # unnecessary conversions
+ - wastedassign
+
+ # bugs, performance, unused, etc ...
+ - contextcheck # function uses a non-inherited context
+ - errorlint # errors not wrapped for 1.13
+ - exhaustive # check exhaustiveness of enum switch statements
+ - gofmt # files are gofmt'ed
+ - gosec # security
+ - nilerr # returns nil even with non-nil error
+ - unparam # unused function params
+
+issues:
+ exclude-rules:
+ # err is very often shadowed in nested scopes
+ - linters:
+ - govet
+ text: '^shadow: declaration of "err" shadows declaration'
+
+ # ignore long lines for skip autogen directives
+ - linters:
+ - revive
+ text: "^line-length-limit: "
+ source: "^//(go:generate|sys) "
+
+ #TODO: remove after upgrading to go1.18
+ # ignore comment spacing for nolint and sys directives
+ - linters:
+ - revive
+ text: "^comment-spacings: no space between comment delimiter and comment text"
+ source: "//(cspell:|nolint:|sys |todo)"
+
+ # not on go 1.18 yet, so no any
+ - linters:
+ - revive
+ text: "^use-any: since GO 1.18 'interface{}' can be replaced by 'any'"
+
+ # allow unjustified ignores of error checks in defer statements
+ - linters:
+ - nolintlint
+ text: "^directive `//nolint:errcheck` should provide explanation"
+ source: '^\s*defer '
+
+ # allow unjustified ignores of error lints for io.EOF
+ - linters:
+ - nolintlint
+ text: "^directive `//nolint:errorlint` should provide explanation"
+ source: '[=|!]= io.EOF'
+
+
+linters-settings:
+ exhaustive:
+ default-signifies-exhaustive: true
+ govet:
+ enable-all: true
+ disable:
+ # struct order is often for Win32 compat
+ # also, ignore pointer bytes/GC issues for now until performance becomes an issue
+ - fieldalignment
+ check-shadowing: true
+ nolintlint:
+ allow-leading-space: false
+ require-explanation: true
+ require-specific: true
+ revive:
+ # revive is more configurable than static check, so likely the preferred alternative to static-check
+ # (once the perf issue is solved: https://github.com/golangci/golangci-lint/issues/2997)
+ enable-all-rules:
+ true
+ # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md
+ rules:
+ # rules with required arguments
+ - name: argument-limit
+ disabled: true
+ - name: banned-characters
+ disabled: true
+ - name: cognitive-complexity
+ disabled: true
+ - name: cyclomatic
+ disabled: true
+ - name: file-header
+ disabled: true
+ - name: function-length
+ disabled: true
+ - name: function-result-limit
+ disabled: true
+ - name: max-public-structs
+ disabled: true
+ # geneally annoying rules
+ - name: add-constant # complains about any and all strings and integers
+ disabled: true
+ - name: confusing-naming # we frequently use "Foo()" and "foo()" together
+ disabled: true
+ - name: flag-parameter # excessive, and a common idiom we use
+ disabled: true
+ - name: unhandled-error # warns over common fmt.Print* and io.Close; rely on errcheck instead
+ disabled: true
+ # general config
+ - name: line-length-limit
+ arguments:
+ - 140
+ - name: var-naming
+ arguments:
+ - []
+ - - CID
+ - CRI
+ - CTRD
+ - DACL
+ - DLL
+ - DOS
+ - ETW
+ - FSCTL
+ - GCS
+ - GMSA
+ - HCS
+ - HV
+ - IO
+ - LCOW
+ - LDAP
+ - LPAC
+ - LTSC
+ - MMIO
+ - NT
+ - OCI
+ - PMEM
+ - PWSH
+ - RX
+ - SACl
+ - SID
+ - SMB
+ - TX
+ - VHD
+ - VHDX
+ - VMID
+ - VPCI
+ - WCOW
+ - WIM
diff --git a/vendor/github.com/Microsoft/go-winio/CODEOWNERS b/vendor/github.com/Microsoft/go-winio/CODEOWNERS
new file mode 100644
index 00000000..ae1b4942
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/CODEOWNERS
@@ -0,0 +1 @@
+ * @microsoft/containerplat
diff --git a/vendor/github.com/Microsoft/go-winio/LICENSE b/vendor/github.com/Microsoft/go-winio/LICENSE
new file mode 100644
index 00000000..b8b569d7
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Microsoft
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/vendor/github.com/Microsoft/go-winio/README.md b/vendor/github.com/Microsoft/go-winio/README.md
new file mode 100644
index 00000000..7474b4f0
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/README.md
@@ -0,0 +1,89 @@
+# go-winio [![Build Status](https://github.com/microsoft/go-winio/actions/workflows/ci.yml/badge.svg)](https://github.com/microsoft/go-winio/actions/workflows/ci.yml)
+
+This repository contains utilities for efficiently performing Win32 IO operations in
+Go. Currently, this is focused on accessing named pipes and other file handles, and
+for using named pipes as a net transport.
+
+This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go
+to reuse the thread to schedule another goroutine. This limits support to Windows Vista and
+newer operating systems. This is similar to the implementation of network sockets in Go's net
+package.
+
+Please see the LICENSE file for licensing information.
+
+## Contributing
+
+This project welcomes contributions and suggestions.
+Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that
+you have the right to, and actually do, grant us the rights to use your contribution.
+For details, visit [Microsoft CLA](https://cla.microsoft.com).
+
+When you submit a pull request, a CLA-bot will automatically determine whether you need to
+provide a CLA and decorate the PR appropriately (e.g., label, comment).
+Simply follow the instructions provided by the bot.
+You will only need to do this once across all repos using our CLA.
+
+Additionally, the pull request pipeline requires the following steps to be performed before
+mergining.
+
+### Code Sign-Off
+
+We require that contributors sign their commits using [`git commit --signoff`][git-commit-s]
+to certify they either authored the work themselves or otherwise have permission to use it in this project.
+
+A range of commits can be signed off using [`git rebase --signoff`][git-rebase-s].
+
+Please see [the developer certificate](https://developercertificate.org) for more info,
+as well as to make sure that you can attest to the rules listed.
+Our CI uses the DCO Github app to ensure that all commits in a given PR are signed-off.
+
+### Linting
+
+Code must pass a linting stage, which uses [`golangci-lint`][lint].
+The linting settings are stored in [`.golangci.yaml`](./.golangci.yaml), and can be run
+automatically with VSCode by adding the following to your workspace or folder settings:
+
+```json
+ "go.lintTool": "golangci-lint",
+ "go.lintOnSave": "package",
+```
+
+Additional editor [integrations options are also available][lint-ide].
+
+Alternatively, `golangci-lint` can be [installed locally][lint-install] and run from the repo root:
+
+```shell
+# use . or specify a path to only lint a package
+# to show all lint errors, use flags "--max-issues-per-linter=0 --max-same-issues=0"
+> golangci-lint run ./...
+```
+
+### Go Generate
+
+The pipeline checks that auto-generated code, via `go generate`, are up to date.
+
+This can be done for the entire repo:
+
+```shell
+> go generate ./...
+```
+
+## Code of Conduct
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
+For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
+contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
+
+## Special Thanks
+
+Thanks to [natefinch][natefinch] for the inspiration for this library.
+See [npipe](https://github.com/natefinch/npipe) for another named pipe implementation.
+
+[lint]: https://golangci-lint.run/
+[lint-ide]: https://golangci-lint.run/usage/integrations/#editor-integration
+[lint-install]: https://golangci-lint.run/usage/install/#local-installation
+
+[git-commit-s]: https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s
+[git-rebase-s]: https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---signoff
+
+[natefinch]: https://github.com/natefinch
diff --git a/vendor/github.com/Microsoft/go-winio/SECURITY.md b/vendor/github.com/Microsoft/go-winio/SECURITY.md
new file mode 100644
index 00000000..869fdfe2
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/SECURITY.md
@@ -0,0 +1,41 @@
+
+
+## Security
+
+Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
+
+If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
+
+## Reporting Security Issues
+
+**Please do not report security vulnerabilities through public GitHub issues.**
+
+Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
+
+If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
+
+You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
+
+Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
+
+ * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
+ * Full paths of source file(s) related to the manifestation of the issue
+ * The location of the affected source code (tag/branch/commit or direct URL)
+ * Any special configuration required to reproduce the issue
+ * Step-by-step instructions to reproduce the issue
+ * Proof-of-concept or exploit code (if possible)
+ * Impact of the issue, including how an attacker might exploit the issue
+
+This information will help us triage your report more quickly.
+
+If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
+
+## Preferred Languages
+
+We prefer all communications to be in English.
+
+## Policy
+
+Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
+
+
diff --git a/vendor/github.com/Microsoft/go-winio/backup.go b/vendor/github.com/Microsoft/go-winio/backup.go
new file mode 100644
index 00000000..09621c88
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/backup.go
@@ -0,0 +1,290 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "runtime"
+ "syscall"
+ "unicode/utf16"
+
+ "golang.org/x/sys/windows"
+)
+
+//sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead
+//sys backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite
+
+const (
+ BackupData = uint32(iota + 1)
+ BackupEaData
+ BackupSecurity
+ BackupAlternateData
+ BackupLink
+ BackupPropertyData
+ BackupObjectId //revive:disable-line:var-naming ID, not Id
+ BackupReparseData
+ BackupSparseBlock
+ BackupTxfsData
+)
+
+const (
+ StreamSparseAttributes = uint32(8)
+)
+
+//nolint:revive // var-naming: ALL_CAPS
+const (
+ WRITE_DAC = windows.WRITE_DAC
+ WRITE_OWNER = windows.WRITE_OWNER
+ ACCESS_SYSTEM_SECURITY = windows.ACCESS_SYSTEM_SECURITY
+)
+
+// BackupHeader represents a backup stream of a file.
+type BackupHeader struct {
+ //revive:disable-next-line:var-naming ID, not Id
+ Id uint32 // The backup stream ID
+ Attributes uint32 // Stream attributes
+ Size int64 // The size of the stream in bytes
+ Name string // The name of the stream (for BackupAlternateData only).
+ Offset int64 // The offset of the stream in the file (for BackupSparseBlock only).
+}
+
+type win32StreamID struct {
+ StreamID uint32
+ Attributes uint32
+ Size uint64
+ NameSize uint32
+}
+
+// BackupStreamReader reads from a stream produced by the BackupRead Win32 API and produces a series
+// of BackupHeader values.
+type BackupStreamReader struct {
+ r io.Reader
+ bytesLeft int64
+}
+
+// NewBackupStreamReader produces a BackupStreamReader from any io.Reader.
+func NewBackupStreamReader(r io.Reader) *BackupStreamReader {
+ return &BackupStreamReader{r, 0}
+}
+
+// Next returns the next backup stream and prepares for calls to Read(). It skips the remainder of the current stream if
+// it was not completely read.
+func (r *BackupStreamReader) Next() (*BackupHeader, error) {
+ if r.bytesLeft > 0 { //nolint:nestif // todo: flatten this
+ if s, ok := r.r.(io.Seeker); ok {
+ // Make sure Seek on io.SeekCurrent sometimes succeeds
+ // before trying the actual seek.
+ if _, err := s.Seek(0, io.SeekCurrent); err == nil {
+ if _, err = s.Seek(r.bytesLeft, io.SeekCurrent); err != nil {
+ return nil, err
+ }
+ r.bytesLeft = 0
+ }
+ }
+ if _, err := io.Copy(io.Discard, r); err != nil {
+ return nil, err
+ }
+ }
+ var wsi win32StreamID
+ if err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil {
+ return nil, err
+ }
+ hdr := &BackupHeader{
+ Id: wsi.StreamID,
+ Attributes: wsi.Attributes,
+ Size: int64(wsi.Size),
+ }
+ if wsi.NameSize != 0 {
+ name := make([]uint16, int(wsi.NameSize/2))
+ if err := binary.Read(r.r, binary.LittleEndian, name); err != nil {
+ return nil, err
+ }
+ hdr.Name = syscall.UTF16ToString(name)
+ }
+ if wsi.StreamID == BackupSparseBlock {
+ if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil {
+ return nil, err
+ }
+ hdr.Size -= 8
+ }
+ r.bytesLeft = hdr.Size
+ return hdr, nil
+}
+
+// Read reads from the current backup stream.
+func (r *BackupStreamReader) Read(b []byte) (int, error) {
+ if r.bytesLeft == 0 {
+ return 0, io.EOF
+ }
+ if int64(len(b)) > r.bytesLeft {
+ b = b[:r.bytesLeft]
+ }
+ n, err := r.r.Read(b)
+ r.bytesLeft -= int64(n)
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ } else if r.bytesLeft == 0 && err == nil {
+ err = io.EOF
+ }
+ return n, err
+}
+
+// BackupStreamWriter writes a stream compatible with the BackupWrite Win32 API.
+type BackupStreamWriter struct {
+ w io.Writer
+ bytesLeft int64
+}
+
+// NewBackupStreamWriter produces a BackupStreamWriter on top of an io.Writer.
+func NewBackupStreamWriter(w io.Writer) *BackupStreamWriter {
+ return &BackupStreamWriter{w, 0}
+}
+
+// WriteHeader writes the next backup stream header and prepares for calls to Write().
+func (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error {
+ if w.bytesLeft != 0 {
+ return fmt.Errorf("missing %d bytes", w.bytesLeft)
+ }
+ name := utf16.Encode([]rune(hdr.Name))
+ wsi := win32StreamID{
+ StreamID: hdr.Id,
+ Attributes: hdr.Attributes,
+ Size: uint64(hdr.Size),
+ NameSize: uint32(len(name) * 2),
+ }
+ if hdr.Id == BackupSparseBlock {
+ // Include space for the int64 block offset
+ wsi.Size += 8
+ }
+ if err := binary.Write(w.w, binary.LittleEndian, &wsi); err != nil {
+ return err
+ }
+ if len(name) != 0 {
+ if err := binary.Write(w.w, binary.LittleEndian, name); err != nil {
+ return err
+ }
+ }
+ if hdr.Id == BackupSparseBlock {
+ if err := binary.Write(w.w, binary.LittleEndian, hdr.Offset); err != nil {
+ return err
+ }
+ }
+ w.bytesLeft = hdr.Size
+ return nil
+}
+
+// Write writes to the current backup stream.
+func (w *BackupStreamWriter) Write(b []byte) (int, error) {
+ if w.bytesLeft < int64(len(b)) {
+ return 0, fmt.Errorf("too many bytes by %d", int64(len(b))-w.bytesLeft)
+ }
+ n, err := w.w.Write(b)
+ w.bytesLeft -= int64(n)
+ return n, err
+}
+
+// BackupFileReader provides an io.ReadCloser interface on top of the BackupRead Win32 API.
+type BackupFileReader struct {
+ f *os.File
+ includeSecurity bool
+ ctx uintptr
+}
+
+// NewBackupFileReader returns a new BackupFileReader from a file handle. If includeSecurity is true,
+// Read will attempt to read the security descriptor of the file.
+func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
+ r := &BackupFileReader{f, includeSecurity, 0}
+ return r
+}
+
+// Read reads a backup stream from the file by calling the Win32 API BackupRead().
+func (r *BackupFileReader) Read(b []byte) (int, error) {
+ var bytesRead uint32
+ err := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx)
+ if err != nil {
+ return 0, &os.PathError{Op: "BackupRead", Path: r.f.Name(), Err: err}
+ }
+ runtime.KeepAlive(r.f)
+ if bytesRead == 0 {
+ return 0, io.EOF
+ }
+ return int(bytesRead), nil
+}
+
+// Close frees Win32 resources associated with the BackupFileReader. It does not close
+// the underlying file.
+func (r *BackupFileReader) Close() error {
+ if r.ctx != 0 {
+ _ = backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
+ runtime.KeepAlive(r.f)
+ r.ctx = 0
+ }
+ return nil
+}
+
+// BackupFileWriter provides an io.WriteCloser interface on top of the BackupWrite Win32 API.
+type BackupFileWriter struct {
+ f *os.File
+ includeSecurity bool
+ ctx uintptr
+}
+
+// NewBackupFileWriter returns a new BackupFileWriter from a file handle. If includeSecurity is true,
+// Write() will attempt to restore the security descriptor from the stream.
+func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
+ w := &BackupFileWriter{f, includeSecurity, 0}
+ return w
+}
+
+// Write restores a portion of the file using the provided backup stream.
+func (w *BackupFileWriter) Write(b []byte) (int, error) {
+ var bytesWritten uint32
+ err := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx)
+ if err != nil {
+ return 0, &os.PathError{Op: "BackupWrite", Path: w.f.Name(), Err: err}
+ }
+ runtime.KeepAlive(w.f)
+ if int(bytesWritten) != len(b) {
+ return int(bytesWritten), errors.New("not all bytes could be written")
+ }
+ return len(b), nil
+}
+
+// Close frees Win32 resources associated with the BackupFileWriter. It does not
+// close the underlying file.
+func (w *BackupFileWriter) Close() error {
+ if w.ctx != 0 {
+ _ = backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
+ runtime.KeepAlive(w.f)
+ w.ctx = 0
+ }
+ return nil
+}
+
+// OpenForBackup opens a file or directory, potentially skipping access checks if the backup
+// or restore privileges have been acquired.
+//
+// If the file opened was a directory, it cannot be used with Readdir().
+func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) {
+ winPath, err := syscall.UTF16FromString(path)
+ if err != nil {
+ return nil, err
+ }
+ h, err := syscall.CreateFile(&winPath[0],
+ access,
+ share,
+ nil,
+ createmode,
+ syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OPEN_REPARSE_POINT,
+ 0)
+ if err != nil {
+ err = &os.PathError{Op: "open", Path: path, Err: err}
+ return nil, err
+ }
+ return os.NewFile(uintptr(h), path), nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/doc.go b/vendor/github.com/Microsoft/go-winio/doc.go
new file mode 100644
index 00000000..1f5bfe2d
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/doc.go
@@ -0,0 +1,22 @@
+// This package provides utilities for efficiently performing Win32 IO operations in Go.
+// Currently, this package is provides support for genreal IO and management of
+// - named pipes
+// - files
+// - [Hyper-V sockets]
+//
+// This code is similar to Go's [net] package, and uses IO completion ports to avoid
+// blocking IO on system threads, allowing Go to reuse the thread to schedule other goroutines.
+//
+// This limits support to Windows Vista and newer operating systems.
+//
+// Additionally, this package provides support for:
+// - creating and managing GUIDs
+// - writing to [ETW]
+// - opening and manageing VHDs
+// - parsing [Windows Image files]
+// - auto-generating Win32 API code
+//
+// [Hyper-V sockets]: https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service
+// [ETW]: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/event-tracing-for-windows--etw-
+// [Windows Image files]: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/work-with-windows-images
+package winio
diff --git a/vendor/github.com/Microsoft/go-winio/ea.go b/vendor/github.com/Microsoft/go-winio/ea.go
new file mode 100644
index 00000000..e104dbdf
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/ea.go
@@ -0,0 +1,137 @@
+package winio
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+)
+
+type fileFullEaInformation struct {
+ NextEntryOffset uint32
+ Flags uint8
+ NameLength uint8
+ ValueLength uint16
+}
+
+var (
+ fileFullEaInformationSize = binary.Size(&fileFullEaInformation{})
+
+ errInvalidEaBuffer = errors.New("invalid extended attribute buffer")
+ errEaNameTooLarge = errors.New("extended attribute name too large")
+ errEaValueTooLarge = errors.New("extended attribute value too large")
+)
+
+// ExtendedAttribute represents a single Windows EA.
+type ExtendedAttribute struct {
+ Name string
+ Value []byte
+ Flags uint8
+}
+
+func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {
+ var info fileFullEaInformation
+ err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)
+ if err != nil {
+ err = errInvalidEaBuffer
+ return ea, nb, err
+ }
+
+ nameOffset := fileFullEaInformationSize
+ nameLen := int(info.NameLength)
+ valueOffset := nameOffset + int(info.NameLength) + 1
+ valueLen := int(info.ValueLength)
+ nextOffset := int(info.NextEntryOffset)
+ if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {
+ err = errInvalidEaBuffer
+ return ea, nb, err
+ }
+
+ ea.Name = string(b[nameOffset : nameOffset+nameLen])
+ ea.Value = b[valueOffset : valueOffset+valueLen]
+ ea.Flags = info.Flags
+ if info.NextEntryOffset != 0 {
+ nb = b[info.NextEntryOffset:]
+ }
+ return ea, nb, err
+}
+
+// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION
+// buffer retrieved from BackupRead, ZwQueryEaFile, etc.
+func DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) {
+ for len(b) != 0 {
+ ea, nb, err := parseEa(b)
+ if err != nil {
+ return nil, err
+ }
+
+ eas = append(eas, ea)
+ b = nb
+ }
+ return eas, err
+}
+
+func writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error {
+ if int(uint8(len(ea.Name))) != len(ea.Name) {
+ return errEaNameTooLarge
+ }
+ if int(uint16(len(ea.Value))) != len(ea.Value) {
+ return errEaValueTooLarge
+ }
+ entrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value))
+ withPadding := (entrySize + 3) &^ 3
+ nextOffset := uint32(0)
+ if !last {
+ nextOffset = withPadding
+ }
+ info := fileFullEaInformation{
+ NextEntryOffset: nextOffset,
+ Flags: ea.Flags,
+ NameLength: uint8(len(ea.Name)),
+ ValueLength: uint16(len(ea.Value)),
+ }
+
+ err := binary.Write(buf, binary.LittleEndian, &info)
+ if err != nil {
+ return err
+ }
+
+ _, err = buf.Write([]byte(ea.Name))
+ if err != nil {
+ return err
+ }
+
+ err = buf.WriteByte(0)
+ if err != nil {
+ return err
+ }
+
+ _, err = buf.Write(ea.Value)
+ if err != nil {
+ return err
+ }
+
+ _, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize])
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// EncodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION
+// buffer for use with BackupWrite, ZwSetEaFile, etc.
+func EncodeExtendedAttributes(eas []ExtendedAttribute) ([]byte, error) {
+ var buf bytes.Buffer
+ for i := range eas {
+ last := false
+ if i == len(eas)-1 {
+ last = true
+ }
+
+ err := writeEa(&buf, &eas[i], last)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return buf.Bytes(), nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/file.go b/vendor/github.com/Microsoft/go-winio/file.go
new file mode 100644
index 00000000..175a99d3
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/file.go
@@ -0,0 +1,331 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "errors"
+ "io"
+ "runtime"
+ "sync"
+ "sync/atomic"
+ "syscall"
+ "time"
+
+ "golang.org/x/sys/windows"
+)
+
+//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx
+//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
+//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
+//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
+//sys wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
+
+type atomicBool int32
+
+func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
+func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }
+func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
+
+//revive:disable-next-line:predeclared Keep "new" to maintain consistency with "atomic" pkg
+func (b *atomicBool) swap(new bool) bool {
+ var newInt int32
+ if new {
+ newInt = 1
+ }
+ return atomic.SwapInt32((*int32)(b), newInt) == 1
+}
+
+var (
+ ErrFileClosed = errors.New("file has already been closed")
+ ErrTimeout = &timeoutError{}
+)
+
+type timeoutError struct{}
+
+func (*timeoutError) Error() string { return "i/o timeout" }
+func (*timeoutError) Timeout() bool { return true }
+func (*timeoutError) Temporary() bool { return true }
+
+type timeoutChan chan struct{}
+
+var ioInitOnce sync.Once
+var ioCompletionPort syscall.Handle
+
+// ioResult contains the result of an asynchronous IO operation.
+type ioResult struct {
+ bytes uint32
+ err error
+}
+
+// ioOperation represents an outstanding asynchronous Win32 IO.
+type ioOperation struct {
+ o syscall.Overlapped
+ ch chan ioResult
+}
+
+func initIO() {
+ h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)
+ if err != nil {
+ panic(err)
+ }
+ ioCompletionPort = h
+ go ioCompletionProcessor(h)
+}
+
+// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.
+// It takes ownership of this handle and will close it if it is garbage collected.
+type win32File struct {
+ handle syscall.Handle
+ wg sync.WaitGroup
+ wgLock sync.RWMutex
+ closing atomicBool
+ socket bool
+ readDeadline deadlineHandler
+ writeDeadline deadlineHandler
+}
+
+type deadlineHandler struct {
+ setLock sync.Mutex
+ channel timeoutChan
+ channelLock sync.RWMutex
+ timer *time.Timer
+ timedout atomicBool
+}
+
+// makeWin32File makes a new win32File from an existing file handle.
+func makeWin32File(h syscall.Handle) (*win32File, error) {
+ f := &win32File{handle: h}
+ ioInitOnce.Do(initIO)
+ _, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
+ if err != nil {
+ return nil, err
+ }
+ err = setFileCompletionNotificationModes(h, windows.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS|windows.FILE_SKIP_SET_EVENT_ON_HANDLE)
+ if err != nil {
+ return nil, err
+ }
+ f.readDeadline.channel = make(timeoutChan)
+ f.writeDeadline.channel = make(timeoutChan)
+ return f, nil
+}
+
+func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
+ // If we return the result of makeWin32File directly, it can result in an
+ // interface-wrapped nil, rather than a nil interface value.
+ f, err := makeWin32File(h)
+ if err != nil {
+ return nil, err
+ }
+ return f, nil
+}
+
+// closeHandle closes the resources associated with a Win32 handle.
+func (f *win32File) closeHandle() {
+ f.wgLock.Lock()
+ // Atomically set that we are closing, releasing the resources only once.
+ if !f.closing.swap(true) {
+ f.wgLock.Unlock()
+ // cancel all IO and wait for it to complete
+ _ = cancelIoEx(f.handle, nil)
+ f.wg.Wait()
+ // at this point, no new IO can start
+ syscall.Close(f.handle)
+ f.handle = 0
+ } else {
+ f.wgLock.Unlock()
+ }
+}
+
+// Close closes a win32File.
+func (f *win32File) Close() error {
+ f.closeHandle()
+ return nil
+}
+
+// IsClosed checks if the file has been closed.
+func (f *win32File) IsClosed() bool {
+ return f.closing.isSet()
+}
+
+// prepareIO prepares for a new IO operation.
+// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
+func (f *win32File) prepareIO() (*ioOperation, error) {
+ f.wgLock.RLock()
+ if f.closing.isSet() {
+ f.wgLock.RUnlock()
+ return nil, ErrFileClosed
+ }
+ f.wg.Add(1)
+ f.wgLock.RUnlock()
+ c := &ioOperation{}
+ c.ch = make(chan ioResult)
+ return c, nil
+}
+
+// ioCompletionProcessor processes completed async IOs forever.
+func ioCompletionProcessor(h syscall.Handle) {
+ for {
+ var bytes uint32
+ var key uintptr
+ var op *ioOperation
+ err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE)
+ if op == nil {
+ panic(err)
+ }
+ op.ch <- ioResult{bytes, err}
+ }
+}
+
+// todo: helsaawy - create an asyncIO version that takes a context
+
+// asyncIO processes the return value from ReadFile or WriteFile, blocking until
+// the operation has actually completed.
+func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
+ if err != syscall.ERROR_IO_PENDING { //nolint:errorlint // err is Errno
+ return int(bytes), err
+ }
+
+ if f.closing.isSet() {
+ _ = cancelIoEx(f.handle, &c.o)
+ }
+
+ var timeout timeoutChan
+ if d != nil {
+ d.channelLock.Lock()
+ timeout = d.channel
+ d.channelLock.Unlock()
+ }
+
+ var r ioResult
+ select {
+ case r = <-c.ch:
+ err = r.err
+ if err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
+ if f.closing.isSet() {
+ err = ErrFileClosed
+ }
+ } else if err != nil && f.socket {
+ // err is from Win32. Query the overlapped structure to get the winsock error.
+ var bytes, flags uint32
+ err = wsaGetOverlappedResult(f.handle, &c.o, &bytes, false, &flags)
+ }
+ case <-timeout:
+ _ = cancelIoEx(f.handle, &c.o)
+ r = <-c.ch
+ err = r.err
+ if err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
+ err = ErrTimeout
+ }
+ }
+
+ // runtime.KeepAlive is needed, as c is passed via native
+ // code to ioCompletionProcessor, c must remain alive
+ // until the channel read is complete.
+ // todo: (de)allocate *ioOperation via win32 heap functions, instead of needing to KeepAlive?
+ runtime.KeepAlive(c)
+ return int(r.bytes), err
+}
+
+// Read reads from a file handle.
+func (f *win32File) Read(b []byte) (int, error) {
+ c, err := f.prepareIO()
+ if err != nil {
+ return 0, err
+ }
+ defer f.wg.Done()
+
+ if f.readDeadline.timedout.isSet() {
+ return 0, ErrTimeout
+ }
+
+ var bytes uint32
+ err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
+ n, err := f.asyncIO(c, &f.readDeadline, bytes, err)
+ runtime.KeepAlive(b)
+
+ // Handle EOF conditions.
+ if err == nil && n == 0 && len(b) != 0 {
+ return 0, io.EOF
+ } else if err == syscall.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno
+ return 0, io.EOF
+ } else {
+ return n, err
+ }
+}
+
+// Write writes to a file handle.
+func (f *win32File) Write(b []byte) (int, error) {
+ c, err := f.prepareIO()
+ if err != nil {
+ return 0, err
+ }
+ defer f.wg.Done()
+
+ if f.writeDeadline.timedout.isSet() {
+ return 0, ErrTimeout
+ }
+
+ var bytes uint32
+ err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
+ n, err := f.asyncIO(c, &f.writeDeadline, bytes, err)
+ runtime.KeepAlive(b)
+ return n, err
+}
+
+func (f *win32File) SetReadDeadline(deadline time.Time) error {
+ return f.readDeadline.set(deadline)
+}
+
+func (f *win32File) SetWriteDeadline(deadline time.Time) error {
+ return f.writeDeadline.set(deadline)
+}
+
+func (f *win32File) Flush() error {
+ return syscall.FlushFileBuffers(f.handle)
+}
+
+func (f *win32File) Fd() uintptr {
+ return uintptr(f.handle)
+}
+
+func (d *deadlineHandler) set(deadline time.Time) error {
+ d.setLock.Lock()
+ defer d.setLock.Unlock()
+
+ if d.timer != nil {
+ if !d.timer.Stop() {
+ <-d.channel
+ }
+ d.timer = nil
+ }
+ d.timedout.setFalse()
+
+ select {
+ case <-d.channel:
+ d.channelLock.Lock()
+ d.channel = make(chan struct{})
+ d.channelLock.Unlock()
+ default:
+ }
+
+ if deadline.IsZero() {
+ return nil
+ }
+
+ timeoutIO := func() {
+ d.timedout.setTrue()
+ close(d.channel)
+ }
+
+ now := time.Now()
+ duration := deadline.Sub(now)
+ if deadline.After(now) {
+ // Deadline is in the future, set a timer to wait
+ d.timer = time.AfterFunc(duration, timeoutIO)
+ } else {
+ // Deadline is in the past. Cancel all pending IO now.
+ timeoutIO()
+ }
+ return nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/fileinfo.go b/vendor/github.com/Microsoft/go-winio/fileinfo.go
new file mode 100644
index 00000000..702950e7
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/fileinfo.go
@@ -0,0 +1,92 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "os"
+ "runtime"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+// FileBasicInfo contains file access time and file attributes information.
+type FileBasicInfo struct {
+ CreationTime, LastAccessTime, LastWriteTime, ChangeTime windows.Filetime
+ FileAttributes uint32
+ _ uint32 // padding
+}
+
+// GetFileBasicInfo retrieves times and attributes for a file.
+func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
+ bi := &FileBasicInfo{}
+ if err := windows.GetFileInformationByHandleEx(
+ windows.Handle(f.Fd()),
+ windows.FileBasicInfo,
+ (*byte)(unsafe.Pointer(bi)),
+ uint32(unsafe.Sizeof(*bi)),
+ ); err != nil {
+ return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
+ }
+ runtime.KeepAlive(f)
+ return bi, nil
+}
+
+// SetFileBasicInfo sets times and attributes for a file.
+func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
+ if err := windows.SetFileInformationByHandle(
+ windows.Handle(f.Fd()),
+ windows.FileBasicInfo,
+ (*byte)(unsafe.Pointer(bi)),
+ uint32(unsafe.Sizeof(*bi)),
+ ); err != nil {
+ return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
+ }
+ runtime.KeepAlive(f)
+ return nil
+}
+
+// FileStandardInfo contains extended information for the file.
+// FILE_STANDARD_INFO in WinBase.h
+// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info
+type FileStandardInfo struct {
+ AllocationSize, EndOfFile int64
+ NumberOfLinks uint32
+ DeletePending, Directory bool
+}
+
+// GetFileStandardInfo retrieves ended information for the file.
+func GetFileStandardInfo(f *os.File) (*FileStandardInfo, error) {
+ si := &FileStandardInfo{}
+ if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()),
+ windows.FileStandardInfo,
+ (*byte)(unsafe.Pointer(si)),
+ uint32(unsafe.Sizeof(*si))); err != nil {
+ return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
+ }
+ runtime.KeepAlive(f)
+ return si, nil
+}
+
+// FileIDInfo contains the volume serial number and file ID for a file. This pair should be
+// unique on a system.
+type FileIDInfo struct {
+ VolumeSerialNumber uint64
+ FileID [16]byte
+}
+
+// GetFileID retrieves the unique (volume, file ID) pair for a file.
+func GetFileID(f *os.File) (*FileIDInfo, error) {
+ fileID := &FileIDInfo{}
+ if err := windows.GetFileInformationByHandleEx(
+ windows.Handle(f.Fd()),
+ windows.FileIdInfo,
+ (*byte)(unsafe.Pointer(fileID)),
+ uint32(unsafe.Sizeof(*fileID)),
+ ); err != nil {
+ return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
+ }
+ runtime.KeepAlive(f)
+ return fileID, nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/hvsock.go b/vendor/github.com/Microsoft/go-winio/hvsock.go
new file mode 100644
index 00000000..c8819165
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/hvsock.go
@@ -0,0 +1,575 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "syscall"
+ "time"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+
+ "github.com/Microsoft/go-winio/internal/socket"
+ "github.com/Microsoft/go-winio/pkg/guid"
+)
+
+const afHVSock = 34 // AF_HYPERV
+
+// Well known Service and VM IDs
+// https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service#vmid-wildcards
+
+// HvsockGUIDWildcard is the wildcard VmId for accepting connections from all partitions.
+func HvsockGUIDWildcard() guid.GUID { // 00000000-0000-0000-0000-000000000000
+ return guid.GUID{}
+}
+
+// HvsockGUIDBroadcast is the wildcard VmId for broadcasting sends to all partitions.
+func HvsockGUIDBroadcast() guid.GUID { // ffffffff-ffff-ffff-ffff-ffffffffffff
+ return guid.GUID{
+ Data1: 0xffffffff,
+ Data2: 0xffff,
+ Data3: 0xffff,
+ Data4: [8]uint8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+ }
+}
+
+// HvsockGUIDLoopback is the Loopback VmId for accepting connections to the same partition as the connector.
+func HvsockGUIDLoopback() guid.GUID { // e0e16197-dd56-4a10-9195-5ee7a155a838
+ return guid.GUID{
+ Data1: 0xe0e16197,
+ Data2: 0xdd56,
+ Data3: 0x4a10,
+ Data4: [8]uint8{0x91, 0x95, 0x5e, 0xe7, 0xa1, 0x55, 0xa8, 0x38},
+ }
+}
+
+// HvsockGUIDSiloHost is the address of a silo's host partition:
+// - The silo host of a hosted silo is the utility VM.
+// - The silo host of a silo on a physical host is the physical host.
+func HvsockGUIDSiloHost() guid.GUID { // 36bd0c5c-7276-4223-88ba-7d03b654c568
+ return guid.GUID{
+ Data1: 0x36bd0c5c,
+ Data2: 0x7276,
+ Data3: 0x4223,
+ Data4: [8]byte{0x88, 0xba, 0x7d, 0x03, 0xb6, 0x54, 0xc5, 0x68},
+ }
+}
+
+// HvsockGUIDChildren is the wildcard VmId for accepting connections from the connector's child partitions.
+func HvsockGUIDChildren() guid.GUID { // 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd
+ return guid.GUID{
+ Data1: 0x90db8b89,
+ Data2: 0xd35,
+ Data3: 0x4f79,
+ Data4: [8]uint8{0x8c, 0xe9, 0x49, 0xea, 0xa, 0xc8, 0xb7, 0xcd},
+ }
+}
+
+// HvsockGUIDParent is the wildcard VmId for accepting connections from the connector's parent partition.
+// Listening on this VmId accepts connection from:
+// - Inside silos: silo host partition.
+// - Inside hosted silo: host of the VM.
+// - Inside VM: VM host.
+// - Physical host: Not supported.
+func HvsockGUIDParent() guid.GUID { // a42e7cda-d03f-480c-9cc2-a4de20abb878
+ return guid.GUID{
+ Data1: 0xa42e7cda,
+ Data2: 0xd03f,
+ Data3: 0x480c,
+ Data4: [8]uint8{0x9c, 0xc2, 0xa4, 0xde, 0x20, 0xab, 0xb8, 0x78},
+ }
+}
+
+// hvsockVsockServiceTemplate is the Service GUID used for the VSOCK protocol.
+func hvsockVsockServiceTemplate() guid.GUID { // 00000000-facb-11e6-bd58-64006a7986d3
+ return guid.GUID{
+ Data2: 0xfacb,
+ Data3: 0x11e6,
+ Data4: [8]uint8{0xbd, 0x58, 0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3},
+ }
+}
+
+// An HvsockAddr is an address for a AF_HYPERV socket.
+type HvsockAddr struct {
+ VMID guid.GUID
+ ServiceID guid.GUID
+}
+
+type rawHvsockAddr struct {
+ Family uint16
+ _ uint16
+ VMID guid.GUID
+ ServiceID guid.GUID
+}
+
+var _ socket.RawSockaddr = &rawHvsockAddr{}
+
+// Network returns the address's network name, "hvsock".
+func (*HvsockAddr) Network() string {
+ return "hvsock"
+}
+
+func (addr *HvsockAddr) String() string {
+ return fmt.Sprintf("%s:%s", &addr.VMID, &addr.ServiceID)
+}
+
+// VsockServiceID returns an hvsock service ID corresponding to the specified AF_VSOCK port.
+func VsockServiceID(port uint32) guid.GUID {
+ g := hvsockVsockServiceTemplate() // make a copy
+ g.Data1 = port
+ return g
+}
+
+func (addr *HvsockAddr) raw() rawHvsockAddr {
+ return rawHvsockAddr{
+ Family: afHVSock,
+ VMID: addr.VMID,
+ ServiceID: addr.ServiceID,
+ }
+}
+
+func (addr *HvsockAddr) fromRaw(raw *rawHvsockAddr) {
+ addr.VMID = raw.VMID
+ addr.ServiceID = raw.ServiceID
+}
+
+// Sockaddr returns a pointer to and the size of this struct.
+//
+// Implements the [socket.RawSockaddr] interface, and allows use in
+// [socket.Bind] and [socket.ConnectEx].
+func (r *rawHvsockAddr) Sockaddr() (unsafe.Pointer, int32, error) {
+ return unsafe.Pointer(r), int32(unsafe.Sizeof(rawHvsockAddr{})), nil
+}
+
+// Sockaddr interface allows use with `sockets.Bind()` and `.ConnectEx()`.
+func (r *rawHvsockAddr) FromBytes(b []byte) error {
+ n := int(unsafe.Sizeof(rawHvsockAddr{}))
+
+ if len(b) < n {
+ return fmt.Errorf("got %d, want %d: %w", len(b), n, socket.ErrBufferSize)
+ }
+
+ copy(unsafe.Slice((*byte)(unsafe.Pointer(r)), n), b[:n])
+ if r.Family != afHVSock {
+ return fmt.Errorf("got %d, want %d: %w", r.Family, afHVSock, socket.ErrAddrFamily)
+ }
+
+ return nil
+}
+
+// HvsockListener is a socket listener for the AF_HYPERV address family.
+type HvsockListener struct {
+ sock *win32File
+ addr HvsockAddr
+}
+
+var _ net.Listener = &HvsockListener{}
+
+// HvsockConn is a connected socket of the AF_HYPERV address family.
+type HvsockConn struct {
+ sock *win32File
+ local, remote HvsockAddr
+}
+
+var _ net.Conn = &HvsockConn{}
+
+func newHVSocket() (*win32File, error) {
+ fd, err := syscall.Socket(afHVSock, syscall.SOCK_STREAM, 1)
+ if err != nil {
+ return nil, os.NewSyscallError("socket", err)
+ }
+ f, err := makeWin32File(fd)
+ if err != nil {
+ syscall.Close(fd)
+ return nil, err
+ }
+ f.socket = true
+ return f, nil
+}
+
+// ListenHvsock listens for connections on the specified hvsock address.
+func ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) {
+ l := &HvsockListener{addr: *addr}
+ sock, err := newHVSocket()
+ if err != nil {
+ return nil, l.opErr("listen", err)
+ }
+ sa := addr.raw()
+ err = socket.Bind(windows.Handle(sock.handle), &sa)
+ if err != nil {
+ return nil, l.opErr("listen", os.NewSyscallError("socket", err))
+ }
+ err = syscall.Listen(sock.handle, 16)
+ if err != nil {
+ return nil, l.opErr("listen", os.NewSyscallError("listen", err))
+ }
+ return &HvsockListener{sock: sock, addr: *addr}, nil
+}
+
+func (l *HvsockListener) opErr(op string, err error) error {
+ return &net.OpError{Op: op, Net: "hvsock", Addr: &l.addr, Err: err}
+}
+
+// Addr returns the listener's network address.
+func (l *HvsockListener) Addr() net.Addr {
+ return &l.addr
+}
+
+// Accept waits for the next connection and returns it.
+func (l *HvsockListener) Accept() (_ net.Conn, err error) {
+ sock, err := newHVSocket()
+ if err != nil {
+ return nil, l.opErr("accept", err)
+ }
+ defer func() {
+ if sock != nil {
+ sock.Close()
+ }
+ }()
+ c, err := l.sock.prepareIO()
+ if err != nil {
+ return nil, l.opErr("accept", err)
+ }
+ defer l.sock.wg.Done()
+
+ // AcceptEx, per documentation, requires an extra 16 bytes per address.
+ //
+ // https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-acceptex
+ const addrlen = uint32(16 + unsafe.Sizeof(rawHvsockAddr{}))
+ var addrbuf [addrlen * 2]byte
+
+ var bytes uint32
+ err = syscall.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0 /* rxdatalen */, addrlen, addrlen, &bytes, &c.o)
+ if _, err = l.sock.asyncIO(c, nil, bytes, err); err != nil {
+ return nil, l.opErr("accept", os.NewSyscallError("acceptex", err))
+ }
+
+ conn := &HvsockConn{
+ sock: sock,
+ }
+ // The local address returned in the AcceptEx buffer is the same as the Listener socket's
+ // address. However, the service GUID reported by GetSockName is different from the Listeners
+ // socket, and is sometimes the same as the local address of the socket that dialed the
+ // address, with the service GUID.Data1 incremented, but othertimes is different.
+ // todo: does the local address matter? is the listener's address or the actual address appropriate?
+ conn.local.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[0])))
+ conn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen])))
+
+ // initialize the accepted socket and update its properties with those of the listening socket
+ if err = windows.Setsockopt(windows.Handle(sock.handle),
+ windows.SOL_SOCKET, windows.SO_UPDATE_ACCEPT_CONTEXT,
+ (*byte)(unsafe.Pointer(&l.sock.handle)), int32(unsafe.Sizeof(l.sock.handle))); err != nil {
+ return nil, conn.opErr("accept", os.NewSyscallError("setsockopt", err))
+ }
+
+ sock = nil
+ return conn, nil
+}
+
+// Close closes the listener, causing any pending Accept calls to fail.
+func (l *HvsockListener) Close() error {
+ return l.sock.Close()
+}
+
+// HvsockDialer configures and dials a Hyper-V Socket (ie, [HvsockConn]).
+type HvsockDialer struct {
+ // Deadline is the time the Dial operation must connect before erroring.
+ Deadline time.Time
+
+ // Retries is the number of additional connects to try if the connection times out, is refused,
+ // or the host is unreachable
+ Retries uint
+
+ // RetryWait is the time to wait after a connection error to retry
+ RetryWait time.Duration
+
+ rt *time.Timer // redial wait timer
+}
+
+// Dial the Hyper-V socket at addr.
+//
+// See [HvsockDialer.Dial] for more information.
+func Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) {
+ return (&HvsockDialer{}).Dial(ctx, addr)
+}
+
+// Dial attempts to connect to the Hyper-V socket at addr, and returns a connection if successful.
+// Will attempt (HvsockDialer).Retries if dialing fails, waiting (HvsockDialer).RetryWait between
+// retries.
+//
+// Dialing can be cancelled either by providing (HvsockDialer).Deadline, or cancelling ctx.
+func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) {
+ op := "dial"
+ // create the conn early to use opErr()
+ conn = &HvsockConn{
+ remote: *addr,
+ }
+
+ if !d.Deadline.IsZero() {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithDeadline(ctx, d.Deadline)
+ defer cancel()
+ }
+
+ // preemptive timeout/cancellation check
+ if err = ctx.Err(); err != nil {
+ return nil, conn.opErr(op, err)
+ }
+
+ sock, err := newHVSocket()
+ if err != nil {
+ return nil, conn.opErr(op, err)
+ }
+ defer func() {
+ if sock != nil {
+ sock.Close()
+ }
+ }()
+
+ sa := addr.raw()
+ err = socket.Bind(windows.Handle(sock.handle), &sa)
+ if err != nil {
+ return nil, conn.opErr(op, os.NewSyscallError("bind", err))
+ }
+
+ c, err := sock.prepareIO()
+ if err != nil {
+ return nil, conn.opErr(op, err)
+ }
+ defer sock.wg.Done()
+ var bytes uint32
+ for i := uint(0); i <= d.Retries; i++ {
+ err = socket.ConnectEx(
+ windows.Handle(sock.handle),
+ &sa,
+ nil, // sendBuf
+ 0, // sendDataLen
+ &bytes,
+ (*windows.Overlapped)(unsafe.Pointer(&c.o)))
+ _, err = sock.asyncIO(c, nil, bytes, err)
+ if i < d.Retries && canRedial(err) {
+ if err = d.redialWait(ctx); err == nil {
+ continue
+ }
+ }
+ break
+ }
+ if err != nil {
+ return nil, conn.opErr(op, os.NewSyscallError("connectex", err))
+ }
+
+ // update the connection properties, so shutdown can be used
+ if err = windows.Setsockopt(
+ windows.Handle(sock.handle),
+ windows.SOL_SOCKET,
+ windows.SO_UPDATE_CONNECT_CONTEXT,
+ nil, // optvalue
+ 0, // optlen
+ ); err != nil {
+ return nil, conn.opErr(op, os.NewSyscallError("setsockopt", err))
+ }
+
+ // get the local name
+ var sal rawHvsockAddr
+ err = socket.GetSockName(windows.Handle(sock.handle), &sal)
+ if err != nil {
+ return nil, conn.opErr(op, os.NewSyscallError("getsockname", err))
+ }
+ conn.local.fromRaw(&sal)
+
+ // one last check for timeout, since asyncIO doesn't check the context
+ if err = ctx.Err(); err != nil {
+ return nil, conn.opErr(op, err)
+ }
+
+ conn.sock = sock
+ sock = nil
+
+ return conn, nil
+}
+
+// redialWait waits before attempting to redial, resetting the timer as appropriate.
+func (d *HvsockDialer) redialWait(ctx context.Context) (err error) {
+ if d.RetryWait == 0 {
+ return nil
+ }
+
+ if d.rt == nil {
+ d.rt = time.NewTimer(d.RetryWait)
+ } else {
+ // should already be stopped and drained
+ d.rt.Reset(d.RetryWait)
+ }
+
+ select {
+ case <-ctx.Done():
+ case <-d.rt.C:
+ return nil
+ }
+
+ // stop and drain the timer
+ if !d.rt.Stop() {
+ <-d.rt.C
+ }
+ return ctx.Err()
+}
+
+// assumes error is a plain, unwrapped syscall.Errno provided by direct syscall.
+func canRedial(err error) bool {
+ //nolint:errorlint // guaranteed to be an Errno
+ switch err {
+ case windows.WSAECONNREFUSED, windows.WSAENETUNREACH, windows.WSAETIMEDOUT,
+ windows.ERROR_CONNECTION_REFUSED, windows.ERROR_CONNECTION_UNAVAIL:
+ return true
+ default:
+ return false
+ }
+}
+
+func (conn *HvsockConn) opErr(op string, err error) error {
+ // translate from "file closed" to "socket closed"
+ if errors.Is(err, ErrFileClosed) {
+ err = socket.ErrSocketClosed
+ }
+ return &net.OpError{Op: op, Net: "hvsock", Source: &conn.local, Addr: &conn.remote, Err: err}
+}
+
+func (conn *HvsockConn) Read(b []byte) (int, error) {
+ c, err := conn.sock.prepareIO()
+ if err != nil {
+ return 0, conn.opErr("read", err)
+ }
+ defer conn.sock.wg.Done()
+ buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
+ var flags, bytes uint32
+ err = syscall.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil)
+ n, err := conn.sock.asyncIO(c, &conn.sock.readDeadline, bytes, err)
+ if err != nil {
+ var eno windows.Errno
+ if errors.As(err, &eno) {
+ err = os.NewSyscallError("wsarecv", eno)
+ }
+ return 0, conn.opErr("read", err)
+ } else if n == 0 {
+ err = io.EOF
+ }
+ return n, err
+}
+
+func (conn *HvsockConn) Write(b []byte) (int, error) {
+ t := 0
+ for len(b) != 0 {
+ n, err := conn.write(b)
+ if err != nil {
+ return t + n, err
+ }
+ t += n
+ b = b[n:]
+ }
+ return t, nil
+}
+
+func (conn *HvsockConn) write(b []byte) (int, error) {
+ c, err := conn.sock.prepareIO()
+ if err != nil {
+ return 0, conn.opErr("write", err)
+ }
+ defer conn.sock.wg.Done()
+ buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
+ var bytes uint32
+ err = syscall.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil)
+ n, err := conn.sock.asyncIO(c, &conn.sock.writeDeadline, bytes, err)
+ if err != nil {
+ var eno windows.Errno
+ if errors.As(err, &eno) {
+ err = os.NewSyscallError("wsasend", eno)
+ }
+ return 0, conn.opErr("write", err)
+ }
+ return n, err
+}
+
+// Close closes the socket connection, failing any pending read or write calls.
+func (conn *HvsockConn) Close() error {
+ return conn.sock.Close()
+}
+
+func (conn *HvsockConn) IsClosed() bool {
+ return conn.sock.IsClosed()
+}
+
+// shutdown disables sending or receiving on a socket.
+func (conn *HvsockConn) shutdown(how int) error {
+ if conn.IsClosed() {
+ return socket.ErrSocketClosed
+ }
+
+ err := syscall.Shutdown(conn.sock.handle, how)
+ if err != nil {
+ // If the connection was closed, shutdowns fail with "not connected"
+ if errors.Is(err, windows.WSAENOTCONN) ||
+ errors.Is(err, windows.WSAESHUTDOWN) {
+ err = socket.ErrSocketClosed
+ }
+ return os.NewSyscallError("shutdown", err)
+ }
+ return nil
+}
+
+// CloseRead shuts down the read end of the socket, preventing future read operations.
+func (conn *HvsockConn) CloseRead() error {
+ err := conn.shutdown(syscall.SHUT_RD)
+ if err != nil {
+ return conn.opErr("closeread", err)
+ }
+ return nil
+}
+
+// CloseWrite shuts down the write end of the socket, preventing future write operations and
+// notifying the other endpoint that no more data will be written.
+func (conn *HvsockConn) CloseWrite() error {
+ err := conn.shutdown(syscall.SHUT_WR)
+ if err != nil {
+ return conn.opErr("closewrite", err)
+ }
+ return nil
+}
+
+// LocalAddr returns the local address of the connection.
+func (conn *HvsockConn) LocalAddr() net.Addr {
+ return &conn.local
+}
+
+// RemoteAddr returns the remote address of the connection.
+func (conn *HvsockConn) RemoteAddr() net.Addr {
+ return &conn.remote
+}
+
+// SetDeadline implements the net.Conn SetDeadline method.
+func (conn *HvsockConn) SetDeadline(t time.Time) error {
+ // todo: implement `SetDeadline` for `win32File`
+ if err := conn.SetReadDeadline(t); err != nil {
+ return fmt.Errorf("set read deadline: %w", err)
+ }
+ if err := conn.SetWriteDeadline(t); err != nil {
+ return fmt.Errorf("set write deadline: %w", err)
+ }
+ return nil
+}
+
+// SetReadDeadline implements the net.Conn SetReadDeadline method.
+func (conn *HvsockConn) SetReadDeadline(t time.Time) error {
+ return conn.sock.SetReadDeadline(t)
+}
+
+// SetWriteDeadline implements the net.Conn SetWriteDeadline method.
+func (conn *HvsockConn) SetWriteDeadline(t time.Time) error {
+ return conn.sock.SetWriteDeadline(t)
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/doc.go b/vendor/github.com/Microsoft/go-winio/internal/fs/doc.go
new file mode 100644
index 00000000..1f653881
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/fs/doc.go
@@ -0,0 +1,2 @@
+// This package contains Win32 filesystem functionality.
+package fs
diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go b/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
new file mode 100644
index 00000000..509b3ec6
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
@@ -0,0 +1,202 @@
+//go:build windows
+
+package fs
+
+import (
+ "golang.org/x/sys/windows"
+
+ "github.com/Microsoft/go-winio/internal/stringbuffer"
+)
+
+//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go fs.go
+
+// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
+//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW
+
+const NullHandle windows.Handle = 0
+
+// AccessMask defines standard, specific, and generic rights.
+//
+// Bitmask:
+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +---------------+---------------+-------------------------------+
+// |G|G|G|G|Resvd|A| StandardRights| SpecificRights |
+// |R|W|E|A| |S| | |
+// +-+-------------+---------------+-------------------------------+
+//
+// GR Generic Read
+// GW Generic Write
+// GE Generic Exectue
+// GA Generic All
+// Resvd Reserved
+// AS Access Security System
+//
+// https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask
+//
+// https://learn.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights
+//
+// https://learn.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants
+type AccessMask = windows.ACCESS_MASK
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ // Not actually any.
+ //
+ // For CreateFile: "query certain metadata such as file, directory, or device attributes without accessing that file or device"
+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#parameters
+ FILE_ANY_ACCESS AccessMask = 0
+
+ // Specific Object Access
+ // from ntioapi.h
+
+ FILE_READ_DATA AccessMask = (0x0001) // file & pipe
+ FILE_LIST_DIRECTORY AccessMask = (0x0001) // directory
+
+ FILE_WRITE_DATA AccessMask = (0x0002) // file & pipe
+ FILE_ADD_FILE AccessMask = (0x0002) // directory
+
+ FILE_APPEND_DATA AccessMask = (0x0004) // file
+ FILE_ADD_SUBDIRECTORY AccessMask = (0x0004) // directory
+ FILE_CREATE_PIPE_INSTANCE AccessMask = (0x0004) // named pipe
+
+ FILE_READ_EA AccessMask = (0x0008) // file & directory
+ FILE_READ_PROPERTIES AccessMask = FILE_READ_EA
+
+ FILE_WRITE_EA AccessMask = (0x0010) // file & directory
+ FILE_WRITE_PROPERTIES AccessMask = FILE_WRITE_EA
+
+ FILE_EXECUTE AccessMask = (0x0020) // file
+ FILE_TRAVERSE AccessMask = (0x0020) // directory
+
+ FILE_DELETE_CHILD AccessMask = (0x0040) // directory
+
+ FILE_READ_ATTRIBUTES AccessMask = (0x0080) // all
+
+ FILE_WRITE_ATTRIBUTES AccessMask = (0x0100) // all
+
+ FILE_ALL_ACCESS AccessMask = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
+ FILE_GENERIC_READ AccessMask = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE)
+ FILE_GENERIC_WRITE AccessMask = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)
+ FILE_GENERIC_EXECUTE AccessMask = (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE)
+
+ SPECIFIC_RIGHTS_ALL AccessMask = 0x0000FFFF
+
+ // Standard Access
+ // from ntseapi.h
+
+ DELETE AccessMask = 0x0001_0000
+ READ_CONTROL AccessMask = 0x0002_0000
+ WRITE_DAC AccessMask = 0x0004_0000
+ WRITE_OWNER AccessMask = 0x0008_0000
+ SYNCHRONIZE AccessMask = 0x0010_0000
+
+ STANDARD_RIGHTS_REQUIRED AccessMask = 0x000F_0000
+
+ STANDARD_RIGHTS_READ AccessMask = READ_CONTROL
+ STANDARD_RIGHTS_WRITE AccessMask = READ_CONTROL
+ STANDARD_RIGHTS_EXECUTE AccessMask = READ_CONTROL
+
+ STANDARD_RIGHTS_ALL AccessMask = 0x001F_0000
+)
+
+type FileShareMode uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ FILE_SHARE_NONE FileShareMode = 0x00
+ FILE_SHARE_READ FileShareMode = 0x01
+ FILE_SHARE_WRITE FileShareMode = 0x02
+ FILE_SHARE_DELETE FileShareMode = 0x04
+ FILE_SHARE_VALID_FLAGS FileShareMode = 0x07
+)
+
+type FileCreationDisposition uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ // from winbase.h
+
+ CREATE_NEW FileCreationDisposition = 0x01
+ CREATE_ALWAYS FileCreationDisposition = 0x02
+ OPEN_EXISTING FileCreationDisposition = 0x03
+ OPEN_ALWAYS FileCreationDisposition = 0x04
+ TRUNCATE_EXISTING FileCreationDisposition = 0x05
+)
+
+// CreateFile and co. take flags or attributes together as one parameter.
+// Define alias until we can use generics to allow both
+
+// https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
+type FileFlagOrAttribute uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const ( // from winnt.h
+ FILE_FLAG_WRITE_THROUGH FileFlagOrAttribute = 0x8000_0000
+ FILE_FLAG_OVERLAPPED FileFlagOrAttribute = 0x4000_0000
+ FILE_FLAG_NO_BUFFERING FileFlagOrAttribute = 0x2000_0000
+ FILE_FLAG_RANDOM_ACCESS FileFlagOrAttribute = 0x1000_0000
+ FILE_FLAG_SEQUENTIAL_SCAN FileFlagOrAttribute = 0x0800_0000
+ FILE_FLAG_DELETE_ON_CLOSE FileFlagOrAttribute = 0x0400_0000
+ FILE_FLAG_BACKUP_SEMANTICS FileFlagOrAttribute = 0x0200_0000
+ FILE_FLAG_POSIX_SEMANTICS FileFlagOrAttribute = 0x0100_0000
+ FILE_FLAG_OPEN_REPARSE_POINT FileFlagOrAttribute = 0x0020_0000
+ FILE_FLAG_OPEN_NO_RECALL FileFlagOrAttribute = 0x0010_0000
+ FILE_FLAG_FIRST_PIPE_INSTANCE FileFlagOrAttribute = 0x0008_0000
+)
+
+type FileSQSFlag = FileFlagOrAttribute
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const ( // from winbase.h
+ SECURITY_ANONYMOUS FileSQSFlag = FileSQSFlag(SecurityAnonymous << 16)
+ SECURITY_IDENTIFICATION FileSQSFlag = FileSQSFlag(SecurityIdentification << 16)
+ SECURITY_IMPERSONATION FileSQSFlag = FileSQSFlag(SecurityImpersonation << 16)
+ SECURITY_DELEGATION FileSQSFlag = FileSQSFlag(SecurityDelegation << 16)
+
+ SECURITY_SQOS_PRESENT FileSQSFlag = 0x00100000
+ SECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F0000
+)
+
+// GetFinalPathNameByHandle flags
+//
+// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew#parameters
+type GetFinalPathFlag uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ GetFinalPathDefaultFlag GetFinalPathFlag = 0x0
+
+ FILE_NAME_NORMALIZED GetFinalPathFlag = 0x0
+ FILE_NAME_OPENED GetFinalPathFlag = 0x8
+
+ VOLUME_NAME_DOS GetFinalPathFlag = 0x0
+ VOLUME_NAME_GUID GetFinalPathFlag = 0x1
+ VOLUME_NAME_NT GetFinalPathFlag = 0x2
+ VOLUME_NAME_NONE GetFinalPathFlag = 0x4
+)
+
+// getFinalPathNameByHandle facilitates calling the Windows API GetFinalPathNameByHandle
+// with the given handle and flags. It transparently takes care of creating a buffer of the
+// correct size for the call.
+//
+// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew
+func GetFinalPathNameByHandle(h windows.Handle, flags GetFinalPathFlag) (string, error) {
+ b := stringbuffer.NewWString()
+ //TODO: can loop infinitely if Win32 keeps returning the same (or a larger) n?
+ for {
+ n, err := windows.GetFinalPathNameByHandle(h, b.Pointer(), b.Cap(), uint32(flags))
+ if err != nil {
+ return "", err
+ }
+ // If the buffer wasn't large enough, n will be the total size needed (including null terminator).
+ // Resize and try again.
+ if n > b.Cap() {
+ b.ResizeTo(n)
+ continue
+ }
+ // If the buffer is large enough, n will be the size not including the null terminator.
+ // Convert to a Go string and return.
+ return b.String(), nil
+ }
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/security.go b/vendor/github.com/Microsoft/go-winio/internal/fs/security.go
new file mode 100644
index 00000000..81760ac6
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/fs/security.go
@@ -0,0 +1,12 @@
+package fs
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
+type SecurityImpersonationLevel int32 // C default enums underlying type is `int`, which is Go `int32`
+
+// Impersonation levels
+const (
+ SecurityAnonymous SecurityImpersonationLevel = 0
+ SecurityIdentification SecurityImpersonationLevel = 1
+ SecurityImpersonation SecurityImpersonationLevel = 2
+ SecurityDelegation SecurityImpersonationLevel = 3
+)
diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
new file mode 100644
index 00000000..e2f7bb24
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
@@ -0,0 +1,64 @@
+//go:build windows
+
+// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
+
+package fs
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
+
+ procCreateFileW = modkernel32.NewProc("CreateFileW")
+)
+
+func CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return
+ }
+ return _CreateFile(_p0, access, mode, sa, createmode, attrs, templatefile)
+}
+
+func _CreateFile(name *uint16, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
+ r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
+ handle = windows.Handle(r0)
+ if handle == windows.InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go b/vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go
new file mode 100644
index 00000000..7e82f9af
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go
@@ -0,0 +1,20 @@
+package socket
+
+import (
+ "unsafe"
+)
+
+// RawSockaddr allows structs to be used with [Bind] and [ConnectEx]. The
+// struct must meet the Win32 sockaddr requirements specified here:
+// https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2
+//
+// Specifically, the struct size must be least larger than an int16 (unsigned short)
+// for the address family.
+type RawSockaddr interface {
+ // Sockaddr returns a pointer to the RawSockaddr and its struct size, allowing
+ // for the RawSockaddr's data to be overwritten by syscalls (if necessary).
+ //
+ // It is the callers responsibility to validate that the values are valid; invalid
+ // pointers or size can cause a panic.
+ Sockaddr() (unsafe.Pointer, int32, error)
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go b/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
new file mode 100644
index 00000000..aeb7b725
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
@@ -0,0 +1,179 @@
+//go:build windows
+
+package socket
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "sync"
+ "syscall"
+ "unsafe"
+
+ "github.com/Microsoft/go-winio/pkg/guid"
+ "golang.org/x/sys/windows"
+)
+
+//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go socket.go
+
+//sys getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getsockname
+//sys getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getpeername
+//sys bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socketError] = ws2_32.bind
+
+const socketError = uintptr(^uint32(0))
+
+var (
+ // todo(helsaawy): create custom error types to store the desired vs actual size and addr family?
+
+ ErrBufferSize = errors.New("buffer size")
+ ErrAddrFamily = errors.New("address family")
+ ErrInvalidPointer = errors.New("invalid pointer")
+ ErrSocketClosed = fmt.Errorf("socket closed: %w", net.ErrClosed)
+)
+
+// todo(helsaawy): replace these with generics, ie: GetSockName[S RawSockaddr](s windows.Handle) (S, error)
+
+// GetSockName writes the local address of socket s to the [RawSockaddr] rsa.
+// If rsa is not large enough, the [windows.WSAEFAULT] is returned.
+func GetSockName(s windows.Handle, rsa RawSockaddr) error {
+ ptr, l, err := rsa.Sockaddr()
+ if err != nil {
+ return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
+ }
+
+ // although getsockname returns WSAEFAULT if the buffer is too small, it does not set
+ // &l to the correct size, so--apart from doubling the buffer repeatedly--there is no remedy
+ return getsockname(s, ptr, &l)
+}
+
+// GetPeerName returns the remote address the socket is connected to.
+//
+// See [GetSockName] for more information.
+func GetPeerName(s windows.Handle, rsa RawSockaddr) error {
+ ptr, l, err := rsa.Sockaddr()
+ if err != nil {
+ return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
+ }
+
+ return getpeername(s, ptr, &l)
+}
+
+func Bind(s windows.Handle, rsa RawSockaddr) (err error) {
+ ptr, l, err := rsa.Sockaddr()
+ if err != nil {
+ return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
+ }
+
+ return bind(s, ptr, l)
+}
+
+// "golang.org/x/sys/windows".ConnectEx and .Bind only accept internal implementations of the
+// their sockaddr interface, so they cannot be used with HvsockAddr
+// Replicate functionality here from
+// https://cs.opensource.google/go/x/sys/+/master:windows/syscall_windows.go
+
+// The function pointers to `AcceptEx`, `ConnectEx` and `GetAcceptExSockaddrs` must be loaded at
+// runtime via a WSAIoctl call:
+// https://docs.microsoft.com/en-us/windows/win32/api/Mswsock/nc-mswsock-lpfn_connectex#remarks
+
+type runtimeFunc struct {
+ id guid.GUID
+ once sync.Once
+ addr uintptr
+ err error
+}
+
+func (f *runtimeFunc) Load() error {
+ f.once.Do(func() {
+ var s windows.Handle
+ s, f.err = windows.Socket(windows.AF_INET, windows.SOCK_STREAM, windows.IPPROTO_TCP)
+ if f.err != nil {
+ return
+ }
+ defer windows.CloseHandle(s) //nolint:errcheck
+
+ var n uint32
+ f.err = windows.WSAIoctl(s,
+ windows.SIO_GET_EXTENSION_FUNCTION_POINTER,
+ (*byte)(unsafe.Pointer(&f.id)),
+ uint32(unsafe.Sizeof(f.id)),
+ (*byte)(unsafe.Pointer(&f.addr)),
+ uint32(unsafe.Sizeof(f.addr)),
+ &n,
+ nil, // overlapped
+ 0, // completionRoutine
+ )
+ })
+ return f.err
+}
+
+var (
+ // todo: add `AcceptEx` and `GetAcceptExSockaddrs`
+ WSAID_CONNECTEX = guid.GUID{ //revive:disable-line:var-naming ALL_CAPS
+ Data1: 0x25a207b9,
+ Data2: 0xddf3,
+ Data3: 0x4660,
+ Data4: [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},
+ }
+
+ connectExFunc = runtimeFunc{id: WSAID_CONNECTEX}
+)
+
+func ConnectEx(
+ fd windows.Handle,
+ rsa RawSockaddr,
+ sendBuf *byte,
+ sendDataLen uint32,
+ bytesSent *uint32,
+ overlapped *windows.Overlapped,
+) error {
+ if err := connectExFunc.Load(); err != nil {
+ return fmt.Errorf("failed to load ConnectEx function pointer: %w", err)
+ }
+ ptr, n, err := rsa.Sockaddr()
+ if err != nil {
+ return err
+ }
+ return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
+}
+
+// BOOL LpfnConnectex(
+// [in] SOCKET s,
+// [in] const sockaddr *name,
+// [in] int namelen,
+// [in, optional] PVOID lpSendBuffer,
+// [in] DWORD dwSendDataLength,
+// [out] LPDWORD lpdwBytesSent,
+// [in] LPOVERLAPPED lpOverlapped
+// )
+
+func connectEx(
+ s windows.Handle,
+ name unsafe.Pointer,
+ namelen int32,
+ sendBuf *byte,
+ sendDataLen uint32,
+ bytesSent *uint32,
+ overlapped *windows.Overlapped,
+) (err error) {
+ // todo: after upgrading to 1.18, switch from syscall.Syscall9 to syscall.SyscallN
+ r1, _, e1 := syscall.Syscall9(connectExFunc.addr,
+ 7,
+ uintptr(s),
+ uintptr(name),
+ uintptr(namelen),
+ uintptr(unsafe.Pointer(sendBuf)),
+ uintptr(sendDataLen),
+ uintptr(unsafe.Pointer(bytesSent)),
+ uintptr(unsafe.Pointer(overlapped)),
+ 0,
+ 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return err
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
new file mode 100644
index 00000000..6d2e1a9e
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
@@ -0,0 +1,72 @@
+//go:build windows
+
+// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
+
+package socket
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
+
+ procbind = modws2_32.NewProc("bind")
+ procgetpeername = modws2_32.NewProc("getpeername")
+ procgetsockname = modws2_32.NewProc("getsockname")
+)
+
+func bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) {
+ r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
+ if r1 == socketError {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
+ r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
+ if r1 == socketError {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
+ r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
+ if r1 == socketError {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go b/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
new file mode 100644
index 00000000..7ad50570
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
@@ -0,0 +1,132 @@
+package stringbuffer
+
+import (
+ "sync"
+ "unicode/utf16"
+)
+
+// TODO: worth exporting and using in mkwinsyscall?
+
+// Uint16BufferSize is the buffer size in the pool, chosen somewhat arbitrarily to accommodate
+// large path strings:
+// MAX_PATH (260) + size of volume GUID prefix (49) + null terminator = 310.
+const MinWStringCap = 310
+
+// use *[]uint16 since []uint16 creates an extra allocation where the slice header
+// is copied to heap and then referenced via pointer in the interface header that sync.Pool
+// stores.
+var pathPool = sync.Pool{ // if go1.18+ adds Pool[T], use that to store []uint16 directly
+ New: func() interface{} {
+ b := make([]uint16, MinWStringCap)
+ return &b
+ },
+}
+
+func newBuffer() []uint16 { return *(pathPool.Get().(*[]uint16)) }
+
+// freeBuffer copies the slice header data, and puts a pointer to that in the pool.
+// This avoids taking a pointer to the slice header in WString, which can be set to nil.
+func freeBuffer(b []uint16) { pathPool.Put(&b) }
+
+// WString is a wide string buffer ([]uint16) meant for storing UTF-16 encoded strings
+// for interacting with Win32 APIs.
+// Sizes are specified as uint32 and not int.
+//
+// It is not thread safe.
+type WString struct {
+ // type-def allows casting to []uint16 directly, use struct to prevent that and allow adding fields in the future.
+
+ // raw buffer
+ b []uint16
+}
+
+// NewWString returns a [WString] allocated from a shared pool with an
+// initial capacity of at least [MinWStringCap].
+// Since the buffer may have been previously used, its contents are not guaranteed to be empty.
+//
+// The buffer should be freed via [WString.Free]
+func NewWString() *WString {
+ return &WString{
+ b: newBuffer(),
+ }
+}
+
+func (b *WString) Free() {
+ if b.empty() {
+ return
+ }
+ freeBuffer(b.b)
+ b.b = nil
+}
+
+// ResizeTo grows the buffer to at least c and returns the new capacity, freeing the
+// previous buffer back into pool.
+func (b *WString) ResizeTo(c uint32) uint32 {
+ // allready sufficient (or n is 0)
+ if c <= b.Cap() {
+ return b.Cap()
+ }
+
+ if c <= MinWStringCap {
+ c = MinWStringCap
+ }
+ // allocate at-least double buffer size, as is done in [bytes.Buffer] and other places
+ if c <= 2*b.Cap() {
+ c = 2 * b.Cap()
+ }
+
+ b2 := make([]uint16, c)
+ if !b.empty() {
+ copy(b2, b.b)
+ freeBuffer(b.b)
+ }
+ b.b = b2
+ return c
+}
+
+// Buffer returns the underlying []uint16 buffer.
+func (b *WString) Buffer() []uint16 {
+ if b.empty() {
+ return nil
+ }
+ return b.b
+}
+
+// Pointer returns a pointer to the first uint16 in the buffer.
+// If the [WString.Free] has already been called, the pointer will be nil.
+func (b *WString) Pointer() *uint16 {
+ if b.empty() {
+ return nil
+ }
+ return &b.b[0]
+}
+
+// String returns the returns the UTF-8 encoding of the UTF-16 string in the buffer.
+//
+// It assumes that the data is null-terminated.
+func (b *WString) String() string {
+ // Using [windows.UTF16ToString] would require importing "golang.org/x/sys/windows"
+ // and would make this code Windows-only, which makes no sense.
+ // So copy UTF16ToString code into here.
+ // If other windows-specific code is added, switch to [windows.UTF16ToString]
+
+ s := b.b
+ for i, v := range s {
+ if v == 0 {
+ s = s[:i]
+ break
+ }
+ }
+ return string(utf16.Decode(s))
+}
+
+// Cap returns the underlying buffer capacity.
+func (b *WString) Cap() uint32 {
+ if b.empty() {
+ return 0
+ }
+ return b.cap()
+}
+
+func (b *WString) cap() uint32 { return uint32(cap(b.b)) }
+func (b *WString) empty() bool { return b == nil || b.cap() == 0 }
diff --git a/vendor/github.com/Microsoft/go-winio/pipe.go b/vendor/github.com/Microsoft/go-winio/pipe.go
new file mode 100644
index 00000000..25cc8110
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pipe.go
@@ -0,0 +1,525 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "runtime"
+ "syscall"
+ "time"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+
+ "github.com/Microsoft/go-winio/internal/fs"
+)
+
+//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
+//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW
+//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
+//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
+//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
+//sys ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) = ntdll.NtCreateNamedPipeFile
+//sys rtlNtStatusToDosError(status ntStatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
+//sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) = ntdll.RtlDosPathNameToNtPathName_U
+//sys rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) = ntdll.RtlDefaultNpAcl
+
+type ioStatusBlock struct {
+ Status, Information uintptr
+}
+
+type objectAttributes struct {
+ Length uintptr
+ RootDirectory uintptr
+ ObjectName *unicodeString
+ Attributes uintptr
+ SecurityDescriptor *securityDescriptor
+ SecurityQoS uintptr
+}
+
+type unicodeString struct {
+ Length uint16
+ MaximumLength uint16
+ Buffer uintptr
+}
+
+type securityDescriptor struct {
+ Revision byte
+ Sbz1 byte
+ Control uint16
+ Owner uintptr
+ Group uintptr
+ Sacl uintptr //revive:disable-line:var-naming SACL, not Sacl
+ Dacl uintptr //revive:disable-line:var-naming DACL, not Dacl
+}
+
+type ntStatus int32
+
+func (status ntStatus) Err() error {
+ if status >= 0 {
+ return nil
+ }
+ return rtlNtStatusToDosError(status)
+}
+
+var (
+ // ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed.
+ ErrPipeListenerClosed = net.ErrClosed
+
+ errPipeWriteClosed = errors.New("pipe has been closed for write")
+)
+
+type win32Pipe struct {
+ *win32File
+ path string
+}
+
+type win32MessageBytePipe struct {
+ win32Pipe
+ writeClosed bool
+ readEOF bool
+}
+
+type pipeAddress string
+
+func (f *win32Pipe) LocalAddr() net.Addr {
+ return pipeAddress(f.path)
+}
+
+func (f *win32Pipe) RemoteAddr() net.Addr {
+ return pipeAddress(f.path)
+}
+
+func (f *win32Pipe) SetDeadline(t time.Time) error {
+ if err := f.SetReadDeadline(t); err != nil {
+ return err
+ }
+ return f.SetWriteDeadline(t)
+}
+
+// CloseWrite closes the write side of a message pipe in byte mode.
+func (f *win32MessageBytePipe) CloseWrite() error {
+ if f.writeClosed {
+ return errPipeWriteClosed
+ }
+ err := f.win32File.Flush()
+ if err != nil {
+ return err
+ }
+ _, err = f.win32File.Write(nil)
+ if err != nil {
+ return err
+ }
+ f.writeClosed = true
+ return nil
+}
+
+// Write writes bytes to a message pipe in byte mode. Zero-byte writes are ignored, since
+// they are used to implement CloseWrite().
+func (f *win32MessageBytePipe) Write(b []byte) (int, error) {
+ if f.writeClosed {
+ return 0, errPipeWriteClosed
+ }
+ if len(b) == 0 {
+ return 0, nil
+ }
+ return f.win32File.Write(b)
+}
+
+// Read reads bytes from a message pipe in byte mode. A read of a zero-byte message on a message
+// mode pipe will return io.EOF, as will all subsequent reads.
+func (f *win32MessageBytePipe) Read(b []byte) (int, error) {
+ if f.readEOF {
+ return 0, io.EOF
+ }
+ n, err := f.win32File.Read(b)
+ if err == io.EOF { //nolint:errorlint
+ // If this was the result of a zero-byte read, then
+ // it is possible that the read was due to a zero-size
+ // message. Since we are simulating CloseWrite with a
+ // zero-byte message, ensure that all future Read() calls
+ // also return EOF.
+ f.readEOF = true
+ } else if err == syscall.ERROR_MORE_DATA { //nolint:errorlint // err is Errno
+ // ERROR_MORE_DATA indicates that the pipe's read mode is message mode
+ // and the message still has more bytes. Treat this as a success, since
+ // this package presents all named pipes as byte streams.
+ err = nil
+ }
+ return n, err
+}
+
+func (pipeAddress) Network() string {
+ return "pipe"
+}
+
+func (s pipeAddress) String() string {
+ return string(s)
+}
+
+// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout.
+func tryDialPipe(ctx context.Context, path *string, access fs.AccessMask) (syscall.Handle, error) {
+ for {
+ select {
+ case <-ctx.Done():
+ return syscall.Handle(0), ctx.Err()
+ default:
+ wh, err := fs.CreateFile(*path,
+ access,
+ 0, // mode
+ nil, // security attributes
+ fs.OPEN_EXISTING,
+ fs.FILE_FLAG_OVERLAPPED|fs.SECURITY_SQOS_PRESENT|fs.SECURITY_ANONYMOUS,
+ 0, // template file handle
+ )
+ h := syscall.Handle(wh)
+ if err == nil {
+ return h, nil
+ }
+ if err != windows.ERROR_PIPE_BUSY { //nolint:errorlint // err is Errno
+ return h, &os.PathError{Err: err, Op: "open", Path: *path}
+ }
+ // Wait 10 msec and try again. This is a rather simplistic
+ // view, as we always try each 10 milliseconds.
+ time.Sleep(10 * time.Millisecond)
+ }
+ }
+}
+
+// DialPipe connects to a named pipe by path, timing out if the connection
+// takes longer than the specified duration. If timeout is nil, then we use
+// a default timeout of 2 seconds. (We do not use WaitNamedPipe.)
+func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
+ var absTimeout time.Time
+ if timeout != nil {
+ absTimeout = time.Now().Add(*timeout)
+ } else {
+ absTimeout = time.Now().Add(2 * time.Second)
+ }
+ ctx, cancel := context.WithDeadline(context.Background(), absTimeout)
+ defer cancel()
+ conn, err := DialPipeContext(ctx, path)
+ if errors.Is(err, context.DeadlineExceeded) {
+ return nil, ErrTimeout
+ }
+ return conn, err
+}
+
+// DialPipeContext attempts to connect to a named pipe by `path` until `ctx`
+// cancellation or timeout.
+func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
+ return DialPipeAccess(ctx, path, syscall.GENERIC_READ|syscall.GENERIC_WRITE)
+}
+
+// DialPipeAccess attempts to connect to a named pipe by `path` with `access` until `ctx`
+// cancellation or timeout.
+func DialPipeAccess(ctx context.Context, path string, access uint32) (net.Conn, error) {
+ var err error
+ var h syscall.Handle
+ h, err = tryDialPipe(ctx, &path, fs.AccessMask(access))
+ if err != nil {
+ return nil, err
+ }
+
+ var flags uint32
+ err = getNamedPipeInfo(h, &flags, nil, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ f, err := makeWin32File(h)
+ if err != nil {
+ syscall.Close(h)
+ return nil, err
+ }
+
+ // If the pipe is in message mode, return a message byte pipe, which
+ // supports CloseWrite().
+ if flags&windows.PIPE_TYPE_MESSAGE != 0 {
+ return &win32MessageBytePipe{
+ win32Pipe: win32Pipe{win32File: f, path: path},
+ }, nil
+ }
+ return &win32Pipe{win32File: f, path: path}, nil
+}
+
+type acceptResponse struct {
+ f *win32File
+ err error
+}
+
+type win32PipeListener struct {
+ firstHandle syscall.Handle
+ path string
+ config PipeConfig
+ acceptCh chan (chan acceptResponse)
+ closeCh chan int
+ doneCh chan int
+}
+
+func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
+ path16, err := syscall.UTF16FromString(path)
+ if err != nil {
+ return 0, &os.PathError{Op: "open", Path: path, Err: err}
+ }
+
+ var oa objectAttributes
+ oa.Length = unsafe.Sizeof(oa)
+
+ var ntPath unicodeString
+ if err := rtlDosPathNameToNtPathName(&path16[0],
+ &ntPath,
+ 0,
+ 0,
+ ).Err(); err != nil {
+ return 0, &os.PathError{Op: "open", Path: path, Err: err}
+ }
+ defer localFree(ntPath.Buffer)
+ oa.ObjectName = &ntPath
+ oa.Attributes = windows.OBJ_CASE_INSENSITIVE
+
+ // The security descriptor is only needed for the first pipe.
+ if first {
+ if sd != nil {
+ l := uint32(len(sd))
+ sdb := localAlloc(0, l)
+ defer localFree(sdb)
+ copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd)
+ oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb))
+ } else {
+ // Construct the default named pipe security descriptor.
+ var dacl uintptr
+ if err := rtlDefaultNpAcl(&dacl).Err(); err != nil {
+ return 0, fmt.Errorf("getting default named pipe ACL: %w", err)
+ }
+ defer localFree(dacl)
+
+ sdb := &securityDescriptor{
+ Revision: 1,
+ Control: windows.SE_DACL_PRESENT,
+ Dacl: dacl,
+ }
+ oa.SecurityDescriptor = sdb
+ }
+ }
+
+ typ := uint32(windows.FILE_PIPE_REJECT_REMOTE_CLIENTS)
+ if c.MessageMode {
+ typ |= windows.FILE_PIPE_MESSAGE_TYPE
+ }
+
+ disposition := uint32(windows.FILE_OPEN)
+ access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | syscall.SYNCHRONIZE)
+ if first {
+ disposition = windows.FILE_CREATE
+ // By not asking for read or write access, the named pipe file system
+ // will put this pipe into an initially disconnected state, blocking
+ // client connections until the next call with first == false.
+ access = syscall.SYNCHRONIZE
+ }
+
+ timeout := int64(-50 * 10000) // 50ms
+
+ var (
+ h syscall.Handle
+ iosb ioStatusBlock
+ )
+ err = ntCreateNamedPipeFile(&h,
+ access,
+ &oa,
+ &iosb,
+ syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE,
+ disposition,
+ 0,
+ typ,
+ 0,
+ 0,
+ 0xffffffff,
+ uint32(c.InputBufferSize),
+ uint32(c.OutputBufferSize),
+ &timeout).Err()
+ if err != nil {
+ return 0, &os.PathError{Op: "open", Path: path, Err: err}
+ }
+
+ runtime.KeepAlive(ntPath)
+ return h, nil
+}
+
+func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
+ h, err := makeServerPipeHandle(l.path, nil, &l.config, false)
+ if err != nil {
+ return nil, err
+ }
+ f, err := makeWin32File(h)
+ if err != nil {
+ syscall.Close(h)
+ return nil, err
+ }
+ return f, nil
+}
+
+func (l *win32PipeListener) makeConnectedServerPipe() (*win32File, error) {
+ p, err := l.makeServerPipe()
+ if err != nil {
+ return nil, err
+ }
+
+ // Wait for the client to connect.
+ ch := make(chan error)
+ go func(p *win32File) {
+ ch <- connectPipe(p)
+ }(p)
+
+ select {
+ case err = <-ch:
+ if err != nil {
+ p.Close()
+ p = nil
+ }
+ case <-l.closeCh:
+ // Abort the connect request by closing the handle.
+ p.Close()
+ p = nil
+ err = <-ch
+ if err == nil || err == ErrFileClosed { //nolint:errorlint // err is Errno
+ err = ErrPipeListenerClosed
+ }
+ }
+ return p, err
+}
+
+func (l *win32PipeListener) listenerRoutine() {
+ closed := false
+ for !closed {
+ select {
+ case <-l.closeCh:
+ closed = true
+ case responseCh := <-l.acceptCh:
+ var (
+ p *win32File
+ err error
+ )
+ for {
+ p, err = l.makeConnectedServerPipe()
+ // If the connection was immediately closed by the client, try
+ // again.
+ if err != windows.ERROR_NO_DATA { //nolint:errorlint // err is Errno
+ break
+ }
+ }
+ responseCh <- acceptResponse{p, err}
+ closed = err == ErrPipeListenerClosed //nolint:errorlint // err is Errno
+ }
+ }
+ syscall.Close(l.firstHandle)
+ l.firstHandle = 0
+ // Notify Close() and Accept() callers that the handle has been closed.
+ close(l.doneCh)
+}
+
+// PipeConfig contain configuration for the pipe listener.
+type PipeConfig struct {
+ // SecurityDescriptor contains a Windows security descriptor in SDDL format.
+ SecurityDescriptor string
+
+ // MessageMode determines whether the pipe is in byte or message mode. In either
+ // case the pipe is read in byte mode by default. The only practical difference in
+ // this implementation is that CloseWrite() is only supported for message mode pipes;
+ // CloseWrite() is implemented as a zero-byte write, but zero-byte writes are only
+ // transferred to the reader (and returned as io.EOF in this implementation)
+ // when the pipe is in message mode.
+ MessageMode bool
+
+ // InputBufferSize specifies the size of the input buffer, in bytes.
+ InputBufferSize int32
+
+ // OutputBufferSize specifies the size of the output buffer, in bytes.
+ OutputBufferSize int32
+}
+
+// ListenPipe creates a listener on a Windows named pipe path, e.g. \\.\pipe\mypipe.
+// The pipe must not already exist.
+func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
+ var (
+ sd []byte
+ err error
+ )
+ if c == nil {
+ c = &PipeConfig{}
+ }
+ if c.SecurityDescriptor != "" {
+ sd, err = SddlToSecurityDescriptor(c.SecurityDescriptor)
+ if err != nil {
+ return nil, err
+ }
+ }
+ h, err := makeServerPipeHandle(path, sd, c, true)
+ if err != nil {
+ return nil, err
+ }
+ l := &win32PipeListener{
+ firstHandle: h,
+ path: path,
+ config: *c,
+ acceptCh: make(chan (chan acceptResponse)),
+ closeCh: make(chan int),
+ doneCh: make(chan int),
+ }
+ go l.listenerRoutine()
+ return l, nil
+}
+
+func connectPipe(p *win32File) error {
+ c, err := p.prepareIO()
+ if err != nil {
+ return err
+ }
+ defer p.wg.Done()
+
+ err = connectNamedPipe(p.handle, &c.o)
+ _, err = p.asyncIO(c, nil, 0, err)
+ if err != nil && err != windows.ERROR_PIPE_CONNECTED { //nolint:errorlint // err is Errno
+ return err
+ }
+ return nil
+}
+
+func (l *win32PipeListener) Accept() (net.Conn, error) {
+ ch := make(chan acceptResponse)
+ select {
+ case l.acceptCh <- ch:
+ response := <-ch
+ err := response.err
+ if err != nil {
+ return nil, err
+ }
+ if l.config.MessageMode {
+ return &win32MessageBytePipe{
+ win32Pipe: win32Pipe{win32File: response.f, path: l.path},
+ }, nil
+ }
+ return &win32Pipe{win32File: response.f, path: l.path}, nil
+ case <-l.doneCh:
+ return nil, ErrPipeListenerClosed
+ }
+}
+
+func (l *win32PipeListener) Close() error {
+ select {
+ case l.closeCh <- 1:
+ <-l.doneCh
+ case <-l.doneCh:
+ }
+ return nil
+}
+
+func (l *win32PipeListener) Addr() net.Addr {
+ return pipeAddress(l.path)
+}
diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
new file mode 100644
index 00000000..48ce4e92
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
@@ -0,0 +1,232 @@
+// Package guid provides a GUID type. The backing structure for a GUID is
+// identical to that used by the golang.org/x/sys/windows GUID type.
+// There are two main binary encodings used for a GUID, the big-endian encoding,
+// and the Windows (mixed-endian) encoding. See here for details:
+// https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding
+package guid
+
+import (
+ "crypto/rand"
+ "crypto/sha1" //nolint:gosec // not used for secure application
+ "encoding"
+ "encoding/binary"
+ "fmt"
+ "strconv"
+)
+
+//go:generate go run golang.org/x/tools/cmd/stringer -type=Variant -trimprefix=Variant -linecomment
+
+// Variant specifies which GUID variant (or "type") of the GUID. It determines
+// how the entirety of the rest of the GUID is interpreted.
+type Variant uint8
+
+// The variants specified by RFC 4122 section 4.1.1.
+const (
+ // VariantUnknown specifies a GUID variant which does not conform to one of
+ // the variant encodings specified in RFC 4122.
+ VariantUnknown Variant = iota
+ VariantNCS
+ VariantRFC4122 // RFC 4122
+ VariantMicrosoft
+ VariantFuture
+)
+
+// Version specifies how the bits in the GUID were generated. For instance, a
+// version 4 GUID is randomly generated, and a version 5 is generated from the
+// hash of an input string.
+type Version uint8
+
+func (v Version) String() string {
+ return strconv.FormatUint(uint64(v), 10)
+}
+
+var _ = (encoding.TextMarshaler)(GUID{})
+var _ = (encoding.TextUnmarshaler)(&GUID{})
+
+// NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122.
+func NewV4() (GUID, error) {
+ var b [16]byte
+ if _, err := rand.Read(b[:]); err != nil {
+ return GUID{}, err
+ }
+
+ g := FromArray(b)
+ g.setVersion(4) // Version 4 means randomly generated.
+ g.setVariant(VariantRFC4122)
+
+ return g, nil
+}
+
+// NewV5 returns a new version 5 (generated from a string via SHA-1 hashing)
+// GUID, as defined by RFC 4122. The RFC is unclear on the encoding of the name,
+// and the sample code treats it as a series of bytes, so we do the same here.
+//
+// Some implementations, such as those found on Windows, treat the name as a
+// big-endian UTF16 stream of bytes. If that is desired, the string can be
+// encoded as such before being passed to this function.
+func NewV5(namespace GUID, name []byte) (GUID, error) {
+ b := sha1.New() //nolint:gosec // not used for secure application
+ namespaceBytes := namespace.ToArray()
+ b.Write(namespaceBytes[:])
+ b.Write(name)
+
+ a := [16]byte{}
+ copy(a[:], b.Sum(nil))
+
+ g := FromArray(a)
+ g.setVersion(5) // Version 5 means generated from a string.
+ g.setVariant(VariantRFC4122)
+
+ return g, nil
+}
+
+func fromArray(b [16]byte, order binary.ByteOrder) GUID {
+ var g GUID
+ g.Data1 = order.Uint32(b[0:4])
+ g.Data2 = order.Uint16(b[4:6])
+ g.Data3 = order.Uint16(b[6:8])
+ copy(g.Data4[:], b[8:16])
+ return g
+}
+
+func (g GUID) toArray(order binary.ByteOrder) [16]byte {
+ b := [16]byte{}
+ order.PutUint32(b[0:4], g.Data1)
+ order.PutUint16(b[4:6], g.Data2)
+ order.PutUint16(b[6:8], g.Data3)
+ copy(b[8:16], g.Data4[:])
+ return b
+}
+
+// FromArray constructs a GUID from a big-endian encoding array of 16 bytes.
+func FromArray(b [16]byte) GUID {
+ return fromArray(b, binary.BigEndian)
+}
+
+// ToArray returns an array of 16 bytes representing the GUID in big-endian
+// encoding.
+func (g GUID) ToArray() [16]byte {
+ return g.toArray(binary.BigEndian)
+}
+
+// FromWindowsArray constructs a GUID from a Windows encoding array of bytes.
+func FromWindowsArray(b [16]byte) GUID {
+ return fromArray(b, binary.LittleEndian)
+}
+
+// ToWindowsArray returns an array of 16 bytes representing the GUID in Windows
+// encoding.
+func (g GUID) ToWindowsArray() [16]byte {
+ return g.toArray(binary.LittleEndian)
+}
+
+func (g GUID) String() string {
+ return fmt.Sprintf(
+ "%08x-%04x-%04x-%04x-%012x",
+ g.Data1,
+ g.Data2,
+ g.Data3,
+ g.Data4[:2],
+ g.Data4[2:])
+}
+
+// FromString parses a string containing a GUID and returns the GUID. The only
+// format currently supported is the `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
+// format.
+func FromString(s string) (GUID, error) {
+ if len(s) != 36 {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+
+ var g GUID
+
+ data1, err := strconv.ParseUint(s[0:8], 16, 32)
+ if err != nil {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ g.Data1 = uint32(data1)
+
+ data2, err := strconv.ParseUint(s[9:13], 16, 16)
+ if err != nil {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ g.Data2 = uint16(data2)
+
+ data3, err := strconv.ParseUint(s[14:18], 16, 16)
+ if err != nil {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ g.Data3 = uint16(data3)
+
+ for i, x := range []int{19, 21, 24, 26, 28, 30, 32, 34} {
+ v, err := strconv.ParseUint(s[x:x+2], 16, 8)
+ if err != nil {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ g.Data4[i] = uint8(v)
+ }
+
+ return g, nil
+}
+
+func (g *GUID) setVariant(v Variant) {
+ d := g.Data4[0]
+ switch v {
+ case VariantNCS:
+ d = (d & 0x7f)
+ case VariantRFC4122:
+ d = (d & 0x3f) | 0x80
+ case VariantMicrosoft:
+ d = (d & 0x1f) | 0xc0
+ case VariantFuture:
+ d = (d & 0x0f) | 0xe0
+ case VariantUnknown:
+ fallthrough
+ default:
+ panic(fmt.Sprintf("invalid variant: %d", v))
+ }
+ g.Data4[0] = d
+}
+
+// Variant returns the GUID variant, as defined in RFC 4122.
+func (g GUID) Variant() Variant {
+ b := g.Data4[0]
+ if b&0x80 == 0 {
+ return VariantNCS
+ } else if b&0xc0 == 0x80 {
+ return VariantRFC4122
+ } else if b&0xe0 == 0xc0 {
+ return VariantMicrosoft
+ } else if b&0xe0 == 0xe0 {
+ return VariantFuture
+ }
+ return VariantUnknown
+}
+
+func (g *GUID) setVersion(v Version) {
+ g.Data3 = (g.Data3 & 0x0fff) | (uint16(v) << 12)
+}
+
+// Version returns the GUID version, as defined in RFC 4122.
+func (g GUID) Version() Version {
+ return Version((g.Data3 & 0xF000) >> 12)
+}
+
+// MarshalText returns the textual representation of the GUID.
+func (g GUID) MarshalText() ([]byte, error) {
+ return []byte(g.String()), nil
+}
+
+// UnmarshalText takes the textual representation of a GUID, and unmarhals it
+// into this GUID.
+func (g *GUID) UnmarshalText(text []byte) error {
+ g2, err := FromString(string(text))
+ if err != nil {
+ return err
+ }
+ *g = g2
+ return nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go
new file mode 100644
index 00000000..805bd354
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go
@@ -0,0 +1,16 @@
+//go:build !windows
+// +build !windows
+
+package guid
+
+// GUID represents a GUID/UUID. It has the same structure as
+// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
+// that type. It is defined as its own type as that is only available to builds
+// targeted at `windows`. The representation matches that used by native Windows
+// code.
+type GUID struct {
+ Data1 uint32
+ Data2 uint16
+ Data3 uint16
+ Data4 [8]byte
+}
diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go
new file mode 100644
index 00000000..27e45ee5
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go
@@ -0,0 +1,13 @@
+//go:build windows
+// +build windows
+
+package guid
+
+import "golang.org/x/sys/windows"
+
+// GUID represents a GUID/UUID. It has the same structure as
+// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
+// that type. It is defined as its own type so that stringification and
+// marshaling can be supported. The representation matches that used by native
+// Windows code.
+type GUID windows.GUID
diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go
new file mode 100644
index 00000000..4076d313
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go
@@ -0,0 +1,27 @@
+// Code generated by "stringer -type=Variant -trimprefix=Variant -linecomment"; DO NOT EDIT.
+
+package guid
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[VariantUnknown-0]
+ _ = x[VariantNCS-1]
+ _ = x[VariantRFC4122-2]
+ _ = x[VariantMicrosoft-3]
+ _ = x[VariantFuture-4]
+}
+
+const _Variant_name = "UnknownNCSRFC 4122MicrosoftFuture"
+
+var _Variant_index = [...]uint8{0, 7, 10, 18, 27, 33}
+
+func (i Variant) String() string {
+ if i >= Variant(len(_Variant_index)-1) {
+ return "Variant(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _Variant_name[_Variant_index[i]:_Variant_index[i+1]]
+}
diff --git a/vendor/github.com/Microsoft/go-winio/privilege.go b/vendor/github.com/Microsoft/go-winio/privilege.go
new file mode 100644
index 00000000..0ff9dac9
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/privilege.go
@@ -0,0 +1,197 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "runtime"
+ "sync"
+ "syscall"
+ "unicode/utf16"
+
+ "golang.org/x/sys/windows"
+)
+
+//sys adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
+//sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf
+//sys revertToSelf() (err error) = advapi32.RevertToSelf
+//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken
+//sys getCurrentThread() (h syscall.Handle) = GetCurrentThread
+//sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW
+//sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW
+//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW
+
+const (
+ //revive:disable-next-line:var-naming ALL_CAPS
+ SE_PRIVILEGE_ENABLED = windows.SE_PRIVILEGE_ENABLED
+
+ //revive:disable-next-line:var-naming ALL_CAPS
+ ERROR_NOT_ALL_ASSIGNED syscall.Errno = windows.ERROR_NOT_ALL_ASSIGNED
+
+ SeBackupPrivilege = "SeBackupPrivilege"
+ SeRestorePrivilege = "SeRestorePrivilege"
+ SeSecurityPrivilege = "SeSecurityPrivilege"
+)
+
+var (
+ privNames = make(map[string]uint64)
+ privNameMutex sync.Mutex
+)
+
+// PrivilegeError represents an error enabling privileges.
+type PrivilegeError struct {
+ privileges []uint64
+}
+
+func (e *PrivilegeError) Error() string {
+ s := "Could not enable privilege "
+ if len(e.privileges) > 1 {
+ s = "Could not enable privileges "
+ }
+ for i, p := range e.privileges {
+ if i != 0 {
+ s += ", "
+ }
+ s += `"`
+ s += getPrivilegeName(p)
+ s += `"`
+ }
+ return s
+}
+
+// RunWithPrivilege enables a single privilege for a function call.
+func RunWithPrivilege(name string, fn func() error) error {
+ return RunWithPrivileges([]string{name}, fn)
+}
+
+// RunWithPrivileges enables privileges for a function call.
+func RunWithPrivileges(names []string, fn func() error) error {
+ privileges, err := mapPrivileges(names)
+ if err != nil {
+ return err
+ }
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+ token, err := newThreadToken()
+ if err != nil {
+ return err
+ }
+ defer releaseThreadToken(token)
+ err = adjustPrivileges(token, privileges, SE_PRIVILEGE_ENABLED)
+ if err != nil {
+ return err
+ }
+ return fn()
+}
+
+func mapPrivileges(names []string) ([]uint64, error) {
+ privileges := make([]uint64, 0, len(names))
+ privNameMutex.Lock()
+ defer privNameMutex.Unlock()
+ for _, name := range names {
+ p, ok := privNames[name]
+ if !ok {
+ err := lookupPrivilegeValue("", name, &p)
+ if err != nil {
+ return nil, err
+ }
+ privNames[name] = p
+ }
+ privileges = append(privileges, p)
+ }
+ return privileges, nil
+}
+
+// EnableProcessPrivileges enables privileges globally for the process.
+func EnableProcessPrivileges(names []string) error {
+ return enableDisableProcessPrivilege(names, SE_PRIVILEGE_ENABLED)
+}
+
+// DisableProcessPrivileges disables privileges globally for the process.
+func DisableProcessPrivileges(names []string) error {
+ return enableDisableProcessPrivilege(names, 0)
+}
+
+func enableDisableProcessPrivilege(names []string, action uint32) error {
+ privileges, err := mapPrivileges(names)
+ if err != nil {
+ return err
+ }
+
+ p := windows.CurrentProcess()
+ var token windows.Token
+ err = windows.OpenProcessToken(p, windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, &token)
+ if err != nil {
+ return err
+ }
+
+ defer token.Close()
+ return adjustPrivileges(token, privileges, action)
+}
+
+func adjustPrivileges(token windows.Token, privileges []uint64, action uint32) error {
+ var b bytes.Buffer
+ _ = binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))
+ for _, p := range privileges {
+ _ = binary.Write(&b, binary.LittleEndian, p)
+ _ = binary.Write(&b, binary.LittleEndian, action)
+ }
+ prevState := make([]byte, b.Len())
+ reqSize := uint32(0)
+ success, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize)
+ if !success {
+ return err
+ }
+ if err == ERROR_NOT_ALL_ASSIGNED { //nolint:errorlint // err is Errno
+ return &PrivilegeError{privileges}
+ }
+ return nil
+}
+
+func getPrivilegeName(luid uint64) string {
+ var nameBuffer [256]uint16
+ bufSize := uint32(len(nameBuffer))
+ err := lookupPrivilegeName("", &luid, &nameBuffer[0], &bufSize)
+ if err != nil {
+ return fmt.Sprintf("", luid)
+ }
+
+ var displayNameBuffer [256]uint16
+ displayBufSize := uint32(len(displayNameBuffer))
+ var langID uint32
+ err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langID)
+ if err != nil {
+ return fmt.Sprintf("", string(utf16.Decode(nameBuffer[:bufSize])))
+ }
+
+ return string(utf16.Decode(displayNameBuffer[:displayBufSize]))
+}
+
+func newThreadToken() (windows.Token, error) {
+ err := impersonateSelf(windows.SecurityImpersonation)
+ if err != nil {
+ return 0, err
+ }
+
+ var token windows.Token
+ err = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token)
+ if err != nil {
+ rerr := revertToSelf()
+ if rerr != nil {
+ panic(rerr)
+ }
+ return 0, err
+ }
+ return token, nil
+}
+
+func releaseThreadToken(h windows.Token) {
+ err := revertToSelf()
+ if err != nil {
+ panic(err)
+ }
+ h.Close()
+}
diff --git a/vendor/github.com/Microsoft/go-winio/reparse.go b/vendor/github.com/Microsoft/go-winio/reparse.go
new file mode 100644
index 00000000..67d1a104
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/reparse.go
@@ -0,0 +1,131 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "strings"
+ "unicode/utf16"
+ "unsafe"
+)
+
+const (
+ reparseTagMountPoint = 0xA0000003
+ reparseTagSymlink = 0xA000000C
+)
+
+type reparseDataBuffer struct {
+ ReparseTag uint32
+ ReparseDataLength uint16
+ Reserved uint16
+ SubstituteNameOffset uint16
+ SubstituteNameLength uint16
+ PrintNameOffset uint16
+ PrintNameLength uint16
+}
+
+// ReparsePoint describes a Win32 symlink or mount point.
+type ReparsePoint struct {
+ Target string
+ IsMountPoint bool
+}
+
+// UnsupportedReparsePointError is returned when trying to decode a non-symlink or
+// mount point reparse point.
+type UnsupportedReparsePointError struct {
+ Tag uint32
+}
+
+func (e *UnsupportedReparsePointError) Error() string {
+ return fmt.Sprintf("unsupported reparse point %x", e.Tag)
+}
+
+// DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink
+// or a mount point.
+func DecodeReparsePoint(b []byte) (*ReparsePoint, error) {
+ tag := binary.LittleEndian.Uint32(b[0:4])
+ return DecodeReparsePointData(tag, b[8:])
+}
+
+func DecodeReparsePointData(tag uint32, b []byte) (*ReparsePoint, error) {
+ isMountPoint := false
+ switch tag {
+ case reparseTagMountPoint:
+ isMountPoint = true
+ case reparseTagSymlink:
+ default:
+ return nil, &UnsupportedReparsePointError{tag}
+ }
+ nameOffset := 8 + binary.LittleEndian.Uint16(b[4:6])
+ if !isMountPoint {
+ nameOffset += 4
+ }
+ nameLength := binary.LittleEndian.Uint16(b[6:8])
+ name := make([]uint16, nameLength/2)
+ err := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name)
+ if err != nil {
+ return nil, err
+ }
+ return &ReparsePoint{string(utf16.Decode(name)), isMountPoint}, nil
+}
+
+func isDriveLetter(c byte) bool {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+}
+
+// EncodeReparsePoint encodes a Win32 REPARSE_DATA_BUFFER structure describing a symlink or
+// mount point.
+func EncodeReparsePoint(rp *ReparsePoint) []byte {
+ // Generate an NT path and determine if this is a relative path.
+ var ntTarget string
+ relative := false
+ if strings.HasPrefix(rp.Target, `\\?\`) {
+ ntTarget = `\??\` + rp.Target[4:]
+ } else if strings.HasPrefix(rp.Target, `\\`) {
+ ntTarget = `\??\UNC\` + rp.Target[2:]
+ } else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' {
+ ntTarget = `\??\` + rp.Target
+ } else {
+ ntTarget = rp.Target
+ relative = true
+ }
+
+ // The paths must be NUL-terminated even though they are counted strings.
+ target16 := utf16.Encode([]rune(rp.Target + "\x00"))
+ ntTarget16 := utf16.Encode([]rune(ntTarget + "\x00"))
+
+ size := int(unsafe.Sizeof(reparseDataBuffer{})) - 8
+ size += len(ntTarget16)*2 + len(target16)*2
+
+ tag := uint32(reparseTagMountPoint)
+ if !rp.IsMountPoint {
+ tag = reparseTagSymlink
+ size += 4 // Add room for symlink flags
+ }
+
+ data := reparseDataBuffer{
+ ReparseTag: tag,
+ ReparseDataLength: uint16(size),
+ SubstituteNameOffset: 0,
+ SubstituteNameLength: uint16((len(ntTarget16) - 1) * 2),
+ PrintNameOffset: uint16(len(ntTarget16) * 2),
+ PrintNameLength: uint16((len(target16) - 1) * 2),
+ }
+
+ var b bytes.Buffer
+ _ = binary.Write(&b, binary.LittleEndian, &data)
+ if !rp.IsMountPoint {
+ flags := uint32(0)
+ if relative {
+ flags |= 1
+ }
+ _ = binary.Write(&b, binary.LittleEndian, flags)
+ }
+
+ _ = binary.Write(&b, binary.LittleEndian, ntTarget16)
+ _ = binary.Write(&b, binary.LittleEndian, target16)
+ return b.Bytes()
+}
diff --git a/vendor/github.com/Microsoft/go-winio/sd.go b/vendor/github.com/Microsoft/go-winio/sd.go
new file mode 100644
index 00000000..5550ef6b
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/sd.go
@@ -0,0 +1,144 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "errors"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW
+//sys lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountSidW
+//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW
+//sys convertStringSidToSid(str *uint16, sid **byte) (err error) = advapi32.ConvertStringSidToSidW
+//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
+//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
+//sys localFree(mem uintptr) = LocalFree
+//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength
+
+type AccountLookupError struct {
+ Name string
+ Err error
+}
+
+func (e *AccountLookupError) Error() string {
+ if e.Name == "" {
+ return "lookup account: empty account name specified"
+ }
+ var s string
+ switch {
+ case errors.Is(e.Err, windows.ERROR_INVALID_SID):
+ s = "the security ID structure is invalid"
+ case errors.Is(e.Err, windows.ERROR_NONE_MAPPED):
+ s = "not found"
+ default:
+ s = e.Err.Error()
+ }
+ return "lookup account " + e.Name + ": " + s
+}
+
+func (e *AccountLookupError) Unwrap() error { return e.Err }
+
+type SddlConversionError struct {
+ Sddl string
+ Err error
+}
+
+func (e *SddlConversionError) Error() string {
+ return "convert " + e.Sddl + ": " + e.Err.Error()
+}
+
+func (e *SddlConversionError) Unwrap() error { return e.Err }
+
+// LookupSidByName looks up the SID of an account by name
+//
+//revive:disable-next-line:var-naming SID, not Sid
+func LookupSidByName(name string) (sid string, err error) {
+ if name == "" {
+ return "", &AccountLookupError{name, windows.ERROR_NONE_MAPPED}
+ }
+
+ var sidSize, sidNameUse, refDomainSize uint32
+ err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse)
+ if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno
+ return "", &AccountLookupError{name, err}
+ }
+ sidBuffer := make([]byte, sidSize)
+ refDomainBuffer := make([]uint16, refDomainSize)
+ err = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)
+ if err != nil {
+ return "", &AccountLookupError{name, err}
+ }
+ var strBuffer *uint16
+ err = convertSidToStringSid(&sidBuffer[0], &strBuffer)
+ if err != nil {
+ return "", &AccountLookupError{name, err}
+ }
+ sid = syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:])
+ localFree(uintptr(unsafe.Pointer(strBuffer)))
+ return sid, nil
+}
+
+// LookupNameBySid looks up the name of an account by SID
+//
+//revive:disable-next-line:var-naming SID, not Sid
+func LookupNameBySid(sid string) (name string, err error) {
+ if sid == "" {
+ return "", &AccountLookupError{sid, windows.ERROR_NONE_MAPPED}
+ }
+
+ sidBuffer, err := windows.UTF16PtrFromString(sid)
+ if err != nil {
+ return "", &AccountLookupError{sid, err}
+ }
+
+ var sidPtr *byte
+ if err = convertStringSidToSid(sidBuffer, &sidPtr); err != nil {
+ return "", &AccountLookupError{sid, err}
+ }
+ defer localFree(uintptr(unsafe.Pointer(sidPtr)))
+
+ var nameSize, refDomainSize, sidNameUse uint32
+ err = lookupAccountSid(nil, sidPtr, nil, &nameSize, nil, &refDomainSize, &sidNameUse)
+ if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno
+ return "", &AccountLookupError{sid, err}
+ }
+
+ nameBuffer := make([]uint16, nameSize)
+ refDomainBuffer := make([]uint16, refDomainSize)
+ err = lookupAccountSid(nil, sidPtr, &nameBuffer[0], &nameSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)
+ if err != nil {
+ return "", &AccountLookupError{sid, err}
+ }
+
+ name = windows.UTF16ToString(nameBuffer)
+ return name, nil
+}
+
+func SddlToSecurityDescriptor(sddl string) ([]byte, error) {
+ var sdBuffer uintptr
+ err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil)
+ if err != nil {
+ return nil, &SddlConversionError{sddl, err}
+ }
+ defer localFree(sdBuffer)
+ sd := make([]byte, getSecurityDescriptorLength(sdBuffer))
+ copy(sd, (*[0xffff]byte)(unsafe.Pointer(sdBuffer))[:len(sd)])
+ return sd, nil
+}
+
+func SecurityDescriptorToSddl(sd []byte) (string, error) {
+ var sddl *uint16
+ // The returned string length seems to include an arbitrary number of terminating NULs.
+ // Don't use it.
+ err := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil)
+ if err != nil {
+ return "", err
+ }
+ defer localFree(uintptr(unsafe.Pointer(sddl)))
+ return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(sddl))[:]), nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/syscall.go b/vendor/github.com/Microsoft/go-winio/syscall.go
new file mode 100644
index 00000000..a6ca111b
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/syscall.go
@@ -0,0 +1,5 @@
+//go:build windows
+
+package winio
+
+//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go ./*.go
diff --git a/vendor/github.com/Microsoft/go-winio/tools.go b/vendor/github.com/Microsoft/go-winio/tools.go
new file mode 100644
index 00000000..2aa04584
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/tools.go
@@ -0,0 +1,5 @@
+//go:build tools
+
+package winio
+
+import _ "golang.org/x/tools/cmd/stringer"
diff --git a/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
new file mode 100644
index 00000000..469b16f6
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
@@ -0,0 +1,419 @@
+//go:build windows
+
+// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
+
+package winio
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
+ modntdll = windows.NewLazySystemDLL("ntdll.dll")
+ modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
+
+ procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
+ procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
+ procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
+ procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
+ procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW")
+ procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
+ procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
+ procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
+ procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW")
+ procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
+ procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
+ procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
+ procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
+ procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
+ procBackupRead = modkernel32.NewProc("BackupRead")
+ procBackupWrite = modkernel32.NewProc("BackupWrite")
+ procCancelIoEx = modkernel32.NewProc("CancelIoEx")
+ procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
+ procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
+ procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
+ procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
+ procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
+ procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
+ procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
+ procLocalAlloc = modkernel32.NewProc("LocalAlloc")
+ procLocalFree = modkernel32.NewProc("LocalFree")
+ procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
+ procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
+ procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
+ procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
+ procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
+ procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
+)
+
+func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
+ var _p0 uint32
+ if releaseAll {
+ _p0 = 1
+ }
+ r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
+ success = r0 != 0
+ if true {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func convertSidToStringSid(sid *byte, str **uint16) (err error) {
+ r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(str)
+ if err != nil {
+ return
+ }
+ return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)
+}
+
+func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func convertStringSidToSid(str *uint16, sid **byte) (err error) {
+ r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(sid)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getSecurityDescriptorLength(sd uintptr) (len uint32) {
+ r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
+ len = uint32(r0)
+ return
+}
+
+func impersonateSelf(level uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(accountName)
+ if err != nil {
+ return
+ }
+ return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
+}
+
+func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(systemName)
+ if err != nil {
+ return
+ }
+ return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
+}
+
+func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(systemName)
+ if err != nil {
+ return
+ }
+ return _lookupPrivilegeName(_p0, luid, buffer, size)
+}
+
+func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(systemName)
+ if err != nil {
+ return
+ }
+ var _p1 *uint16
+ _p1, err = syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return
+ }
+ return _lookupPrivilegeValue(_p0, _p1, luid)
+}
+
+func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
+ r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
+ var _p0 uint32
+ if openAsSelf {
+ _p0 = 1
+ }
+ r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func revertToSelf() (err error) {
+ r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
+ var _p0 *byte
+ if len(b) > 0 {
+ _p0 = &b[0]
+ }
+ var _p1 uint32
+ if abort {
+ _p1 = 1
+ }
+ var _p2 uint32
+ if processSecurity {
+ _p2 = 1
+ }
+ r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
+ var _p0 *byte
+ if len(b) > 0 {
+ _p0 = &b[0]
+ }
+ var _p1 uint32
+ if abort {
+ _p1 = 1
+ }
+ var _p2 uint32
+ if processSecurity {
+ _p2 = 1
+ }
+ r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
+ r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
+ r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
+ r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
+ newport = syscall.Handle(r0)
+ if newport == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return
+ }
+ return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
+}
+
+func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
+ r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
+ handle = syscall.Handle(r0)
+ if handle == syscall.InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getCurrentThread() (h syscall.Handle) {
+ r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
+ h = syscall.Handle(r0)
+ return
+}
+
+func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
+ r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
+ r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
+ ptr = uintptr(r0)
+ return
+}
+
+func localFree(mem uintptr) {
+ syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
+ return
+}
+
+func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
+ r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) {
+ r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
+ status = ntStatus(r0)
+ return
+}
+
+func rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) {
+ r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
+ status = ntStatus(r0)
+ return
+}
+
+func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) {
+ r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
+ status = ntStatus(r0)
+ return
+}
+
+func rtlNtStatusToDosError(status ntStatus) (winerr error) {
+ r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
+ if r0 != 0 {
+ winerr = syscall.Errno(r0)
+ }
+ return
+}
+
+func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
+ var _p0 uint32
+ if wait {
+ _p0 = 1
+ }
+ r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/vendor/github.com/NVIDIA/k8s-test-infra/pkg/framework/framework.go b/vendor/github.com/NVIDIA/k8s-test-infra/pkg/framework/framework.go
deleted file mode 100644
index 38cf0c75..00000000
--- a/vendor/github.com/NVIDIA/k8s-test-infra/pkg/framework/framework.go
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
- *
- * 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 framework contains provider-independent helper code for
-// building and running E2E tests with Ginkgo. The actual Ginkgo test
-// suites gets assembled by combining this framework, the optional
-// provider support code and specific tests via a separate .go file
-// like Kubernetes' test/e2e.go.
-package framework
-
-import (
- "context"
- "errors"
- "fmt"
- "log"
- "math/rand"
- "os"
- "path/filepath"
- "time"
-
- helm "github.com/mittwald/go-helm-client"
- "github.com/onsi/ginkgo/v2"
- "github.com/onsi/gomega"
- corev1 "k8s.io/api/core/v1"
- apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
- apierrors "k8s.io/apimachinery/pkg/api/errors"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/runtime/schema"
- clientset "k8s.io/client-go/kubernetes"
- "k8s.io/client-go/rest"
-)
-
-const (
- // DefaultNamespaceDeletionTimeout is timeout duration for waiting for a namespace deletion.
- DefaultNamespaceDeletionTimeout = 5 * time.Minute
-)
-
-// Options is a struct for managing test framework options.
-type Options struct {
- ClientQPS float32
- ClientBurst int
- GroupVersion *schema.GroupVersion
-}
-
-// Framework supports common operations used by e2e tests; it will keep a client & a namespace for you.
-// Eventual goal is to merge this with integration test framework.
-//
-// You can configure the pod security level for your test by setting the `NamespacePodSecurityLevel`
-// which will set all three of pod security admission enforce, warn and audit labels on the namespace.
-// The default pod security profile is "restricted".
-// Each of the labels can be overridden by using more specific NamespacePodSecurity* attributes of this
-// struct.
-type Framework struct {
- BaseName string
-
- // Set together with creating the ClientSet and the namespace.
- // Guaranteed to be unique in the cluster even when running the same
- // test multiple times in parallel.
- UniqueName string
-
- clientConfig *rest.Config
- ClientSet clientset.Interface
- ApiExtClient *apiextensionsclientset.Clientset
-
- // Helm
- HelmClient helm.Client
- HelmLogFile *os.File
- HelmLogger *log.Logger
-
- // configuration for framework's client
- Options Options
-
- SkipNamespaceCreation bool // Whether to skip creating a namespace
- Namespace *corev1.Namespace // Every test has at least one namespace unless creation is skipped
- NamespaceDeletionTimeout time.Duration
-
- namespacesToDelete []*corev1.Namespace // Some tests have more than one.
-}
-
-// NewFramework creates a test framework.
-func NewFramework(baseName string) *Framework {
- f := &Framework{
- BaseName: baseName,
- }
-
- // The order is important here: if the extension calls ginkgo.BeforeEach
- // itself, then it can be sure that f.BeforeEach already ran when its
- // own callback gets invoked.
- ginkgo.BeforeEach(f.BeforeEach)
-
- return f
-}
-
-// ClientConfig an externally accessible method for reading the kube client config.
-func (f *Framework) ClientConfig() *rest.Config {
- ret := rest.CopyConfig(f.clientConfig)
- // json is the least common denominator
- ret.ContentType = runtime.ContentTypeJSON
- ret.AcceptContentTypes = runtime.ContentTypeJSON
- return ret
-}
-
-// BeforeEach gets a client and makes a namespace.
-func (f *Framework) BeforeEach(ctx context.Context) {
- // DeferCleanup, in contrast to AfterEach, triggers execution in
- // first-in-last-out order. This ensures that the framework instance
- // remains valid as long as possible.
- //
- // In addition, AfterEach will not be called if a test never gets here.
- ginkgo.DeferCleanup(f.AfterEach)
-
- ginkgo.By("Creating a kubernetes client")
- config, err := LoadConfig()
- gomega.Expect(err).NotTo(gomega.HaveOccurred())
-
- config.QPS = f.Options.ClientQPS
- config.Burst = f.Options.ClientBurst
- if f.Options.GroupVersion != nil {
- config.GroupVersion = f.Options.GroupVersion
- }
- f.clientConfig = rest.CopyConfig(config)
- f.ClientSet, err = clientset.NewForConfig(config)
- gomega.Expect(err).NotTo(gomega.HaveOccurred())
-
- // Create an API extensions client
- f.ApiExtClient, err = apiextensionsclientset.NewForConfig(config)
- gomega.Expect(err).NotTo(gomega.HaveOccurred())
-
- if !f.SkipNamespaceCreation {
- ginkgo.By(fmt.Sprintf("Building a namespace with basename %s", f.BaseName))
- namespace, err := f.CreateNamespace(ctx, f.BaseName, map[string]string{
- "e2e-framework": f.BaseName,
- })
- gomega.Expect(err).NotTo(gomega.HaveOccurred())
-
- f.Namespace = namespace
-
- f.UniqueName = f.Namespace.GetName()
- } else {
- // not guaranteed to be unique, but very likely
- f.UniqueName = fmt.Sprintf("%s-%08x", f.BaseName, rand.Int31())
- }
-
- // Create a Helm client
- ginkgo.By("Creating a Helm client")
-
- err = os.MkdirAll(filepath.Dir(TestContext.HelmLogFile), 0755)
- gomega.Expect(err).To(gomega.BeNil())
-
- f.HelmLogFile, err = os.OpenFile(TestContext.HelmLogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
- gomega.Expect(err).To(gomega.BeNil())
-
- f.HelmLogger = log.New(f.HelmLogFile, fmt.Sprintf("%s\t", f.UniqueName), log.Ldate|log.Ltime)
- helmRestConf := &helm.RestConfClientOptions{
- Options: &helm.Options{
- Namespace: f.Namespace.Name,
- RepositoryCache: "/tmp/.helmcache",
- RepositoryConfig: "/tmp/.helmrepo",
- Debug: true,
- DebugLog: f.HelmLogger.Printf,
- },
- RestConfig: config,
- }
-
- f.HelmClient, err = helm.NewClientFromRestConf(helmRestConf)
- gomega.Expect(err).NotTo(gomega.HaveOccurred())
-}
-
-// AfterEach deletes the namespace, after reading its events.
-func (f *Framework) AfterEach(ctx context.Context) {
- // This should not happen. Given ClientSet is a public field a test must have updated it!
- // Error out early before any API calls during cleanup.
- gomega.Expect(f.ClientSet).NotTo(gomega.BeNil())
-
- // DeleteNamespace at the very end in defer, to avoid any
- // expectation failures preventing deleting the namespace.
- defer func() {
- var nsDeletionErrors error
- // Whether to delete namespace is determined by 3 factors: delete-namespace flag, delete-namespace-on-failure flag and the test result
- // if delete-namespace set to false, namespace will always be preserved.
- // if delete-namespace is true and delete-namespace-on-failure is false, namespace will be preserved if test failed.
- if TestContext.DeleteNamespace && (TestContext.DeleteNamespaceOnFailure || !ginkgo.CurrentSpecReport().Failed()) {
- for _, ns := range f.namespacesToDelete {
- ginkgo.By(fmt.Sprintf("[Cleanup]\tDeleting testing namespace %q.", ns.Name))
- if err := f.ClientSet.CoreV1().Namespaces().Delete(ctx, ns.Name, metav1.DeleteOptions{}); err != nil {
- if !apierrors.IsNotFound(err) {
- nsDeletionErrors = errors.Join(nsDeletionErrors, fmt.Errorf("error deleting %v: %w", ns.Name, err))
- }
- }
- // remove the namespace from the list of namespaces to delete
- // so that it is not deleted again in the defer block
- f.namespacesToDelete = f.namespacesToDelete[1:]
- }
- }
-
- // Unsetting this is relevant for a following test that uses
- // the same instance because it might not reach f.BeforeEach
- // when some other BeforeEach skips the test first.
- f.Namespace = nil
- f.clientConfig = nil
- f.ClientSet = nil
-
- // if we had errors deleting, report them now.
- gomega.Expect(nsDeletionErrors).NotTo(gomega.HaveOccurred())
- }()
-
- // Close helm log file
- err := f.HelmLogFile.Close()
- gomega.Expect(err).To(gomega.BeNil())
-}
-
-// CreateNamespace creates a namespace for e2e testing.
-func (f *Framework) CreateNamespace(ctx context.Context, baseName string, labels map[string]string) (*corev1.Namespace, error) {
- createTestingNS := TestContext.CreateTestingNS
- if createTestingNS == nil {
- createTestingNS = CreateTestingNS
- }
-
- if labels == nil {
- labels = make(map[string]string)
- } else {
- labelsCopy := make(map[string]string)
- for k, v := range labels {
- labelsCopy[k] = v
- }
- labels = labelsCopy
- }
-
- ns, err := createTestingNS(ctx, baseName, f.ClientSet, labels)
-
- // check ns instead of err to see if it's nil as we may
- // fail to create serviceAccount in it.
- f.AddNamespacesToDelete(ns)
-
- return ns, err
-}
-
-// DeleteNamespace can be used to delete a namespace
-func (f *Framework) DeleteNamespace(ctx context.Context, name string) {
- defer func() {
- err := f.ClientSet.CoreV1().Namespaces().Delete(ctx, name, metav1.DeleteOptions{})
- if err != nil && !apierrors.IsNotFound(err) {
- gomega.Expect(err).NotTo(gomega.HaveOccurred())
- }
- err = WaitForNamespacesDeleted(ctx, f.ClientSet, []string{name}, DefaultNamespaceDeletionTimeout)
- gomega.Expect(err).NotTo(gomega.HaveOccurred())
- }()
-}
-
-// AddNamespacesToDelete adds one or more namespaces to be deleted when the test
-// completes.
-func (f *Framework) AddNamespacesToDelete(namespaces ...*corev1.Namespace) {
- for _, ns := range namespaces {
- if ns == nil {
- continue
- }
- f.namespacesToDelete = append(f.namespacesToDelete, ns)
-
- }
-}
diff --git a/vendor/github.com/NVIDIA/k8s-test-infra/pkg/framework/test_context.go b/vendor/github.com/NVIDIA/k8s-test-infra/pkg/framework/test_context.go
deleted file mode 100644
index 739b9aa6..00000000
--- a/vendor/github.com/NVIDIA/k8s-test-infra/pkg/framework/test_context.go
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
- *
- * 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 framework
-
-import (
- "context"
- "flag"
- "os"
-
- corev1 "k8s.io/api/core/v1"
- clientset "k8s.io/client-go/kubernetes"
- "k8s.io/client-go/tools/clientcmd"
-)
-
-// CreateTestingNSFn is a func that is responsible for creating namespace used for executing e2e tests.
-type CreateTestingNSFn func(ctx context.Context, baseName string, c clientset.Interface, labels map[string]string) (*corev1.Namespace, error)
-
-// TestContextType contains test settings and global state
-type TestContextType struct {
- KubeConfig string
- KubeContext string
- DeleteNamespace bool
- DeleteNamespaceOnFailure bool
-
- HelmLogFile string
-
- // CreateTestingNS is responsible for creating namespace used for executing e2e tests.
- // It accepts namespace base name, which will be prepended with e2e prefix, kube client
- // and labels to be applied to a namespace.
- CreateTestingNS CreateTestingNSFn
-}
-
-// TestContext should be used by all tests to access common context data.
-var TestContext = TestContextType{}
-
-// RegisterClusterFlags registers flags specific to the cluster e2e test suite.
-func RegisterClusterFlags(flags *flag.FlagSet) {
- flags.BoolVar(&TestContext.DeleteNamespace, "delete-namespace", true, "If true tests will delete namespace after completion. It is only designed to make debugging easier, DO NOT turn it off by default.")
- flags.BoolVar(&TestContext.DeleteNamespaceOnFailure, "delete-namespace-on-failure", true, "If true, framework will delete test namespace on failure. Used only during test debugging.")
- flags.StringVar(&TestContext.KubeConfig, clientcmd.RecommendedConfigPathFlag, os.Getenv(clientcmd.RecommendedConfigPathEnvVar), "Path to kubeconfig containing embedded authinfo.")
- flags.StringVar(&TestContext.KubeContext, clientcmd.FlagContext, "", "kubeconfig context to use/override. If unset, will use value from 'current-context'")
- flags.StringVar(&TestContext.HelmLogFile, "helm-log-file", "e2e-helm", "Path to the file where helm logs will be written.")
-}
diff --git a/vendor/github.com/NVIDIA/k8s-test-infra/pkg/framework/util.go b/vendor/github.com/NVIDIA/k8s-test-infra/pkg/framework/util.go
deleted file mode 100644
index 78e06fd6..00000000
--- a/vendor/github.com/NVIDIA/k8s-test-infra/pkg/framework/util.go
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
- *
- * 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 framework
-
-import (
- "context"
- "fmt"
- "math/rand"
- "strconv"
- "strings"
- "time"
-
- "github.com/onsi/ginkgo/v2"
- corev1 "k8s.io/api/core/v1"
- apierrors "k8s.io/apimachinery/pkg/api/errors"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/util/uuid"
- "k8s.io/apimachinery/pkg/util/wait"
- clientset "k8s.io/client-go/kubernetes"
- restclient "k8s.io/client-go/rest"
- "k8s.io/client-go/tools/clientcmd"
- clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
-)
-
-const (
- // PollInterval is how often to Poll pods, nodes and claims.
- PollInterval = 2 * time.Second
-)
-
-// RunID is a unique identifier of the e2e run.
-// Beware that this ID is not the same for all tests in the e2e run, because each Ginkgo node creates it separately.
-var RunID = uuid.NewUUID()
-
-// RandomSuffix provides a random sequence to append to pods,services,rcs.
-func RandomSuffix() string {
- return strconv.Itoa(rand.Intn(10000))
-}
-
-// LoadConfig returns a config for a rest client with the UserAgent set to include the current test name.
-func LoadConfig() (config *restclient.Config, err error) {
- defer func() {
- if err == nil && config != nil {
- testDesc := ginkgo.CurrentSpecReport()
- if len(testDesc.ContainerHierarchyTexts) > 0 {
- testName := strings.Join(testDesc.ContainerHierarchyTexts, " ")
- if len(testDesc.LeafNodeText) > 0 {
- testName = testName + " " + testDesc.LeafNodeText
- }
- config.UserAgent = fmt.Sprintf("%s -- %s", restclient.DefaultKubernetesUserAgent(), testName)
- }
- }
- }()
-
- c, err := restclientConfig(TestContext.KubeContext)
- if err != nil {
- if TestContext.KubeConfig == "" {
- return restclient.InClusterConfig()
- }
- return nil, err
- }
-
- return clientcmd.NewDefaultClientConfig(*c, &clientcmd.ConfigOverrides{}).ClientConfig()
-}
-
-// restclientConfig returns a config holds the information needed to build connection to kubernetes clusters.
-func restclientConfig(kubeContext string) (*clientcmdapi.Config, error) {
- if TestContext.KubeConfig == "" {
- return nil, fmt.Errorf("KubeConfig must be specified to load client config")
- }
- c, err := clientcmd.LoadFromFile(TestContext.KubeConfig)
- if err != nil {
- return nil, fmt.Errorf("error loading KubeConfig: %v", err.Error())
- }
- if kubeContext != "" {
- c.CurrentContext = kubeContext
- }
- return c, nil
-}
-
-// CreateTestingNS should be used by every test, note that we append a common prefix to the provided test name.
-// Please see NewFramework instead of using this directly.
-func CreateTestingNS(ctx context.Context, baseName string, c clientset.Interface, labels map[string]string) (*corev1.Namespace, error) {
- if labels == nil {
- labels = map[string]string{}
- }
- labels["e2e-run"] = string(RunID)
-
- // We don't use ObjectMeta.GenerateName feature, as in case of API call
- // failure we don't know whether the namespace was created and what is its
- // name.
- name := fmt.Sprintf("%v-%v", baseName, RandomSuffix())
-
- namespaceObj := &corev1.Namespace{
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: "",
- Labels: labels,
- },
- Status: corev1.NamespaceStatus{},
- }
- // Be robust about making the namespace creation call.
- var got *corev1.Namespace
- if err := wait.PollUntilContextTimeout(ctx, PollInterval, 30*time.Second, true, func(ctx context.Context) (bool, error) {
- var err error
- got, err = c.CoreV1().Namespaces().Create(ctx, namespaceObj, metav1.CreateOptions{})
- if err != nil {
- if apierrors.IsAlreadyExists(err) {
- // regenerate on conflict
- namespaceObj.Name = fmt.Sprintf("%v-%v", baseName, RandomSuffix())
- }
- return false, nil
- }
- return true, nil
- }); err != nil {
- return nil, err
- }
-
- return got, nil
-}
-
-// WaitForNamespacesDeleted waits for the namespaces to be deleted.
-func WaitForNamespacesDeleted(ctx context.Context, c clientset.Interface, namespaces []string, timeout time.Duration) error {
- ginkgo.By(fmt.Sprintf("Waiting for namespaces %+v to vanish", namespaces))
- nsMap := map[string]bool{}
- for _, ns := range namespaces {
- nsMap[ns] = true
- }
- // Now POLL until all namespaces have been eradicated.
- return wait.PollUntilContextTimeout(ctx, 2*time.Second, timeout, true,
- func(ctx context.Context) (bool, error) {
- nsList, err := c.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
- if err != nil {
- return false, err
- }
- for _, item := range nsList.Items {
- if _, ok := nsMap[item.Name]; ok {
- return false, nil
- }
- }
- return true, nil
- })
-}
diff --git a/vendor/github.com/ProtonMail/go-crypto/AUTHORS b/vendor/github.com/ProtonMail/go-crypto/AUTHORS
new file mode 100644
index 00000000..2b00ddba
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at https://tip.golang.org/AUTHORS.
diff --git a/vendor/github.com/ProtonMail/go-crypto/CONTRIBUTORS b/vendor/github.com/ProtonMail/go-crypto/CONTRIBUTORS
new file mode 100644
index 00000000..1fbd3e97
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at https://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/github.com/ProtonMail/go-crypto/LICENSE b/vendor/github.com/ProtonMail/go-crypto/LICENSE
new file mode 100644
index 00000000..6a66aea5
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/ProtonMail/go-crypto/PATENTS b/vendor/github.com/ProtonMail/go-crypto/PATENTS
new file mode 100644
index 00000000..73309904
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go b/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go
new file mode 100644
index 00000000..c85e6bef
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go
@@ -0,0 +1,381 @@
+package bitcurves
+
+// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2011 ThePiachu. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package bitelliptic implements several Koblitz elliptic curves over prime
+// fields.
+
+// This package operates, internally, on Jacobian coordinates. For a given
+// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
+// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
+// calculation can be performed within the transform (as in ScalarMult and
+// ScalarBaseMult). But even for Add and Double, it's faster to apply and
+// reverse the transform than to operate in affine coordinates.
+
+import (
+ "crypto/elliptic"
+ "io"
+ "math/big"
+ "sync"
+)
+
+// A BitCurve represents a Koblitz Curve with a=0.
+// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
+type BitCurve struct {
+ Name string
+ P *big.Int // the order of the underlying field
+ N *big.Int // the order of the base point
+ B *big.Int // the constant of the BitCurve equation
+ Gx, Gy *big.Int // (x,y) of the base point
+ BitSize int // the size of the underlying field
+}
+
+// Params returns the parameters of the given BitCurve (see BitCurve struct)
+func (bitCurve *BitCurve) Params() (cp *elliptic.CurveParams) {
+ cp = new(elliptic.CurveParams)
+ cp.Name = bitCurve.Name
+ cp.P = bitCurve.P
+ cp.N = bitCurve.N
+ cp.Gx = bitCurve.Gx
+ cp.Gy = bitCurve.Gy
+ cp.BitSize = bitCurve.BitSize
+ return cp
+}
+
+// IsOnCurve returns true if the given (x,y) lies on the BitCurve.
+func (bitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
+ // y² = x³ + b
+ y2 := new(big.Int).Mul(y, y) //y²
+ y2.Mod(y2, bitCurve.P) //y²%P
+
+ x3 := new(big.Int).Mul(x, x) //x²
+ x3.Mul(x3, x) //x³
+
+ x3.Add(x3, bitCurve.B) //x³+B
+ x3.Mod(x3, bitCurve.P) //(x³+B)%P
+
+ return x3.Cmp(y2) == 0
+}
+
+// affineFromJacobian reverses the Jacobian transform. See the comment at the
+// top of the file.
+func (bitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
+ if z.Cmp(big.NewInt(0)) == 0 {
+ panic("bitcurve: Can't convert to affine with Jacobian Z = 0")
+ }
+ // x = YZ^2 mod P
+ zinv := new(big.Int).ModInverse(z, bitCurve.P)
+ zinvsq := new(big.Int).Mul(zinv, zinv)
+
+ xOut = new(big.Int).Mul(x, zinvsq)
+ xOut.Mod(xOut, bitCurve.P)
+ // y = YZ^3 mod P
+ zinvsq.Mul(zinvsq, zinv)
+ yOut = new(big.Int).Mul(y, zinvsq)
+ yOut.Mod(yOut, bitCurve.P)
+ return xOut, yOut
+}
+
+// Add returns the sum of (x1,y1) and (x2,y2)
+func (bitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
+ z := new(big.Int).SetInt64(1)
+ x, y, z := bitCurve.addJacobian(x1, y1, z, x2, y2, z)
+ return bitCurve.affineFromJacobian(x, y, z)
+}
+
+// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
+// (x2, y2, z2) and returns their sum, also in Jacobian form.
+func (bitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
+ // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
+ z1z1 := new(big.Int).Mul(z1, z1)
+ z1z1.Mod(z1z1, bitCurve.P)
+ z2z2 := new(big.Int).Mul(z2, z2)
+ z2z2.Mod(z2z2, bitCurve.P)
+
+ u1 := new(big.Int).Mul(x1, z2z2)
+ u1.Mod(u1, bitCurve.P)
+ u2 := new(big.Int).Mul(x2, z1z1)
+ u2.Mod(u2, bitCurve.P)
+ h := new(big.Int).Sub(u2, u1)
+ if h.Sign() == -1 {
+ h.Add(h, bitCurve.P)
+ }
+ i := new(big.Int).Lsh(h, 1)
+ i.Mul(i, i)
+ j := new(big.Int).Mul(h, i)
+
+ s1 := new(big.Int).Mul(y1, z2)
+ s1.Mul(s1, z2z2)
+ s1.Mod(s1, bitCurve.P)
+ s2 := new(big.Int).Mul(y2, z1)
+ s2.Mul(s2, z1z1)
+ s2.Mod(s2, bitCurve.P)
+ r := new(big.Int).Sub(s2, s1)
+ if r.Sign() == -1 {
+ r.Add(r, bitCurve.P)
+ }
+ r.Lsh(r, 1)
+ v := new(big.Int).Mul(u1, i)
+
+ x3 := new(big.Int).Set(r)
+ x3.Mul(x3, x3)
+ x3.Sub(x3, j)
+ x3.Sub(x3, v)
+ x3.Sub(x3, v)
+ x3.Mod(x3, bitCurve.P)
+
+ y3 := new(big.Int).Set(r)
+ v.Sub(v, x3)
+ y3.Mul(y3, v)
+ s1.Mul(s1, j)
+ s1.Lsh(s1, 1)
+ y3.Sub(y3, s1)
+ y3.Mod(y3, bitCurve.P)
+
+ z3 := new(big.Int).Add(z1, z2)
+ z3.Mul(z3, z3)
+ z3.Sub(z3, z1z1)
+ if z3.Sign() == -1 {
+ z3.Add(z3, bitCurve.P)
+ }
+ z3.Sub(z3, z2z2)
+ if z3.Sign() == -1 {
+ z3.Add(z3, bitCurve.P)
+ }
+ z3.Mul(z3, h)
+ z3.Mod(z3, bitCurve.P)
+
+ return x3, y3, z3
+}
+
+// Double returns 2*(x,y)
+func (bitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
+ z1 := new(big.Int).SetInt64(1)
+ return bitCurve.affineFromJacobian(bitCurve.doubleJacobian(x1, y1, z1))
+}
+
+// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
+// returns its double, also in Jacobian form.
+func (bitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
+ // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
+
+ a := new(big.Int).Mul(x, x) //X1²
+ b := new(big.Int).Mul(y, y) //Y1²
+ c := new(big.Int).Mul(b, b) //B²
+
+ d := new(big.Int).Add(x, b) //X1+B
+ d.Mul(d, d) //(X1+B)²
+ d.Sub(d, a) //(X1+B)²-A
+ d.Sub(d, c) //(X1+B)²-A-C
+ d.Mul(d, big.NewInt(2)) //2*((X1+B)²-A-C)
+
+ e := new(big.Int).Mul(big.NewInt(3), a) //3*A
+ f := new(big.Int).Mul(e, e) //E²
+
+ x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D
+ x3.Sub(f, x3) //F-2*D
+ x3.Mod(x3, bitCurve.P)
+
+ y3 := new(big.Int).Sub(d, x3) //D-X3
+ y3.Mul(e, y3) //E*(D-X3)
+ y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C
+ y3.Mod(y3, bitCurve.P)
+
+ z3 := new(big.Int).Mul(y, z) //Y1*Z1
+ z3.Mul(big.NewInt(2), z3) //3*Y1*Z1
+ z3.Mod(z3, bitCurve.P)
+
+ return x3, y3, z3
+}
+
+// TODO: double check if it is okay
+// ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
+func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
+ // We have a slight problem in that the identity of the group (the
+ // point at infinity) cannot be represented in (x, y) form on a finite
+ // machine. Thus the standard add/double algorithm has to be tweaked
+ // slightly: our initial state is not the identity, but x, and we
+ // ignore the first true bit in |k|. If we don't find any true bits in
+ // |k|, then we return nil, nil, because we cannot return the identity
+ // element.
+
+ Bz := new(big.Int).SetInt64(1)
+ x := Bx
+ y := By
+ z := Bz
+
+ seenFirstTrue := false
+ for _, byte := range k {
+ for bitNum := 0; bitNum < 8; bitNum++ {
+ if seenFirstTrue {
+ x, y, z = bitCurve.doubleJacobian(x, y, z)
+ }
+ if byte&0x80 == 0x80 {
+ if !seenFirstTrue {
+ seenFirstTrue = true
+ } else {
+ x, y, z = bitCurve.addJacobian(Bx, By, Bz, x, y, z)
+ }
+ }
+ byte <<= 1
+ }
+ }
+
+ if !seenFirstTrue {
+ return nil, nil
+ }
+
+ return bitCurve.affineFromJacobian(x, y, z)
+}
+
+// ScalarBaseMult returns k*G, where G is the base point of the group and k is
+// an integer in big-endian form.
+func (bitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
+ return bitCurve.ScalarMult(bitCurve.Gx, bitCurve.Gy, k)
+}
+
+var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
+
+// TODO: double check if it is okay
+// GenerateKey returns a public/private key pair. The private key is generated
+// using the given reader, which must return random data.
+func (bitCurve *BitCurve) GenerateKey(rand io.Reader) (priv []byte, x, y *big.Int, err error) {
+ byteLen := (bitCurve.BitSize + 7) >> 3
+ priv = make([]byte, byteLen)
+
+ for x == nil {
+ _, err = io.ReadFull(rand, priv)
+ if err != nil {
+ return
+ }
+ // We have to mask off any excess bits in the case that the size of the
+ // underlying field is not a whole number of bytes.
+ priv[0] &= mask[bitCurve.BitSize%8]
+ // This is because, in tests, rand will return all zeros and we don't
+ // want to get the point at infinity and loop forever.
+ priv[1] ^= 0x42
+ x, y = bitCurve.ScalarBaseMult(priv)
+ }
+ return
+}
+
+// Marshal converts a point into the form specified in section 4.3.6 of ANSI
+// X9.62.
+func (bitCurve *BitCurve) Marshal(x, y *big.Int) []byte {
+ byteLen := (bitCurve.BitSize + 7) >> 3
+
+ ret := make([]byte, 1+2*byteLen)
+ ret[0] = 4 // uncompressed point
+
+ xBytes := x.Bytes()
+ copy(ret[1+byteLen-len(xBytes):], xBytes)
+ yBytes := y.Bytes()
+ copy(ret[1+2*byteLen-len(yBytes):], yBytes)
+ return ret
+}
+
+// Unmarshal converts a point, serialised by Marshal, into an x, y pair. On
+// error, x = nil.
+func (bitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) {
+ byteLen := (bitCurve.BitSize + 7) >> 3
+ if len(data) != 1+2*byteLen {
+ return
+ }
+ if data[0] != 4 { // uncompressed form
+ return
+ }
+ x = new(big.Int).SetBytes(data[1 : 1+byteLen])
+ y = new(big.Int).SetBytes(data[1+byteLen:])
+ return
+}
+
+//curve parameters taken from:
+//http://www.secg.org/collateral/sec2_final.pdf
+
+var initonce sync.Once
+var secp160k1 *BitCurve
+var secp192k1 *BitCurve
+var secp224k1 *BitCurve
+var secp256k1 *BitCurve
+
+func initAll() {
+ initS160()
+ initS192()
+ initS224()
+ initS256()
+}
+
+func initS160() {
+ // See SEC 2 section 2.4.1
+ secp160k1 = new(BitCurve)
+ secp160k1.Name = "secp160k1"
+ secp160k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", 16)
+ secp160k1.N, _ = new(big.Int).SetString("0100000000000000000001B8FA16DFAB9ACA16B6B3", 16)
+ secp160k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000007", 16)
+ secp160k1.Gx, _ = new(big.Int).SetString("3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", 16)
+ secp160k1.Gy, _ = new(big.Int).SetString("938CF935318FDCED6BC28286531733C3F03C4FEE", 16)
+ secp160k1.BitSize = 160
+}
+
+func initS192() {
+ // See SEC 2 section 2.5.1
+ secp192k1 = new(BitCurve)
+ secp192k1.Name = "secp192k1"
+ secp192k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", 16)
+ secp192k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 16)
+ secp192k1.B, _ = new(big.Int).SetString("000000000000000000000000000000000000000000000003", 16)
+ secp192k1.Gx, _ = new(big.Int).SetString("DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", 16)
+ secp192k1.Gy, _ = new(big.Int).SetString("9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", 16)
+ secp192k1.BitSize = 192
+}
+
+func initS224() {
+ // See SEC 2 section 2.6.1
+ secp224k1 = new(BitCurve)
+ secp224k1.Name = "secp224k1"
+ secp224k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", 16)
+ secp224k1.N, _ = new(big.Int).SetString("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 16)
+ secp224k1.B, _ = new(big.Int).SetString("00000000000000000000000000000000000000000000000000000005", 16)
+ secp224k1.Gx, _ = new(big.Int).SetString("A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", 16)
+ secp224k1.Gy, _ = new(big.Int).SetString("7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", 16)
+ secp224k1.BitSize = 224
+}
+
+func initS256() {
+ // See SEC 2 section 2.7.1
+ secp256k1 = new(BitCurve)
+ secp256k1.Name = "secp256k1"
+ secp256k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
+ secp256k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
+ secp256k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16)
+ secp256k1.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16)
+ secp256k1.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16)
+ secp256k1.BitSize = 256
+}
+
+// S160 returns a BitCurve which implements secp160k1 (see SEC 2 section 2.4.1)
+func S160() *BitCurve {
+ initonce.Do(initAll)
+ return secp160k1
+}
+
+// S192 returns a BitCurve which implements secp192k1 (see SEC 2 section 2.5.1)
+func S192() *BitCurve {
+ initonce.Do(initAll)
+ return secp192k1
+}
+
+// S224 returns a BitCurve which implements secp224k1 (see SEC 2 section 2.6.1)
+func S224() *BitCurve {
+ initonce.Do(initAll)
+ return secp224k1
+}
+
+// S256 returns a BitCurve which implements bitcurves (see SEC 2 section 2.7.1)
+func S256() *BitCurve {
+ initonce.Do(initAll)
+ return secp256k1
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/brainpool/brainpool.go b/vendor/github.com/ProtonMail/go-crypto/brainpool/brainpool.go
new file mode 100644
index 00000000..cb6676de
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/brainpool/brainpool.go
@@ -0,0 +1,134 @@
+// Package brainpool implements Brainpool elliptic curves.
+// Implementation of rcurves is from github.com/ebfe/brainpool
+// Note that these curves are implemented with naive, non-constant time operations
+// and are likely not suitable for environments where timing attacks are a concern.
+package brainpool
+
+import (
+ "crypto/elliptic"
+ "math/big"
+ "sync"
+)
+
+var (
+ once sync.Once
+ p256t1, p384t1, p512t1 *elliptic.CurveParams
+ p256r1, p384r1, p512r1 *rcurve
+)
+
+func initAll() {
+ initP256t1()
+ initP384t1()
+ initP512t1()
+ initP256r1()
+ initP384r1()
+ initP512r1()
+}
+
+func initP256t1() {
+ p256t1 = &elliptic.CurveParams{Name: "brainpoolP256t1"}
+ p256t1.P, _ = new(big.Int).SetString("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16)
+ p256t1.N, _ = new(big.Int).SetString("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16)
+ p256t1.B, _ = new(big.Int).SetString("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16)
+ p256t1.Gx, _ = new(big.Int).SetString("A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4", 16)
+ p256t1.Gy, _ = new(big.Int).SetString("2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE", 16)
+ p256t1.BitSize = 256
+}
+
+func initP256r1() {
+ twisted := p256t1
+ params := &elliptic.CurveParams{
+ Name: "brainpoolP256r1",
+ P: twisted.P,
+ N: twisted.N,
+ BitSize: twisted.BitSize,
+ }
+ params.Gx, _ = new(big.Int).SetString("8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", 16)
+ params.Gy, _ = new(big.Int).SetString("547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", 16)
+ z, _ := new(big.Int).SetString("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0", 16)
+ p256r1 = newrcurve(twisted, params, z)
+}
+
+func initP384t1() {
+ p384t1 = &elliptic.CurveParams{Name: "brainpoolP384t1"}
+ p384t1.P, _ = new(big.Int).SetString("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16)
+ p384t1.N, _ = new(big.Int).SetString("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16)
+ p384t1.B, _ = new(big.Int).SetString("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16)
+ p384t1.Gx, _ = new(big.Int).SetString("18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC", 16)
+ p384t1.Gy, _ = new(big.Int).SetString("25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928", 16)
+ p384t1.BitSize = 384
+}
+
+func initP384r1() {
+ twisted := p384t1
+ params := &elliptic.CurveParams{
+ Name: "brainpoolP384r1",
+ P: twisted.P,
+ N: twisted.N,
+ BitSize: twisted.BitSize,
+ }
+ params.Gx, _ = new(big.Int).SetString("1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", 16)
+ params.Gy, _ = new(big.Int).SetString("8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", 16)
+ z, _ := new(big.Int).SetString("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C", 16)
+ p384r1 = newrcurve(twisted, params, z)
+}
+
+func initP512t1() {
+ p512t1 = &elliptic.CurveParams{Name: "brainpoolP512t1"}
+ p512t1.P, _ = new(big.Int).SetString("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16)
+ p512t1.N, _ = new(big.Int).SetString("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16)
+ p512t1.B, _ = new(big.Int).SetString("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16)
+ p512t1.Gx, _ = new(big.Int).SetString("640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA", 16)
+ p512t1.Gy, _ = new(big.Int).SetString("5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332", 16)
+ p512t1.BitSize = 512
+}
+
+func initP512r1() {
+ twisted := p512t1
+ params := &elliptic.CurveParams{
+ Name: "brainpoolP512r1",
+ P: twisted.P,
+ N: twisted.N,
+ BitSize: twisted.BitSize,
+ }
+ params.Gx, _ = new(big.Int).SetString("81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", 16)
+ params.Gy, _ = new(big.Int).SetString("7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", 16)
+ z, _ := new(big.Int).SetString("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB", 16)
+ p512r1 = newrcurve(twisted, params, z)
+}
+
+// P256t1 returns a Curve which implements Brainpool P256t1 (see RFC 5639, section 3.4)
+func P256t1() elliptic.Curve {
+ once.Do(initAll)
+ return p256t1
+}
+
+// P256r1 returns a Curve which implements Brainpool P256r1 (see RFC 5639, section 3.4)
+func P256r1() elliptic.Curve {
+ once.Do(initAll)
+ return p256r1
+}
+
+// P384t1 returns a Curve which implements Brainpool P384t1 (see RFC 5639, section 3.6)
+func P384t1() elliptic.Curve {
+ once.Do(initAll)
+ return p384t1
+}
+
+// P384r1 returns a Curve which implements Brainpool P384r1 (see RFC 5639, section 3.6)
+func P384r1() elliptic.Curve {
+ once.Do(initAll)
+ return p384r1
+}
+
+// P512t1 returns a Curve which implements Brainpool P512t1 (see RFC 5639, section 3.7)
+func P512t1() elliptic.Curve {
+ once.Do(initAll)
+ return p512t1
+}
+
+// P512r1 returns a Curve which implements Brainpool P512r1 (see RFC 5639, section 3.7)
+func P512r1() elliptic.Curve {
+ once.Do(initAll)
+ return p512r1
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go b/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go
new file mode 100644
index 00000000..7e291d6a
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go
@@ -0,0 +1,83 @@
+package brainpool
+
+import (
+ "crypto/elliptic"
+ "math/big"
+)
+
+var _ elliptic.Curve = (*rcurve)(nil)
+
+type rcurve struct {
+ twisted elliptic.Curve
+ params *elliptic.CurveParams
+ z *big.Int
+ zinv *big.Int
+ z2 *big.Int
+ z3 *big.Int
+ zinv2 *big.Int
+ zinv3 *big.Int
+}
+
+var (
+ two = big.NewInt(2)
+ three = big.NewInt(3)
+)
+
+func newrcurve(twisted elliptic.Curve, params *elliptic.CurveParams, z *big.Int) *rcurve {
+ zinv := new(big.Int).ModInverse(z, params.P)
+ return &rcurve{
+ twisted: twisted,
+ params: params,
+ z: z,
+ zinv: zinv,
+ z2: new(big.Int).Exp(z, two, params.P),
+ z3: new(big.Int).Exp(z, three, params.P),
+ zinv2: new(big.Int).Exp(zinv, two, params.P),
+ zinv3: new(big.Int).Exp(zinv, three, params.P),
+ }
+}
+
+func (curve *rcurve) toTwisted(x, y *big.Int) (*big.Int, *big.Int) {
+ var tx, ty big.Int
+ tx.Mul(x, curve.z2)
+ tx.Mod(&tx, curve.params.P)
+ ty.Mul(y, curve.z3)
+ ty.Mod(&ty, curve.params.P)
+ return &tx, &ty
+}
+
+func (curve *rcurve) fromTwisted(tx, ty *big.Int) (*big.Int, *big.Int) {
+ var x, y big.Int
+ x.Mul(tx, curve.zinv2)
+ x.Mod(&x, curve.params.P)
+ y.Mul(ty, curve.zinv3)
+ y.Mod(&y, curve.params.P)
+ return &x, &y
+}
+
+func (curve *rcurve) Params() *elliptic.CurveParams {
+ return curve.params
+}
+
+func (curve *rcurve) IsOnCurve(x, y *big.Int) bool {
+ return curve.twisted.IsOnCurve(curve.toTwisted(x, y))
+}
+
+func (curve *rcurve) Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int) {
+ tx1, ty1 := curve.toTwisted(x1, y1)
+ tx2, ty2 := curve.toTwisted(x2, y2)
+ return curve.fromTwisted(curve.twisted.Add(tx1, ty1, tx2, ty2))
+}
+
+func (curve *rcurve) Double(x1, y1 *big.Int) (x, y *big.Int) {
+ return curve.fromTwisted(curve.twisted.Double(curve.toTwisted(x1, y1)))
+}
+
+func (curve *rcurve) ScalarMult(x1, y1 *big.Int, scalar []byte) (x, y *big.Int) {
+ tx1, ty1 := curve.toTwisted(x1, y1)
+ return curve.fromTwisted(curve.twisted.ScalarMult(tx1, ty1, scalar))
+}
+
+func (curve *rcurve) ScalarBaseMult(scalar []byte) (x, y *big.Int) {
+ return curve.fromTwisted(curve.twisted.ScalarBaseMult(scalar))
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/eax/eax.go b/vendor/github.com/ProtonMail/go-crypto/eax/eax.go
new file mode 100644
index 00000000..3ae91d59
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/eax/eax.go
@@ -0,0 +1,162 @@
+// Copyright (C) 2019 ProtonTech AG
+
+// Package eax provides an implementation of the EAX
+// (encrypt-authenticate-translate) mode of operation, as described in
+// Bellare, Rogaway, and Wagner "THE EAX MODE OF OPERATION: A TWO-PASS
+// AUTHENTICATED-ENCRYPTION SCHEME OPTIMIZED FOR SIMPLICITY AND EFFICIENCY."
+// In FSE'04, volume 3017 of LNCS, 2004
+package eax
+
+import (
+ "crypto/cipher"
+ "crypto/subtle"
+ "errors"
+ "github.com/ProtonMail/go-crypto/internal/byteutil"
+)
+
+const (
+ defaultTagSize = 16
+ defaultNonceSize = 16
+)
+
+type eax struct {
+ block cipher.Block // Only AES-{128, 192, 256} supported
+ tagSize int // At least 12 bytes recommended
+ nonceSize int
+}
+
+func (e *eax) NonceSize() int {
+ return e.nonceSize
+}
+
+func (e *eax) Overhead() int {
+ return e.tagSize
+}
+
+// NewEAX returns an EAX instance with AES-{KEYLENGTH} and default nonce and
+// tag lengths. Supports {128, 192, 256}- bit key length.
+func NewEAX(block cipher.Block) (cipher.AEAD, error) {
+ return NewEAXWithNonceAndTagSize(block, defaultNonceSize, defaultTagSize)
+}
+
+// NewEAXWithNonceAndTagSize returns an EAX instance with AES-{keyLength} and
+// given nonce and tag lengths in bytes. Panics on zero nonceSize and
+// exceedingly long tags.
+//
+// It is recommended to use at least 12 bytes as tag length (see, for instance,
+// NIST SP 800-38D).
+//
+// Only to be used for compatibility with existing cryptosystems with
+// non-standard parameters. For all other cases, prefer NewEAX.
+func NewEAXWithNonceAndTagSize(
+ block cipher.Block, nonceSize, tagSize int) (cipher.AEAD, error) {
+ if nonceSize < 1 {
+ return nil, eaxError("Cannot initialize EAX with nonceSize = 0")
+ }
+ if tagSize > block.BlockSize() {
+ return nil, eaxError("Custom tag length exceeds blocksize")
+ }
+ return &eax{
+ block: block,
+ tagSize: tagSize,
+ nonceSize: nonceSize,
+ }, nil
+}
+
+func (e *eax) Seal(dst, nonce, plaintext, adata []byte) []byte {
+ if len(nonce) > e.nonceSize {
+ panic("crypto/eax: Nonce too long for this instance")
+ }
+ ret, out := byteutil.SliceForAppend(dst, len(plaintext)+e.tagSize)
+ omacNonce := e.omacT(0, nonce)
+ omacAdata := e.omacT(1, adata)
+
+ // Encrypt message using CTR mode and omacNonce as IV
+ ctr := cipher.NewCTR(e.block, omacNonce)
+ ciphertextData := out[:len(plaintext)]
+ ctr.XORKeyStream(ciphertextData, plaintext)
+
+ omacCiphertext := e.omacT(2, ciphertextData)
+
+ tag := out[len(plaintext):]
+ for i := 0; i < e.tagSize; i++ {
+ tag[i] = omacCiphertext[i] ^ omacNonce[i] ^ omacAdata[i]
+ }
+ return ret
+}
+
+func (e *eax) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) {
+ if len(nonce) > e.nonceSize {
+ panic("crypto/eax: Nonce too long for this instance")
+ }
+ if len(ciphertext) < e.tagSize {
+ return nil, eaxError("Ciphertext shorter than tag length")
+ }
+ sep := len(ciphertext) - e.tagSize
+
+ // Compute tag
+ omacNonce := e.omacT(0, nonce)
+ omacAdata := e.omacT(1, adata)
+ omacCiphertext := e.omacT(2, ciphertext[:sep])
+
+ tag := make([]byte, e.tagSize)
+ for i := 0; i < e.tagSize; i++ {
+ tag[i] = omacCiphertext[i] ^ omacNonce[i] ^ omacAdata[i]
+ }
+
+ // Compare tags
+ if subtle.ConstantTimeCompare(ciphertext[sep:], tag) != 1 {
+ return nil, eaxError("Tag authentication failed")
+ }
+
+ // Decrypt ciphertext
+ ret, out := byteutil.SliceForAppend(dst, len(ciphertext))
+ ctr := cipher.NewCTR(e.block, omacNonce)
+ ctr.XORKeyStream(out, ciphertext[:sep])
+
+ return ret[:sep], nil
+}
+
+// Tweakable OMAC - Calls OMAC_K([t]_n || plaintext)
+func (e *eax) omacT(t byte, plaintext []byte) []byte {
+ blockSize := e.block.BlockSize()
+ byteT := make([]byte, blockSize)
+ byteT[blockSize-1] = t
+ concat := append(byteT, plaintext...)
+ return e.omac(concat)
+}
+
+func (e *eax) omac(plaintext []byte) []byte {
+ blockSize := e.block.BlockSize()
+ // L ← E_K(0^n); B ← 2L; P ← 4L
+ L := make([]byte, blockSize)
+ e.block.Encrypt(L, L)
+ B := byteutil.GfnDouble(L)
+ P := byteutil.GfnDouble(B)
+
+ // CBC with IV = 0
+ cbc := cipher.NewCBCEncrypter(e.block, make([]byte, blockSize))
+ padded := e.pad(plaintext, B, P)
+ cbcCiphertext := make([]byte, len(padded))
+ cbc.CryptBlocks(cbcCiphertext, padded)
+
+ return cbcCiphertext[len(cbcCiphertext)-blockSize:]
+}
+
+func (e *eax) pad(plaintext, B, P []byte) []byte {
+ // if |M| in {n, 2n, 3n, ...}
+ blockSize := e.block.BlockSize()
+ if len(plaintext) != 0 && len(plaintext)%blockSize == 0 {
+ return byteutil.RightXor(plaintext, B)
+ }
+
+ // else return (M || 1 || 0^(n−1−(|M| % n))) xor→ P
+ ending := make([]byte, blockSize-len(plaintext)%blockSize)
+ ending[0] = 0x80
+ padded := append(plaintext, ending...)
+ return byteutil.RightXor(padded, P)
+}
+
+func eaxError(err string) error {
+ return errors.New("crypto/eax: " + err)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/eax/eax_test_vectors.go b/vendor/github.com/ProtonMail/go-crypto/eax/eax_test_vectors.go
new file mode 100644
index 00000000..ddb53d07
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/eax/eax_test_vectors.go
@@ -0,0 +1,58 @@
+package eax
+
+// Test vectors from
+// https://web.cs.ucdavis.edu/~rogaway/papers/eax.pdf
+var testVectors = []struct {
+ msg, key, nonce, header, ciphertext string
+}{
+ {"",
+ "233952DEE4D5ED5F9B9C6D6FF80FF478",
+ "62EC67F9C3A4A407FCB2A8C49031A8B3",
+ "6BFB914FD07EAE6B",
+ "E037830E8389F27B025A2D6527E79D01"},
+ {"F7FB",
+ "91945D3F4DCBEE0BF45EF52255F095A4",
+ "BECAF043B0A23D843194BA972C66DEBD",
+ "FA3BFD4806EB53FA",
+ "19DD5C4C9331049D0BDAB0277408F67967E5"},
+ {"1A47CB4933",
+ "01F74AD64077F2E704C0F60ADA3DD523",
+ "70C3DB4F0D26368400A10ED05D2BFF5E",
+ "234A3463C1264AC6",
+ "D851D5BAE03A59F238A23E39199DC9266626C40F80"},
+ {"481C9E39B1",
+ "D07CF6CBB7F313BDDE66B727AFD3C5E8",
+ "8408DFFF3C1A2B1292DC199E46B7D617",
+ "33CCE2EABFF5A79D",
+ "632A9D131AD4C168A4225D8E1FF755939974A7BEDE"},
+ {"40D0C07DA5E4",
+ "35B6D0580005BBC12B0587124557D2C2",
+ "FDB6B06676EEDC5C61D74276E1F8E816",
+ "AEB96EAEBE2970E9",
+ "071DFE16C675CB0677E536F73AFE6A14B74EE49844DD"},
+ {"4DE3B35C3FC039245BD1FB7D",
+ "BD8E6E11475E60B268784C38C62FEB22",
+ "6EAC5C93072D8E8513F750935E46DA1B",
+ "D4482D1CA78DCE0F",
+ "835BB4F15D743E350E728414ABB8644FD6CCB86947C5E10590210A4F"},
+ {"8B0A79306C9CE7ED99DAE4F87F8DD61636",
+ "7C77D6E813BED5AC98BAA417477A2E7D",
+ "1A8C98DCD73D38393B2BF1569DEEFC19",
+ "65D2017990D62528",
+ "02083E3979DA014812F59F11D52630DA30137327D10649B0AA6E1C181DB617D7F2"},
+ {"1BDA122BCE8A8DBAF1877D962B8592DD2D56",
+ "5FFF20CAFAB119CA2FC73549E20F5B0D",
+ "DDE59B97D722156D4D9AFF2BC7559826",
+ "54B9F04E6A09189A",
+ "2EC47B2C4954A489AFC7BA4897EDCDAE8CC33B60450599BD02C96382902AEF7F832A"},
+ {"6CF36720872B8513F6EAB1A8A44438D5EF11",
+ "A4A4782BCFFD3EC5E7EF6D8C34A56123",
+ "B781FCF2F75FA5A8DE97A9CA48E522EC",
+ "899A175897561D7E",
+ "0DE18FD0FDD91E7AF19F1D8EE8733938B1E8E7F6D2231618102FDB7FE55FF1991700"},
+ {"CA40D7446E545FFAED3BD12A740A659FFBBB3CEAB7",
+ "8395FCF1E95BEBD697BD010BC766AAC3",
+ "22E7ADD93CFC6393C57EC0B3C17D6B44",
+ "126735FCC320D25A",
+ "CB8920F87A6C75CFF39627B56E3ED197C552D295A7CFC46AFC253B4652B1AF3795B124AB6E"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/eax/random_vectors.go b/vendor/github.com/ProtonMail/go-crypto/eax/random_vectors.go
new file mode 100644
index 00000000..4eb19f28
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/eax/random_vectors.go
@@ -0,0 +1,131 @@
+// These vectors include key length in {128, 192, 256}, tag size 128, and
+// random nonce, header, and plaintext lengths.
+
+// This file was automatically generated.
+
+package eax
+
+var randomVectors = []struct {
+ key, nonce, header, plaintext, ciphertext string
+}{
+ {"DFDE093F36B0356E5A81F609786982E3",
+ "1D8AC604419001816905BA72B14CED7E",
+ "152A1517A998D7A24163FCDD146DE81AC347C8B97088F502093C1ABB8F6E33D9A219C34D7603A18B1F5ABE02E56661B7D7F67E81EC08C1302EF38D80A859486D450E94A4F26AD9E68EEBBC0C857A0FC5CF9E641D63D565A7E361BC8908F5A8DC8FD6",
+ "1C8EAAB71077FE18B39730A3156ADE29C5EE824C7EE86ED2A253B775603FB237116E654F6FEC588DD27F523A0E01246FE73FE348491F2A8E9ABC6CA58D663F71CDBCF4AD798BE46C42AE6EE8B599DB44A1A48D7BBBBA0F7D2750181E1C5E66967F7D57CBD30AFBDA5727",
+ "79E7E150934BBEBF7013F61C60462A14D8B15AF7A248AFB8A344EF021C1500E16666891D6E973D8BB56B71A371F12CA34660C4410C016982B20F547E3762A58B7BF4F20236CADCF559E2BE7D783B13723B2741FC7CDC8997D839E39A3DDD2BADB96743DD7049F1BDB0516A262869915B3F70498AFB7B191BF960"},
+ {"F10619EF02E5D94D7550EB84ED364A21",
+ "8DC0D4F2F745BBAE835CC5574B942D20",
+ "FE561358F2E8DF7E1024FF1AE9A8D36EBD01352214505CB99D644777A8A1F6027FA2BDBFC529A9B91136D5F2416CFC5F0F4EC3A1AFD32BDDA23CA504C5A5CB451785FABF4DFE4CD50D817491991A60615B30286361C100A95D1712F2A45F8E374461F4CA2B",
+ "D7B5A971FC219631D30EFC3664AE3127D9CF3097DAD9C24AC7905D15E8D9B25B026B31D68CAE00975CDB81EB1FD96FD5E1A12E2BB83FA25F1B1D91363457657FC03875C27F2946C5",
+ "2F336ED42D3CC38FC61660C4CD60BA4BD438B05F5965D8B7B399D2E7167F5D34F792D318F94DB15D67463AC449E13D568CC09BFCE32A35EE3EE96A041927680AE329811811E27F2D1E8E657707AF99BA96D13A478D695D59"},
+ {"429F514EFC64D98A698A9247274CFF45",
+ "976AA5EB072F912D126ACEBC954FEC38",
+ "A71D89DC5B6CEDBB7451A27C3C2CAE09126DB4C421",
+ "5632FE62AB1DC549D54D3BC3FC868ACCEDEFD9ECF5E9F8",
+ "848AE4306CA8C7F416F8707625B7F55881C0AB430353A5C967CDA2DA787F581A70E34DBEBB2385"},
+ {"398138F309085F47F8457CDF53895A63",
+ "F8A8A7F2D28E5FFF7BBC2F24353F7A36",
+ "5D633C21BA7764B8855CAB586F3746E236AD486039C83C6B56EFA9C651D38A41D6B20DAEE3418BFEA44B8BD6",
+ "A3BBAA91920AF5E10659818B1B3B300AC79BFC129C8329E75251F73A66D3AE0128EB91D5031E0A65C329DB7D1E9C0493E268",
+ "D078097267606E5FB07CFB7E2B4B718172A82C6A4CEE65D549A4DFB9838003BD2FBF64A7A66988AC1A632FD88F9E9FBB57C5A78AD2E086EACBA3DB68511D81C2970A"},
+ {"7A4151EBD3901B42CBA45DAFB2E931BA",
+ "0FC88ACEE74DD538040321C330974EB8",
+ "250464FB04733BAB934C59E6AD2D6AE8D662CBCFEFBE61E5A308D4211E58C4C25935B72C69107722E946BFCBF416796600542D76AEB73F2B25BF53BAF97BDEB36ED3A7A51C31E7F170EB897457E7C17571D1BA0A908954E9",
+ "88C41F3EBEC23FAB8A362D969CAC810FAD4F7CA6A7F7D0D44F060F92E37E1183768DD4A8C733F71C96058D362A39876D183B86C103DE",
+ "74A25B2182C51096D48A870D80F18E1CE15867778E34FCBA6BD7BFB3739FDCD42AD0F2D9F4EBA29085285C6048C15BCE5E5166F1F962D3337AA88E6062F05523029D0A7F0BF9"},
+ {"BFB147E1CD5459424F8C0271FC0E0DC5",
+ "EABCC126442BF373969EA3015988CC45",
+ "4C0880E1D71AA2C7",
+ "BE1B5EC78FBF73E7A6682B21BA7E0E5D2D1C7ABE",
+ "5660D7C1380E2F306895B1402CB2D6C37876504276B414D120F4CF92FDDDBB293A238EA0"},
+ {"595DD6F52D18BC2CA8EB4EDAA18D9FA3",
+ "0F84B5D36CF4BC3B863313AF3B4D2E97",
+ "30AE6CC5F99580F12A779D98BD379A60948020C0B6FBD5746B30BA3A15C6CD33DAF376C70A9F15B6C0EB410A93161F7958AE23",
+ "8EF3687A1642B070970B0B91462229D1D76ABC154D18211F7152AA9FF368",
+ "317C1DDB11417E5A9CC4DDE7FDFF6659A5AC4B31DE025212580A05CDAC6024D3E4AE7C2966E52B9129E9ECDBED86"},
+ {"44E6F2DC8FDC778AD007137D11410F50",
+ "270A237AD977F7187AA6C158A0BAB24F",
+ "509B0F0EB12E2AA5C5BA2DE553C07FAF4CE0C9E926531AA709A3D6224FCB783ACCF1559E10B1123EBB7D52E8AB54E6B5352A9ED0D04124BF0E9D9BACFD7E32B817B2E625F5EE94A64EDE9E470DE7FE6886C19B294F9F828209FE257A78",
+ "8B3D7815DF25618A5D0C55A601711881483878F113A12EC36CF64900549A3199555528559DC118F789788A55FAFD944E6E99A9CA3F72F238CD3F4D88223F7A745992B3FAED1848",
+ "1CC00D79F7AD82FDA71B58D286E5F34D0CC4CEF30704E771CC1E50746BDF83E182B078DB27149A42BAE619DF0F85B0B1090AD55D3B4471B0D6F6ECCD09C8F876B30081F0E7537A9624F8AAF29DA85E324122EFB4D68A56"},
+ {"BB7BC352A03044B4428D8DBB4B0701FDEC4649FD17B81452",
+ "8B4BBE26CCD9859DCD84884159D6B0A4",
+ "2212BEB0E78E0F044A86944CF33C8D5C80D9DBE1034BF3BCF73611835C7D3A52F5BD2D81B68FD681B68540A496EE5DA16FD8AC8824E60E1EC2042BE28FB0BFAD4E4B03596446BDD8C37D936D9B3D5295BE19F19CF5ACE1D33A46C952CE4DE5C12F92C1DD051E04AEED",
+ "9037234CC44FFF828FABED3A7084AF40FA7ABFF8E0C0EFB57A1CC361E18FC4FAC1AB54F3ABFE9FF77263ACE16C3A",
+ "A9391B805CCD956081E0B63D282BEA46E7025126F1C1631239C33E92AA6F92CD56E5A4C56F00FF9658E93D48AF4EF0EF81628E34AD4DB0CDAEDCD2A17EE7"},
+ {"99C0AD703196D2F60A74E6B378B838B31F82EA861F06FC4E",
+ "92745C018AA708ECFEB1667E9F3F1B01",
+ "828C69F376C0C0EC651C67749C69577D589EE39E51404D80EBF70C8660A8F5FD375473F4A7C611D59CB546A605D67446CE2AA844135FCD78BB5FBC90222A00D42920BB1D7EEDFB0C4672554F583EF23184F89063CDECBE482367B5F9AF3ACBC3AF61392BD94CBCD9B64677",
+ "A879214658FD0A5B0E09836639BF82E05EC7A5EF71D4701934BDA228435C68AC3D5CEB54997878B06A655EEACEFB1345C15867E7FE6C6423660C8B88DF128EBD6BCD85118DBAE16E9252FFB204324E5C8F38CA97759BDBF3CB0083",
+ "51FE87996F194A2585E438B023B345439EA60D1AEBED4650CDAF48A4D4EEC4FC77DC71CC4B09D3BEEF8B7B7AF716CE2B4EFFB3AC9E6323C18AC35E0AA6E2BBBC8889490EB6226C896B0D105EAB42BFE7053CCF00ED66BA94C1BA09A792AA873F0C3B26C5C5F9A936E57B25"},
+ {"7086816D00D648FB8304AA8C9E552E1B69A9955FB59B25D1",
+ "0F45CF7F0BF31CCEB85D9DA10F4D749F",
+ "93F27C60A417D9F0669E86ACC784FC8917B502DAF30A6338F11B30B94D74FEFE2F8BE1BBE2EAD10FAB7EED3C6F72B7C3ECEE1937C32ED4970A6404E139209C05",
+ "877F046601F3CBE4FB1491943FA29487E738F94B99AF206262A1D6FF856C9AA0B8D4D08A54370C98F8E88FA3DCC2B14C1F76D71B2A4C7963AEE8AF960464C5BEC8357AD00DC8",
+ "FE96906B895CE6A8E72BC72344E2C8BB3C63113D70EAFA26C299BAFE77A8A6568172EB447FB3E86648A0AF3512DEB1AAC0819F3EC553903BF28A9FB0F43411237A774BF9EE03E445D280FBB9CD12B9BAAB6EF5E52691"},
+ {"062F65A896D5BF1401BADFF70E91B458E1F9BD4888CB2E4D",
+ "5B11EA1D6008EBB41CF892FCA5B943D1",
+ "BAF4FF5C8242",
+ "A8870E091238355984EB2F7D61A865B9170F440BFF999A5993DD41A10F4440D21FF948DDA2BF663B2E03AC3324492DC5E40262ECC6A65C07672353BE23E7FB3A9D79FF6AA38D97960905A38DECC312CB6A59E5467ECF06C311CD43ADC0B543EDF34FE8BE611F176460D5627CA51F8F8D9FED71F55C",
+ "B10E127A632172CF8AA7539B140D2C9C2590E6F28C3CB892FC498FCE56A34F732FBFF32E79C7B9747D9094E8635A0C084D6F0247F9768FB5FF83493799A9BEC6C39572120C40E9292C8C947AE8573462A9108C36D9D7112E6995AE5867E6C8BB387D1C5D4BEF524F391B9FD9F0A3B4BFA079E915BCD920185CFD38D114C558928BD7D47877"},
+ {"38A8E45D6D705A11AF58AED5A1344896998EACF359F2E26A",
+ "FD82B5B31804FF47D44199B533D0CF84",
+ "DE454D4E62FE879F2050EE3E25853623D3E9AC52EEC1A1779A48CFAF5ECA0BFDE44749391866D1",
+ "B804",
+ "164BB965C05EBE0931A1A63293EDF9C38C27"},
+ {"34C33C97C6D7A0850DA94D78A58DC61EC717CD7574833068",
+ "343BE00DA9483F05C14F2E9EB8EA6AE8",
+ "78312A43EFDE3CAE34A65796FF059A3FE15304EEA5CF1D9306949FE5BF3349D4977D4EBE76C040FE894C5949E4E4D6681153DA87FB9AC5062063CA2EA183566343362370944CE0362D25FC195E124FD60E8682E665D13F2229DDA3E4B2CB1DCA",
+ "CC11BB284B1153578E4A5ED9D937B869DAF00F5B1960C23455CA9CC43F486A3BE0B66254F1041F04FDF459C8640465B6E1D2CF899A381451E8E7FCB50CF87823BE77E24B132BBEEDC72E53369B275E1D8F49ECE59F4F215230AC4FE133FC80E4F634EE80BA4682B62C86",
+ "E7F703DC31A95E3A4919FF957836CB76C063D81702AEA4703E1C2BF30831E58C4609D626EC6810E12EAA5B930F049FF9EFC22C3E3F1EBD4A1FB285CB02A1AC5AD46B425199FC0A85670A5C4E3DAA9636C8F64C199F42F18AAC8EA7457FD377F322DD7752D7D01B946C8F0A97E6113F0D50106F319AFD291AAACE"},
+ {"C6ECF7F053573E403E61B83052A343D93CBCC179D1E835BE",
+ "E280E13D7367042E3AA09A80111B6184",
+ "21486C9D7A9647",
+ "5F2639AFA6F17931853791CD8C92382BBB677FD72D0AB1A080D0E49BFAA21810E963E4FACD422E92F65CBFAD5884A60CD94740DF31AF02F95AA57DA0C4401B0ED906",
+ "5C51DB20755302070C45F52E50128A67C8B2E4ED0EACB7E29998CCE2E8C289DD5655913EC1A51CC3AABE5CDC2402B2BE7D6D4BF6945F266FBD70BA9F37109067157AE7530678B45F64475D4EBFCB5FFF46A5"},
+ {"5EC6CF7401BC57B18EF154E8C38ACCA8959E57D2F3975FF5",
+ "656B41CB3F9CF8C08BAD7EBFC80BD225",
+ "6B817C2906E2AF425861A7EF59BA5801F143EE2A139EE72697CDE168B4",
+ "2C0E1DDC9B1E5389BA63845B18B1F8A1DB062037151BCC56EF7C21C0BB4DAE366636BBA975685D7CC5A94AFBE89C769016388C56FB7B57CE750A12B718A8BDCF70E80E8659A8330EFC8F86640F21735E8C80E23FE43ABF23507CE3F964AE4EC99D",
+ "ED780CF911E6D1AA8C979B889B0B9DC1ABE261832980BDBFB576901D9EF5AB8048998E31A15BE54B3E5845A4D136AD24D0BDA1C3006168DF2F8AC06729CB0818867398150020131D8F04EDF1923758C9EABB5F735DE5EA1758D4BC0ACFCA98AFD202E9839B8720253693B874C65586C6F0"},
+ {"C92F678EB2208662F5BCF3403EC05F5961E957908A3E79421E1D25FC19054153",
+ "DA0F3A40983D92F2D4C01FED33C7A192",
+ "2B6E9D26DB406A0FAB47608657AA10EFC2B4AA5F459B29FF85AC9A40BFFE7AEB04F77E9A11FAAA116D7F6D4DA417671A9AB02C588E0EF59CB1BFB4B1CC931B63A3B3A159FCEC97A04D1E6F0C7E6A9CEF6B0ABB04758A69F1FE754DF4C2610E8C46B6CF413BDB31351D55BEDCB7B4A13A1C98E10984475E0F2F957853",
+ "F37326A80E08",
+ "83519E53E321D334F7C10B568183775C0E9AAE55F806"},
+ {"6847E0491BE57E72995D186D50094B0B3593957A5146798FCE68B287B2FB37B5",
+ "3EE1182AEBB19A02B128F28E1D5F7F99",
+ "D9F35ABB16D776CE",
+ "DB7566ED8EA95BDF837F23DB277BAFBC5E70D1105ADFD0D9EF15475051B1EF94709C67DCA9F8D5",
+ "2CDCED0C9EBD6E2A508822A685F7DCD1CDD99E7A5FCA786C234E7F7F1D27EC49751AD5DCFA30C5EDA87C43CAE3B919B6BBCFE34C8EDA59"},
+ {"82B019673642C08388D3E42075A4D5D587558C229E4AB8F660E37650C4C41A0A",
+ "336F5D681E0410FAE7B607246092C6DC",
+ "D430CBD8FE435B64214E9E9CDC5DE99D31CFCFB8C10AA0587A49DF276611",
+ "998404153AD77003E1737EDE93ED79859EE6DCCA93CB40C4363AA817ABF2DBBD46E42A14A7183B6CC01E12A577888141363D0AE011EB6E8D28C0B235",
+ "9BEF69EEB60BD3D6065707B7557F25292A8872857CFBD24F2F3C088E4450995333088DA50FD9121221C504DF1D0CD5EFE6A12666C5D5BB12282CF4C19906E9CFAB97E9BDF7F49DC17CFC384B"},
+ {"747B2E269B1859F0622C15C8BAD6A725028B1F94B8DB7326948D1E6ED663A8BC",
+ "AB91F7245DDCE3F1C747872D47BE0A8A",
+ "3B03F786EF1DDD76E1D42646DA4CD2A5165DC5383CE86D1A0B5F13F910DC278A4E451EE0192CBA178E13B3BA27FDC7840DF73D2E104B",
+ "6B803F4701114F3E5FE21718845F8416F70F626303F545BE197189E0A2BA396F37CE06D389EB2658BC7D56D67868708F6D0D32",
+ "1570DDB0BCE75AA25D1957A287A2C36B1A5F2270186DA81BA6112B7F43B0F3D1D0ED072591DCF1F1C99BBB25621FC39B896FF9BD9413A2845363A9DCD310C32CF98E57"},
+ {"02E59853FB29AEDA0FE1C5F19180AD99A12FF2F144670BB2B8BADF09AD812E0A",
+ "C691294EF67CD04D1B9242AF83DD1421",
+ "879334DAE3",
+ "1E17F46A98FEF5CBB40759D95354",
+ "FED8C3FF27DDF6313AED444A2985B36CBA268AAD6AAC563C0BA28F6DB5DB"},
+ {"F6C1FB9B4188F2288FF03BD716023198C3582CF2A037FC2F29760916C2B7FCDB",
+ "4228DA0678CA3534588859E77DFF014C",
+ "D8153CAF35539A61DD8D05B3C9B44F01E564FB9348BCD09A1C23B84195171308861058F0A3CD2A55B912A3AAEE06FF4D356C77275828F2157C2FC7C115DA39E443210CCC56BEDB0CC99BBFB227ABD5CC454F4E7F547C7378A659EEB6A7E809101A84F866503CB18D4484E1FA09B3EC7FC75EB2E35270800AA7",
+ "23B660A779AD285704B12EC1C580387A47BEC7B00D452C6570",
+ "5AA642BBABA8E49849002A2FAF31DB8FC7773EFDD656E469CEC19B3206D4174C9A263D0A05484261F6"},
+ {"8FF6086F1FADB9A3FBE245EAC52640C43B39D43F89526BB5A6EBA47710931446",
+ "943188480C99437495958B0AE4831AA9",
+ "AD5CD0BDA426F6EBA23C8EB23DC73FF9FEC173355EDBD6C9344C4C4383F211888F7CE6B29899A6801DF6B38651A7C77150941A",
+ "80CD5EA8D7F81DDF5070B934937912E8F541A5301877528EB41AB60C020968D459960ED8FB73083329841A",
+ "ABAE8EB7F36FCA2362551E72DAC890BA1BB6794797E0FC3B67426EC9372726ED4725D379EA0AC9147E48DCD0005C502863C2C5358A38817C8264B5"},
+ {"A083B54E6B1FE01B65D42FCD248F97BB477A41462BBFE6FD591006C022C8FD84",
+ "B0490F5BD68A52459556B3749ACDF40E",
+ "8892E047DA5CFBBDF7F3CFCBD1BD21C6D4C80774B1826999234394BD3E513CC7C222BB40E1E3140A152F19B3802F0D036C24A590512AD0E8",
+ "D7B15752789DC94ED0F36778A5C7BBB207BEC32BAC66E702B39966F06E381E090C6757653C3D26A81EC6AD6C364D66867A334C91BB0B8A8A4B6EACDF0783D09010AEBA2DD2062308FE99CC1F",
+ "C071280A732ADC93DF272BF1E613B2BB7D46FC6665EF2DC1671F3E211D6BDE1D6ADDD28DF3AA2E47053FC8BB8AE9271EC8BC8B2CFFA320D225B451685B6D23ACEFDD241FE284F8ADC8DB07F456985B14330BBB66E0FB212213E05B3E"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go b/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go
new file mode 100644
index 00000000..affb74a7
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go
@@ -0,0 +1,90 @@
+// Copyright (C) 2019 ProtonTech AG
+// This file contains necessary tools for the aex and ocb packages.
+//
+// These functions SHOULD NOT be used elsewhere, since they are optimized for
+// specific input nature in the EAX and OCB modes of operation.
+
+package byteutil
+
+// GfnDouble computes 2 * input in the field of 2^n elements.
+// The irreducible polynomial in the finite field for n=128 is
+// x^128 + x^7 + x^2 + x + 1 (equals 0x87)
+// Constant-time execution in order to avoid side-channel attacks
+func GfnDouble(input []byte) []byte {
+ if len(input) != 16 {
+ panic("Doubling in GFn only implemented for n = 128")
+ }
+ // If the first bit is zero, return 2L = L << 1
+ // Else return (L << 1) xor 0^120 10000111
+ shifted := ShiftBytesLeft(input)
+ shifted[15] ^= ((input[0] >> 7) * 0x87)
+ return shifted
+}
+
+// ShiftBytesLeft outputs the byte array corresponding to x << 1 in binary.
+func ShiftBytesLeft(x []byte) []byte {
+ l := len(x)
+ dst := make([]byte, l)
+ for i := 0; i < l-1; i++ {
+ dst[i] = (x[i] << 1) | (x[i+1] >> 7)
+ }
+ dst[l-1] = x[l-1] << 1
+ return dst
+}
+
+// ShiftNBytesLeft puts in dst the byte array corresponding to x << n in binary.
+func ShiftNBytesLeft(dst, x []byte, n int) {
+ // Erase first n / 8 bytes
+ copy(dst, x[n/8:])
+
+ // Shift the remaining n % 8 bits
+ bits := uint(n % 8)
+ l := len(dst)
+ for i := 0; i < l-1; i++ {
+ dst[i] = (dst[i] << bits) | (dst[i+1] >> uint(8-bits))
+ }
+ dst[l-1] = dst[l-1] << bits
+
+ // Append trailing zeroes
+ dst = append(dst, make([]byte, n/8)...)
+}
+
+// XorBytesMut assumes equal input length, replaces X with X XOR Y
+func XorBytesMut(X, Y []byte) {
+ for i := 0; i < len(X); i++ {
+ X[i] ^= Y[i]
+ }
+}
+
+// XorBytes assumes equal input length, puts X XOR Y into Z
+func XorBytes(Z, X, Y []byte) {
+ for i := 0; i < len(X); i++ {
+ Z[i] = X[i] ^ Y[i]
+ }
+}
+
+// RightXor XORs smaller input (assumed Y) at the right of the larger input (assumed X)
+func RightXor(X, Y []byte) []byte {
+ offset := len(X) - len(Y)
+ xored := make([]byte, len(X))
+ copy(xored, X)
+ for i := 0; i < len(Y); i++ {
+ xored[offset+i] ^= Y[i]
+ }
+ return xored
+}
+
+// SliceForAppend takes a slice and a requested number of bytes. It returns a
+// slice with the contents of the given slice followed by that many bytes and a
+// second slice that aliases into it and contains only the extra bytes. If the
+// original slice has sufficient capacity then no allocation is performed.
+func SliceForAppend(in []byte, n int) (head, tail []byte) {
+ if total := len(in) + n; cap(in) >= total {
+ head = in[:total]
+ } else {
+ head = make([]byte, total)
+ copy(head, in)
+ }
+ tail = head[len(in):]
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go b/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go
new file mode 100644
index 00000000..1a6f7350
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go
@@ -0,0 +1,317 @@
+// Copyright (C) 2019 ProtonTech AG
+
+// Package ocb provides an implementation of the OCB (offset codebook) mode of
+// operation, as described in RFC-7253 of the IRTF and in Rogaway, Bellare,
+// Black and Krovetz - OCB: A BLOCK-CIPHER MODE OF OPERATION FOR EFFICIENT
+// AUTHENTICATED ENCRYPTION (2003).
+// Security considerations (from RFC-7253): A private key MUST NOT be used to
+// encrypt more than 2^48 blocks. Tag length should be at least 12 bytes (a
+// brute-force forging adversary succeeds after 2^{tag length} attempts). A
+// single key SHOULD NOT be used to decrypt ciphertext with different tag
+// lengths. Nonces need not be secret, but MUST NOT be reused.
+// This package only supports underlying block ciphers with 128-bit blocks,
+// such as AES-{128, 192, 256}, but may be extended to other sizes.
+package ocb
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "crypto/subtle"
+ "errors"
+ "github.com/ProtonMail/go-crypto/internal/byteutil"
+ "math/bits"
+)
+
+type ocb struct {
+ block cipher.Block
+ tagSize int
+ nonceSize int
+ mask mask
+ // Optimized en/decrypt: For each nonce N used to en/decrypt, the 'Ktop'
+ // internal variable can be reused for en/decrypting with nonces sharing
+ // all but the last 6 bits with N. The prefix of the first nonce used to
+ // compute the new Ktop, and the Ktop value itself, are stored in
+ // reusableKtop. If using incremental nonces, this saves one block cipher
+ // call every 63 out of 64 OCB encryptions, and stores one nonce and one
+ // output of the block cipher in memory only.
+ reusableKtop reusableKtop
+}
+
+type mask struct {
+ // L_*, L_$, (L_i)_{i ∈ N}
+ lAst []byte
+ lDol []byte
+ L [][]byte
+}
+
+type reusableKtop struct {
+ noncePrefix []byte
+ Ktop []byte
+}
+
+const (
+ defaultTagSize = 16
+ defaultNonceSize = 15
+)
+
+const (
+ enc = iota
+ dec
+)
+
+func (o *ocb) NonceSize() int {
+ return o.nonceSize
+}
+
+func (o *ocb) Overhead() int {
+ return o.tagSize
+}
+
+// NewOCB returns an OCB instance with the given block cipher and default
+// tag and nonce sizes.
+func NewOCB(block cipher.Block) (cipher.AEAD, error) {
+ return NewOCBWithNonceAndTagSize(block, defaultNonceSize, defaultTagSize)
+}
+
+// NewOCBWithNonceAndTagSize returns an OCB instance with the given block
+// cipher, nonce length, and tag length. Panics on zero nonceSize and
+// exceedingly long tag size.
+//
+// It is recommended to use at least 12 bytes as tag length.
+func NewOCBWithNonceAndTagSize(
+ block cipher.Block, nonceSize, tagSize int) (cipher.AEAD, error) {
+ if block.BlockSize() != 16 {
+ return nil, ocbError("Block cipher must have 128-bit blocks")
+ }
+ if nonceSize < 1 {
+ return nil, ocbError("Incorrect nonce length")
+ }
+ if nonceSize >= block.BlockSize() {
+ return nil, ocbError("Nonce length exceeds blocksize - 1")
+ }
+ if tagSize > block.BlockSize() {
+ return nil, ocbError("Custom tag length exceeds blocksize")
+ }
+ return &ocb{
+ block: block,
+ tagSize: tagSize,
+ nonceSize: nonceSize,
+ mask: initializeMaskTable(block),
+ reusableKtop: reusableKtop{
+ noncePrefix: nil,
+ Ktop: nil,
+ },
+ }, nil
+}
+
+func (o *ocb) Seal(dst, nonce, plaintext, adata []byte) []byte {
+ if len(nonce) > o.nonceSize {
+ panic("crypto/ocb: Incorrect nonce length given to OCB")
+ }
+ ret, out := byteutil.SliceForAppend(dst, len(plaintext)+o.tagSize)
+ o.crypt(enc, out, nonce, adata, plaintext)
+ return ret
+}
+
+func (o *ocb) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) {
+ if len(nonce) > o.nonceSize {
+ panic("Nonce too long for this instance")
+ }
+ if len(ciphertext) < o.tagSize {
+ return nil, ocbError("Ciphertext shorter than tag length")
+ }
+ sep := len(ciphertext) - o.tagSize
+ ret, out := byteutil.SliceForAppend(dst, len(ciphertext))
+ ciphertextData := ciphertext[:sep]
+ tag := ciphertext[sep:]
+ o.crypt(dec, out, nonce, adata, ciphertextData)
+ if subtle.ConstantTimeCompare(ret[sep:], tag) == 1 {
+ ret = ret[:sep]
+ return ret, nil
+ }
+ for i := range out {
+ out[i] = 0
+ }
+ return nil, ocbError("Tag authentication failed")
+}
+
+// On instruction enc (resp. dec), crypt is the encrypt (resp. decrypt)
+// function. It returns the resulting plain/ciphertext with the tag appended.
+func (o *ocb) crypt(instruction int, Y, nonce, adata, X []byte) []byte {
+ //
+ // Consider X as a sequence of 128-bit blocks
+ //
+ // Note: For encryption (resp. decryption), X is the plaintext (resp., the
+ // ciphertext without the tag).
+ blockSize := o.block.BlockSize()
+
+ //
+ // Nonce-dependent and per-encryption variables
+ //
+ // Zero out the last 6 bits of the nonce into truncatedNonce to see if Ktop
+ // is already computed.
+ truncatedNonce := make([]byte, len(nonce))
+ copy(truncatedNonce, nonce)
+ truncatedNonce[len(truncatedNonce)-1] &= 192
+ Ktop := make([]byte, blockSize)
+ if bytes.Equal(truncatedNonce, o.reusableKtop.noncePrefix) {
+ Ktop = o.reusableKtop.Ktop
+ } else {
+ // Nonce = num2str(TAGLEN mod 128, 7) || zeros(120 - bitlen(N)) || 1 || N
+ paddedNonce := append(make([]byte, blockSize-1-len(nonce)), 1)
+ paddedNonce = append(paddedNonce, truncatedNonce...)
+ paddedNonce[0] |= byte(((8 * o.tagSize) % (8 * blockSize)) << 1)
+ // Last 6 bits of paddedNonce are already zero. Encrypt into Ktop
+ paddedNonce[blockSize-1] &= 192
+ Ktop = paddedNonce
+ o.block.Encrypt(Ktop, Ktop)
+ o.reusableKtop.noncePrefix = truncatedNonce
+ o.reusableKtop.Ktop = Ktop
+ }
+
+ // Stretch = Ktop || ((lower half of Ktop) XOR (lower half of Ktop << 8))
+ xorHalves := make([]byte, blockSize/2)
+ byteutil.XorBytes(xorHalves, Ktop[:blockSize/2], Ktop[1:1+blockSize/2])
+ stretch := append(Ktop, xorHalves...)
+ bottom := int(nonce[len(nonce)-1] & 63)
+ offset := make([]byte, len(stretch))
+ byteutil.ShiftNBytesLeft(offset, stretch, bottom)
+ offset = offset[:blockSize]
+
+ //
+ // Process any whole blocks
+ //
+ // Note: For encryption Y is ciphertext || tag, for decryption Y is
+ // plaintext || tag.
+ checksum := make([]byte, blockSize)
+ m := len(X) / blockSize
+ for i := 0; i < m; i++ {
+ index := bits.TrailingZeros(uint(i + 1))
+ if len(o.mask.L)-1 < index {
+ o.mask.extendTable(index)
+ }
+ byteutil.XorBytesMut(offset, o.mask.L[bits.TrailingZeros(uint(i+1))])
+ blockX := X[i*blockSize : (i+1)*blockSize]
+ blockY := Y[i*blockSize : (i+1)*blockSize]
+ byteutil.XorBytes(blockY, blockX, offset)
+ switch instruction {
+ case enc:
+ o.block.Encrypt(blockY, blockY)
+ byteutil.XorBytesMut(blockY, offset)
+ byteutil.XorBytesMut(checksum, blockX)
+ case dec:
+ o.block.Decrypt(blockY, blockY)
+ byteutil.XorBytesMut(blockY, offset)
+ byteutil.XorBytesMut(checksum, blockY)
+ }
+ }
+ //
+ // Process any final partial block and compute raw tag
+ //
+ tag := make([]byte, blockSize)
+ if len(X)%blockSize != 0 {
+ byteutil.XorBytesMut(offset, o.mask.lAst)
+ pad := make([]byte, blockSize)
+ o.block.Encrypt(pad, offset)
+ chunkX := X[blockSize*m:]
+ chunkY := Y[blockSize*m : len(X)]
+ byteutil.XorBytes(chunkY, chunkX, pad[:len(chunkX)])
+ // P_* || bit(1) || zeroes(127) - len(P_*)
+ switch instruction {
+ case enc:
+ paddedY := append(chunkX, byte(128))
+ paddedY = append(paddedY, make([]byte, blockSize-len(chunkX)-1)...)
+ byteutil.XorBytesMut(checksum, paddedY)
+ case dec:
+ paddedX := append(chunkY, byte(128))
+ paddedX = append(paddedX, make([]byte, blockSize-len(chunkY)-1)...)
+ byteutil.XorBytesMut(checksum, paddedX)
+ }
+ byteutil.XorBytes(tag, checksum, offset)
+ byteutil.XorBytesMut(tag, o.mask.lDol)
+ o.block.Encrypt(tag, tag)
+ byteutil.XorBytesMut(tag, o.hash(adata))
+ copy(Y[blockSize*m+len(chunkY):], tag[:o.tagSize])
+ } else {
+ byteutil.XorBytes(tag, checksum, offset)
+ byteutil.XorBytesMut(tag, o.mask.lDol)
+ o.block.Encrypt(tag, tag)
+ byteutil.XorBytesMut(tag, o.hash(adata))
+ copy(Y[blockSize*m:], tag[:o.tagSize])
+ }
+ return Y
+}
+
+// This hash function is used to compute the tag. Per design, on empty input it
+// returns a slice of zeros, of the same length as the underlying block cipher
+// block size.
+func (o *ocb) hash(adata []byte) []byte {
+ //
+ // Consider A as a sequence of 128-bit blocks
+ //
+ A := make([]byte, len(adata))
+ copy(A, adata)
+ blockSize := o.block.BlockSize()
+
+ //
+ // Process any whole blocks
+ //
+ sum := make([]byte, blockSize)
+ offset := make([]byte, blockSize)
+ m := len(A) / blockSize
+ for i := 0; i < m; i++ {
+ chunk := A[blockSize*i : blockSize*(i+1)]
+ index := bits.TrailingZeros(uint(i + 1))
+ // If the mask table is too short
+ if len(o.mask.L)-1 < index {
+ o.mask.extendTable(index)
+ }
+ byteutil.XorBytesMut(offset, o.mask.L[index])
+ byteutil.XorBytesMut(chunk, offset)
+ o.block.Encrypt(chunk, chunk)
+ byteutil.XorBytesMut(sum, chunk)
+ }
+
+ //
+ // Process any final partial block; compute final hash value
+ //
+ if len(A)%blockSize != 0 {
+ byteutil.XorBytesMut(offset, o.mask.lAst)
+ // Pad block with 1 || 0 ^ 127 - bitlength(a)
+ ending := make([]byte, blockSize-len(A)%blockSize)
+ ending[0] = 0x80
+ encrypted := append(A[blockSize*m:], ending...)
+ byteutil.XorBytesMut(encrypted, offset)
+ o.block.Encrypt(encrypted, encrypted)
+ byteutil.XorBytesMut(sum, encrypted)
+ }
+ return sum
+}
+
+func initializeMaskTable(block cipher.Block) mask {
+ //
+ // Key-dependent variables
+ //
+ lAst := make([]byte, block.BlockSize())
+ block.Encrypt(lAst, lAst)
+ lDol := byteutil.GfnDouble(lAst)
+ L := make([][]byte, 1)
+ L[0] = byteutil.GfnDouble(lDol)
+
+ return mask{
+ lAst: lAst,
+ lDol: lDol,
+ L: L,
+ }
+}
+
+// Extends the L array of mask m up to L[limit], with L[i] = GfnDouble(L[i-1])
+func (m *mask) extendTable(limit int) {
+ for i := len(m.L); i <= limit; i++ {
+ m.L = append(m.L, byteutil.GfnDouble(m.L[i-1]))
+ }
+}
+
+func ocbError(err string) error {
+ return errors.New("crypto/ocb: " + err)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/random_vectors.go b/vendor/github.com/ProtonMail/go-crypto/ocb/random_vectors.go
new file mode 100644
index 00000000..0efaf344
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/ocb/random_vectors.go
@@ -0,0 +1,136 @@
+// In the test vectors provided by RFC 7253, the "bottom"
+// internal variable, which defines "offset" for the first time, does not
+// exceed 15. However, it can attain values up to 63.
+
+// These vectors include key length in {128, 192, 256}, tag size 128, and
+// random nonce, header, and plaintext lengths.
+
+// This file was automatically generated.
+
+package ocb
+
+var randomVectors = []struct {
+ key, nonce, header, plaintext, ciphertext string
+}{
+
+ {"9438C5D599308EAF13F800D2D31EA7F0",
+ "C38EE4801BEBFFA1CD8635BE",
+ "0E507B7DADD8A98CDFE272D3CB6B3E8332B56AE583FB049C0874D4200BED16BD1A044182434E9DA0E841F182DFD5B3016B34641CED0784F1745F63AB3D0DA22D3351C9EF9A658B8081E24498EBF61FCE40DA6D8E184536",
+ "962D227786FB8913A8BAD5DC3250",
+ "EEDEF5FFA5986D1E3BF86DDD33EF9ADC79DCA06E215FA772CCBA814F63AD"},
+ {"BA7DE631C7D6712167C6724F5B9A2B1D",
+ "35263EBDA05765DC0E71F1F5",
+ "0103257B4224507C0242FEFE821EA7FA42E0A82863E5F8B68F7D881B4B44FA428A2B6B21D2F591260802D8AB6D83",
+ "9D6D1FC93AE8A64E7889B7B2E3521EFA9B920A8DDB692E6F833DDC4A38AFA535E5E2A3ED82CB7E26404AB86C54D01C4668F28398C2DF33D5D561CBA1C8DCFA7A912F5048E545B59483C0E3221F54B14DAA2E4EB657B3BEF9554F34CAD69B2724AE962D3D8A",
+ "E93852D1985C5E775655E937FA79CE5BF28A585F2AF53A5018853B9634BE3C84499AC0081918FDCE0624494D60E25F76ACD6853AC7576E3C350F332249BFCABD4E73CEABC36BE4EDDA40914E598AE74174A0D7442149B26990899491BDDFE8FC54D6C18E83AE9E9A6FFBF5D376565633862EEAD88D"},
+ {"2E74B25289F6FD3E578C24866E9C72A5",
+ "FD912F15025AF8414642BA1D1D",
+ "FB5FB8C26F365EEDAB5FE260C6E3CCD27806729C8335F146063A7F9EA93290E56CF84576EB446350D22AD730547C267B1F0BBB97EB34E1E2C41A",
+ "6C092EBF78F76EE8C1C6E592277D9545BA16EDB67BC7D8480B9827702DC2F8A129E2B08A2CE710CA7E1DA45CE162BB6CD4B512E632116E2211D3C90871EFB06B8D4B902681C7FB",
+ "6AC0A77F26531BF4F354A1737F99E49BE32ECD909A7A71AD69352906F54B08A9CE9B8CA5D724CBFFC5673437F23F630697F3B84117A1431D6FA8CC13A974FB4AD360300522E09511B99E71065D5AC4BBCB1D791E864EF4"},
+ {"E7EC507C802528F790AFF5303A017B17",
+ "4B97A7A568940A9E3CE7A99E93031E",
+ "28349BDC5A09390C480F9B8AA3EDEA3DDB8B9D64BCA322C570B8225DF0E31190DAB25A4014BA39519E02ABFB12B89AA28BBFD29E486E7FB28734258C817B63CED9912DBAFEBB93E2798AB2890DE3B0ACFCFF906AB15563EF7823CE83D27CDB251195E22BD1337BCBDE65E7C2C427321C463C2777BFE5AEAA",
+ "9455B3EA706B74",
+ "7F33BA3EA848D48A96B9530E26888F43EBD4463C9399B6"},
+ {"6C928AA3224736F28EE7378DE0090191",
+ "8936138E2E4C6A13280017A1622D",
+ "6202717F2631565BDCDC57C6584543E72A7C8BD444D0D108ED35069819633C",
+ "DA0691439E5F035F3E455269D14FE5C201C8C9B0A3FE2D3F86BCC59387C868FE65733D388360B31E3CE28B4BF6A8BE636706B536D5720DB66B47CF1C7A5AFD6F61E0EF90F1726D6B0E169F9A768B2B7AE4EE00A17F630AC905FCAAA1B707FFF25B3A1AAE83B504837C64A5639B2A34002B300EC035C9B43654DA55",
+ "B8804D182AB0F0EEB464FA7BD1329AD6154F982013F3765FEDFE09E26DAC078C9C1439BFC1159D6C02A25E3FF83EF852570117B315852AD5EE20E0FA3AA0A626B0E43BC0CEA38B44579DD36803455FB46989B90E6D229F513FD727AF8372517E9488384C515D6067704119C931299A0982EDDFB9C2E86A90C450C077EB222511EC9CCABC9FCFDB19F70088"},
+ {"ECEA315CA4B3F425B0C9957A17805EA4",
+ "664CDAE18403F4F9BA13015A44FC",
+ "642AFB090D6C6DB46783F08B01A3EF2A8FEB5736B531EAC226E7888FCC8505F396818F83105065FACB3267485B9E5E4A0261F621041C08FCCB2A809A49AB5252A91D0971BCC620B9D614BD77E57A0EED2FA5",
+ "6852C31F8083E20E364CEA21BB7854D67CEE812FE1C9ED2425C0932A90D3780728D1BB",
+ "2ECEF962A9695A463ADABB275BDA9FF8B2BA57AEC2F52EFFB700CD9271A74D2A011C24AEA946051BD6291776429B7E681BA33E"},
+ {"4EE616C4A58AAA380878F71A373461F6",
+ "91B8C9C176D9C385E9C47E52",
+ "CDA440B7F9762C572A718AC754EDEECC119E5EE0CCB9FEA4FFB22EEE75087C032EBF3DA9CDD8A28CC010B99ED45143B41A4BA50EA2A005473F89639237838867A57F23B0F0ED3BF22490E4501DAC9C658A9B9F",
+ "D6E645FA9AE410D15B8123FD757FA356A8DBE9258DDB5BE88832E615910993F497EC",
+ "B70ED7BF959FB2AAED4F36174A2A99BFB16992C8CDF369C782C4DB9C73DE78C5DB8E0615F647243B97ACDB24503BC9CADC48"},
+ {"DCD475773136C830D5E3D0C5FE05B7FF",
+ "BB8E1FBB483BE7616A922C4A",
+ "36FEF2E1CB29E76A6EA663FC3AF66ECD7404F466382F7B040AABED62293302B56E8783EF7EBC21B4A16C3E78A7483A0A403F253A2CDC5BBF79DC3DAE6C73F39A961D8FBBE8D41B",
+ "441E886EA38322B2437ECA7DEB5282518865A66780A454E510878E61BFEC3106A3CD93D2A02052E6F9E1832F9791053E3B76BF4C07EFDD6D4106E3027FABB752E60C1AA425416A87D53938163817A1051EBA1D1DEEB4B9B25C7E97368B52E5911A31810B0EC5AF547559B6142D9F4C4A6EF24A4CF75271BF9D48F62B",
+ "1BE4DD2F4E25A6512C2CC71D24BBB07368589A94C2714962CD0ACE5605688F06342587521E75F0ACAFFD86212FB5C34327D238DB36CF2B787794B9A4412E7CD1410EA5DDD2450C265F29CF96013CD213FD2880657694D718558964BC189B4A84AFCF47EB012935483052399DBA5B088B0A0477F20DFE0E85DCB735E21F22A439FB837DD365A93116D063E607"},
+ {"3FBA2B3D30177FFE15C1C59ED2148BB2C091F5615FBA7C07",
+ "FACF804A4BEBF998505FF9DE",
+ "8213B9263B2971A5BDA18DBD02208EE1",
+ "15B323926993B326EA19F892D704439FC478828322AF72118748284A1FD8A6D814E641F70512FD706980337379F31DC63355974738D7FEA87AD2858C0C2EBBFBE74371C21450072373C7B651B334D7C4D43260B9D7CCD3AF9EDB",
+ "6D35DC1469B26E6AAB26272A41B46916397C24C485B61162E640A062D9275BC33DDCFD3D9E1A53B6C8F51AC89B66A41D59B3574197A40D9B6DCF8A4E2A001409C8112F16B9C389E0096179DB914E05D6D11ED0005AD17E1CE105A2F0BAB8F6B1540DEB968B7A5428FF44"},
+ {"53B52B8D4D748BCDF1DDE68857832FA46227FA6E2F32EFA1",
+ "0B0EF53D4606B28D1398355F",
+ "F23882436349094AF98BCACA8218E81581A043B19009E28EFBF2DE37883E04864148CC01D240552CA8844EC1456F42034653067DA67E80F87105FD06E14FF771246C9612867BE4D215F6D761",
+ "F15030679BD4088D42CAC9BF2E9606EAD4798782FA3ED8C57EBE7F84A53236F51B25967C6489D0CD20C9EEA752F9BC",
+ "67B96E2D67C3729C96DAEAEDF821D61C17E648643A2134C5621FEC621186915AD80864BFD1EB5B238BF526A679385E012A457F583AFA78134242E9D9C1B4E4"},
+ {"0272DD80F23399F49BFC320381A5CD8225867245A49A7D41",
+ "5C83F4896D0738E1366B1836",
+ "69B0337289B19F73A12BAEEA857CCAF396C11113715D9500CCCF48BA08CFF12BC8B4BADB3084E63B85719DB5058FA7C2C11DEB096D7943CFA7CAF5",
+ "C01AD10FC8B562CD17C7BC2FAB3E26CBDFF8D7F4DEA816794BBCC12336991712972F52816AABAB244EB43B0137E2BAC1DD413CE79531E78BEF782E6B439612BB3AEF154DE3502784F287958EBC159419F9EBA27916A28D6307324129F506B1DE80C1755A929F87",
+ "FEFE52DD7159C8DD6E8EC2D3D3C0F37AB6CB471A75A071D17EC4ACDD8F3AA4D7D4F7BB559F3C09099E3D9003E5E8AA1F556B79CECDE66F85B08FA5955E6976BF2695EA076388A62D2AD5BAB7CBF1A7F3F4C8D5CDF37CDE99BD3E30B685D9E5EEE48C7C89118EF4878EB89747F28271FA2CC45F8E9E7601"},
+ {"3EEAED04A455D6E5E5AB53CFD5AFD2F2BC625C7BF4BE49A5",
+ "36B88F63ADBB5668588181D774",
+ "D367E3CB3703E762D23C6533188EF7028EFF9D935A3977150361997EC9DEAF1E4794BDE26AA8B53C124980B1362EC86FCDDFC7A90073171C1BAEE351A53234B86C66E8AB92FAE99EC6967A6D3428892D80",
+ "573454C719A9A55E04437BF7CBAAF27563CCCD92ADD5E515CD63305DFF0687E5EEF790C5DCA5C0033E9AB129505E2775438D92B38F08F3B0356BA142C6F694",
+ "E9F79A5B432D9E682C9AAA5661CFC2E49A0FCB81A431E54B42EB73DD3BED3F377FEC556ABA81624BA64A5D739AD41467460088F8D4F442180A9382CA635745473794C382FCDDC49BA4EB6D8A44AE3C"},
+ {"B695C691538F8CBD60F039D0E28894E3693CC7C36D92D79D",
+ "BC099AEB637361BAC536B57618",
+ "BFFF1A65AE38D1DC142C71637319F5F6508E2CB33C9DCB94202B359ED5A5ED8042E7F4F09231D32A7242976677E6F4C549BF65FADC99E5AF43F7A46FD95E16C2",
+ "081DF3FD85B415D803F0BE5AC58CFF0023FDDED99788296C3731D8",
+ "E50C64E3614D94FE69C47092E46ACC9957C6FEA2CCBF96BC62FBABE7424753C75F9C147C42AE26FE171531"},
+ {"C9ACBD2718F0689A1BE9802A551B6B8D9CF5614DAF5E65ED",
+ "B1B0AAF373B8B026EB80422051D8",
+ "6648C0E61AC733C76119D23FB24548D637751387AA2EAE9D80E912B7BD486CAAD9EAF4D7A5FE2B54AAD481E8EC94BB4D558000896E2010462B70C9FED1E7273080D1",
+ "189F591F6CB6D59AFEDD14C341741A8F1037DC0DF00FC57CE65C30F49E860255CEA5DC6019380CC0FE8880BC1A9E685F41C239C38F36E3F2A1388865C5C311059C0A",
+ "922A5E949B61D03BE34AB5F4E58607D4504EA14017BB363DAE3C873059EA7A1C77A746FB78981671D26C2CF6D9F24952D510044CE02A10177E9DB42D0145211DFE6E84369C5E3BC2669EAB4147B2822895F9"},
+ {"7A832BD2CF5BF4919F353CE2A8C86A5E406DA2D52BE16A72",
+ "2F2F17CECF7E5A756D10785A3CB9DB",
+ "61DA05E3788CC2D8405DBA70C7A28E5AF699863C9F72E6C6770126929F5D6FA267F005EBCF49495CB46400958A3AE80D1289D1C671",
+ "44E91121195A41AF14E8CFDBD39A4B517BE0DF1A72977ED8A3EEF8EEDA1166B2EB6DB2C4AE2E74FA0F0C74537F659BFBD141E5DDEC67E64EDA85AABD3F52C85A785B9FB3CECD70E7DF",
+ "BEDF596EA21288D2B84901E188F6EE1468B14D5161D3802DBFE00D60203A24E2AB62714BF272A45551489838C3A7FEAADC177B591836E73684867CCF4E12901DCF2064058726BBA554E84ADC5136F507E961188D4AF06943D3"},
+ {"1508E8AE9079AA15F1CEC4F776B4D11BCCB061B58AA56C18",
+ "BCA625674F41D1E3AB47672DC0C3",
+ "8B12CF84F16360F0EAD2A41BC021530FFCEC7F3579CAE658E10E2D3D81870F65AFCED0C77C6C4C6E6BA424FF23088C796BA6195ABA35094BF1829E089662E7A95FC90750AE16D0C8AFA55DAC789D7735B970B58D4BE7CEC7341DA82A0179A01929C27A59C5063215B859EA43",
+ "E525422519ECE070E82C",
+ "B47BC07C3ED1C0A43BA52C43CBACBCDBB29CAF1001E09FDF7107"},
+ {"7550C2761644E911FE9ADD119BAC07376BEA442845FEAD876D7E7AC1B713E464",
+ "36D2EC25ADD33CDEDF495205BBC923",
+ "7FCFE81A3790DE97FFC3DE160C470847EA7E841177C2F759571CBD837EA004A6CA8C6F4AEBFF2E9FD552D73EB8A30705D58D70C0B67AEEA280CBBF0A477358ACEF1E7508F2735CD9A0E4F9AC92B8C008F575D3B6278F1C18BD01227E3502E5255F3AB1893632AD00C717C588EF652A51A43209E7EE90",
+ "2B1A62F8FDFAA3C16470A21AD307C9A7D03ADE8EF72C69B06F8D738CDE578D7AEFD0D40BD9C022FB9F580DF5394C998ACCCEFC5471A3996FB8F1045A81FDC6F32D13502EA65A211390C8D882B8E0BEFD8DD8CBEF51D1597B124E9F7F",
+ "C873E02A22DB89EB0787DB6A60B99F7E4A0A085D5C4232A81ADCE2D60AA36F92DDC33F93DD8640AC0E08416B187FB382B3EC3EE85A64B0E6EE41C1366A5AD2A282F66605E87031CCBA2FA7B2DA201D975994AADE3DD1EE122AE09604AD489B84BF0C1AB7129EE16C6934850E"},
+ {"A51300285E554FDBDE7F771A9A9A80955639DD87129FAEF74987C91FB9687C71",
+ "81691D5D20EC818FCFF24B33DECC",
+ "C948093218AA9EB2A8E44A87EEA73FC8B6B75A196819A14BD83709EA323E8DF8B491045220E1D88729A38DBCFFB60D3056DAD4564498FD6574F74512945DEB34B69329ACED9FFC05D5D59DFCD5B973E2ACAFE6AD1EF8BBBC49351A2DD12508ED89ED",
+ "EB861165DAF7625F827C6B574ED703F03215",
+ "C6CD1CE76D2B3679C1B5AA1CFD67CCB55444B6BFD3E22C81CBC9BB738796B83E54E3"},
+ {"8CE0156D26FAEB7E0B9B800BBB2E9D4075B5EAC5C62358B0E7F6FCE610223282",
+ "D2A7B94DD12CDACA909D3AD7",
+ "E021A78F374FC271389AB9A3E97077D755",
+ "7C26000B58929F5095E1CEE154F76C2A299248E299F9B5ADE6C403AA1FD4A67FD4E0232F214CE7B919EE7A1027D2B76C57475715CD078461",
+ "C556FB38DF069B56F337B5FF5775CE6EAA16824DFA754F20B78819028EA635C3BB7AA731DE8776B2DCB67DCA2D33EEDF3C7E52EA450013722A41755A0752433ED17BDD5991AAE77A"},
+ {"1E8000A2CE00A561C9920A30BF0D7B983FEF8A1014C8F04C35CA6970E6BA02BD",
+ "65ED3D63F79F90BBFD19775E",
+ "336A8C0B7243582A46B221AA677647FCAE91",
+ "134A8B34824A290E7B",
+ "914FBEF80D0E6E17F8BDBB6097EBF5FBB0554952DC2B9E5151"},
+ {"53D5607BBE690B6E8D8F6D97F3DF2BA853B682597A214B8AA0EA6E598650AF15",
+ "C391A856B9FE234E14BA1AC7BB40FF",
+ "479682BC21349C4BE1641D5E78FE2C79EC1B9CF5470936DCAD9967A4DCD7C4EFADA593BC9EDE71E6A08829B8580901B61E274227E9D918502DE3",
+ "EAD154DC09C5E26C5D26FF33ED148B27120C7F2C23225CC0D0631B03E1F6C6D96FEB88C1A4052ACB4CE746B884B6502931F407021126C6AAB8C514C077A5A38438AE88EE",
+ "938821286EBB671D999B87C032E1D6055392EB564E57970D55E545FC5E8BAB90E6E3E3C0913F6320995FC636D72CD9919657CC38BD51552F4A502D8D1FE56DB33EBAC5092630E69EBB986F0E15CEE9FC8C052501"},
+ {"294362FCC984F440CEA3E9F7D2C06AF20C53AAC1B3738CA2186C914A6E193ABB",
+ "B15B61C8BB39261A8F55AB178EC3",
+ "D0729B6B75BB",
+ "2BD089ADCE9F334BAE3B065996C7D616DD0C27DF4218DCEEA0FBCA0F968837CE26B0876083327E25681FDDD620A32EC0DA12F73FAE826CC94BFF2B90A54D2651",
+ "AC94B25E4E21DE2437B806966CCD5D9385EF0CD4A51AB9FA6DE675C7B8952D67802E9FEC1FDE9F5D1EAB06057498BC0EEA454804FC9D2068982A3E24182D9AC2E7AB9994DDC899A604264583F63D066B"},
+ {"959DBFEB039B1A5B8CE6A44649B602AAA5F98A906DB96143D202CD2024F749D9",
+ "01D7BDB1133E9C347486C1EFA6",
+ "F3843955BD741F379DD750585EDC55E2CDA05CCBA8C1F4622AC2FE35214BC3A019B8BD12C4CC42D9213D1E1556941E8D8450830287FFB3B763A13722DD4140ED9846FB5FFF745D7B0B967D810A068222E10B259AF1D392035B0D83DC1498A6830B11B2418A840212599171E0258A1C203B05362978",
+ "A21811232C950FA8B12237C2EBD6A7CD2C3A155905E9E0C7C120",
+ "63C1CE397B22F1A03F1FA549B43178BC405B152D3C95E977426D519B3DFCA28498823240592B6EEE7A14"},
+ {"096AE499F5294173F34FF2B375F0E5D5AB79D0D03B33B1A74D7D576826345DF4",
+ "0C52B3D11D636E5910A4DD76D32C",
+ "229E9ECA3053789E937447BC719467075B6138A142DA528DA8F0CF8DDF022FD9AF8E74779BA3AC306609",
+ "8B7A00038783E8BAF6EDEAE0C4EAB48FC8FD501A588C7E4A4DB71E3604F2155A97687D3D2FFF8569261375A513CF4398CE0F87CA1658A1050F6EF6C4EA3E25",
+ "C20B6CF8D3C8241825FD90B2EDAC7593600646E579A8D8DAAE9E2E40C3835FE801B2BE4379131452BC5182C90307B176DFBE2049544222FE7783147B690774F6D9D7CEF52A91E61E298E9AA15464AC"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_a.go b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_a.go
new file mode 100644
index 00000000..330309ff
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_a.go
@@ -0,0 +1,78 @@
+package ocb
+
+import (
+ "encoding/hex"
+)
+
+// Test vectors from https://tools.ietf.org/html/rfc7253. Note that key is
+// shared across tests.
+var testKey, _ = hex.DecodeString("000102030405060708090A0B0C0D0E0F")
+
+var rfc7253testVectors = []struct {
+ nonce, header, plaintext, ciphertext string
+}{
+ {"BBAA99887766554433221100",
+ "",
+ "",
+ "785407BFFFC8AD9EDCC5520AC9111EE6"},
+ {"BBAA99887766554433221101",
+ "0001020304050607",
+ "0001020304050607",
+ "6820B3657B6F615A5725BDA0D3B4EB3A257C9AF1F8F03009"},
+ {"BBAA99887766554433221102",
+ "0001020304050607",
+ "",
+ "81017F8203F081277152FADE694A0A00"},
+ {"BBAA99887766554433221103",
+ "",
+ "0001020304050607",
+ "45DD69F8F5AAE72414054CD1F35D82760B2CD00D2F99BFA9"},
+ {"BBAA99887766554433221104",
+ "000102030405060708090A0B0C0D0E0F",
+ "000102030405060708090A0B0C0D0E0F",
+ "571D535B60B277188BE5147170A9A22C3AD7A4FF3835B8C5701C1CCEC8FC3358"},
+ {"BBAA99887766554433221105",
+ "000102030405060708090A0B0C0D0E0F",
+ "",
+ "8CF761B6902EF764462AD86498CA6B97"},
+ {"BBAA99887766554433221106",
+ "",
+ "000102030405060708090A0B0C0D0E0F",
+ "5CE88EC2E0692706A915C00AEB8B2396F40E1C743F52436BDF06D8FA1ECA343D"},
+ {"BBAA99887766554433221107",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "1CA2207308C87C010756104D8840CE1952F09673A448A122C92C62241051F57356D7F3C90BB0E07F"},
+ {"BBAA99887766554433221108",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "",
+ "6DC225A071FC1B9F7C69F93B0F1E10DE"},
+ {"BBAA99887766554433221109",
+ "",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "221BD0DE7FA6FE993ECCD769460A0AF2D6CDED0C395B1C3CE725F32494B9F914D85C0B1EB38357FF"},
+ {"BBAA9988776655443322110A",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "BD6F6C496201C69296C11EFD138A467ABD3C707924B964DEAFFC40319AF5A48540FBBA186C5553C68AD9F592A79A4240"},
+ {"BBAA9988776655443322110B",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "",
+ "FE80690BEE8A485D11F32965BC9D2A32"},
+ {"BBAA9988776655443322110C",
+ "",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "2942BFC773BDA23CABC6ACFD9BFD5835BD300F0973792EF46040C53F1432BCDFB5E1DDE3BC18A5F840B52E653444D5DF"},
+ {"BBAA9988776655443322110D",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "D5CA91748410C1751FF8A2F618255B68A0A12E093FF454606E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483A7035490C5769E60"},
+ {"BBAA9988776655443322110E",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "",
+ "C5CD9D1850C141E358649994EE701B68"},
+ {"BBAA9988776655443322110F",
+ "",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "4412923493C57D5DE0D700F753CCE0D1D2D95060122E9F15A5DDBFC5787E50B5CC55EE507BCB084E479AD363AC366B95A98CA5F3000B1479"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go
new file mode 100644
index 00000000..14a3c336
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go
@@ -0,0 +1,25 @@
+package ocb
+
+// Second set of test vectors from https://tools.ietf.org/html/rfc7253
+var rfc7253TestVectorTaglen96 = struct {
+ key, nonce, header, plaintext, ciphertext string
+}{"0F0E0D0C0B0A09080706050403020100",
+ "BBAA9988776655443322110D",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FDAC4F02AA"}
+
+var rfc7253AlgorithmTest = []struct {
+ KEYLEN, TAGLEN int
+ OUTPUT string
+}{
+ {128, 128, "67E944D23256C5E0B6C61FA22FDF1EA2"},
+ {192, 128, "F673F2C3E7174AAE7BAE986CA9F29E17"},
+ {256, 128, "D90EB8E9C977C88B79DD793D7FFA161C"},
+ {128, 96, "77A3D8E73589158D25D01209"},
+ {192, 96, "05D56EAD2752C86BE6932C5E"},
+ {256, 96, "5458359AC23B0CBA9E6330DD"},
+ {128, 64, "192C9B7BD90BA06A"},
+ {192, 64, "0066BC6E0EF34E24"},
+ {256, 64, "7D4EA5D445501CBE"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/aes/keywrap/keywrap.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/aes/keywrap/keywrap.go
new file mode 100644
index 00000000..3c6251d1
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/aes/keywrap/keywrap.go
@@ -0,0 +1,153 @@
+// Copyright 2014 Matthew Endsley
+// All rights reserved
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted providing 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.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+
+// Package keywrap is an implementation of the RFC 3394 AES key wrapping
+// algorithm. This is used in OpenPGP with elliptic curve keys.
+package keywrap
+
+import (
+ "crypto/aes"
+ "encoding/binary"
+ "errors"
+)
+
+var (
+ // ErrWrapPlaintext is returned if the plaintext is not a multiple
+ // of 64 bits.
+ ErrWrapPlaintext = errors.New("keywrap: plainText must be a multiple of 64 bits")
+
+ // ErrUnwrapCiphertext is returned if the ciphertext is not a
+ // multiple of 64 bits.
+ ErrUnwrapCiphertext = errors.New("keywrap: cipherText must by a multiple of 64 bits")
+
+ // ErrUnwrapFailed is returned if unwrapping a key fails.
+ ErrUnwrapFailed = errors.New("keywrap: failed to unwrap key")
+
+ // NB: the AES NewCipher call only fails if the key is an invalid length.
+
+ // ErrInvalidKey is returned when the AES key is invalid.
+ ErrInvalidKey = errors.New("keywrap: invalid AES key")
+)
+
+// Wrap a key using the RFC 3394 AES Key Wrap Algorithm.
+func Wrap(key, plainText []byte) ([]byte, error) {
+ if len(plainText)%8 != 0 {
+ return nil, ErrWrapPlaintext
+ }
+
+ c, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, ErrInvalidKey
+ }
+
+ nblocks := len(plainText) / 8
+
+ // 1) Initialize variables.
+ var block [aes.BlockSize]byte
+ // - Set A = IV, an initial value (see 2.2.3)
+ for ii := 0; ii < 8; ii++ {
+ block[ii] = 0xA6
+ }
+
+ // - For i = 1 to n
+ // - Set R[i] = P[i]
+ intermediate := make([]byte, len(plainText))
+ copy(intermediate, plainText)
+
+ // 2) Calculate intermediate values.
+ for ii := 0; ii < 6; ii++ {
+ for jj := 0; jj < nblocks; jj++ {
+ // - B = AES(K, A | R[i])
+ copy(block[8:], intermediate[jj*8:jj*8+8])
+ c.Encrypt(block[:], block[:])
+
+ // - A = MSB(64, B) ^ t where t = (n*j)+1
+ t := uint64(ii*nblocks + jj + 1)
+ val := binary.BigEndian.Uint64(block[:8]) ^ t
+ binary.BigEndian.PutUint64(block[:8], val)
+
+ // - R[i] = LSB(64, B)
+ copy(intermediate[jj*8:jj*8+8], block[8:])
+ }
+ }
+
+ // 3) Output results.
+ // - Set C[0] = A
+ // - For i = 1 to n
+ // - C[i] = R[i]
+ return append(block[:8], intermediate...), nil
+}
+
+// Unwrap a key using the RFC 3394 AES Key Wrap Algorithm.
+func Unwrap(key, cipherText []byte) ([]byte, error) {
+ if len(cipherText)%8 != 0 {
+ return nil, ErrUnwrapCiphertext
+ }
+
+ c, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, ErrInvalidKey
+ }
+
+ nblocks := len(cipherText)/8 - 1
+
+ // 1) Initialize variables.
+ var block [aes.BlockSize]byte
+ // - Set A = C[0]
+ copy(block[:8], cipherText[:8])
+
+ // - For i = 1 to n
+ // - Set R[i] = C[i]
+ intermediate := make([]byte, len(cipherText)-8)
+ copy(intermediate, cipherText[8:])
+
+ // 2) Compute intermediate values.
+ for jj := 5; jj >= 0; jj-- {
+ for ii := nblocks - 1; ii >= 0; ii-- {
+ // - B = AES-1(K, (A ^ t) | R[i]) where t = n*j+1
+ // - A = MSB(64, B)
+ t := uint64(jj*nblocks + ii + 1)
+ val := binary.BigEndian.Uint64(block[:8]) ^ t
+ binary.BigEndian.PutUint64(block[:8], val)
+
+ copy(block[8:], intermediate[ii*8:ii*8+8])
+ c.Decrypt(block[:], block[:])
+
+ // - R[i] = LSB(B, 64)
+ copy(intermediate[ii*8:ii*8+8], block[8:])
+ }
+ }
+
+ // 3) Output results.
+ // - If A is an appropriate initial value (see 2.2.3),
+ for ii := 0; ii < 8; ii++ {
+ if block[ii] != 0xA6 {
+ return nil, ErrUnwrapFailed
+ }
+ }
+
+ // - For i = 1 to n
+ // - P[i] = R[i]
+ return intermediate, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go
new file mode 100644
index 00000000..d7af9141
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go
@@ -0,0 +1,231 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package armor implements OpenPGP ASCII Armor, see RFC 4880. OpenPGP Armor is
+// very similar to PEM except that it has an additional CRC checksum.
+package armor // import "github.com/ProtonMail/go-crypto/openpgp/armor"
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/base64"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// A Block represents an OpenPGP armored structure.
+//
+// The encoded form is:
+//
+// -----BEGIN Type-----
+// Headers
+//
+// base64-encoded Bytes
+// '=' base64 encoded checksum
+// -----END Type-----
+//
+// where Headers is a possibly empty sequence of Key: Value lines.
+//
+// Since the armored data can be very large, this package presents a streaming
+// interface.
+type Block struct {
+ Type string // The type, taken from the preamble (i.e. "PGP SIGNATURE").
+ Header map[string]string // Optional headers.
+ Body io.Reader // A Reader from which the contents can be read
+ lReader lineReader
+ oReader openpgpReader
+}
+
+var ArmorCorrupt error = errors.StructuralError("armor invalid")
+
+const crc24Init = 0xb704ce
+const crc24Poly = 0x1864cfb
+const crc24Mask = 0xffffff
+
+// crc24 calculates the OpenPGP checksum as specified in RFC 4880, section 6.1
+func crc24(crc uint32, d []byte) uint32 {
+ for _, b := range d {
+ crc ^= uint32(b) << 16
+ for i := 0; i < 8; i++ {
+ crc <<= 1
+ if crc&0x1000000 != 0 {
+ crc ^= crc24Poly
+ }
+ }
+ }
+ return crc
+}
+
+var armorStart = []byte("-----BEGIN ")
+var armorEnd = []byte("-----END ")
+var armorEndOfLine = []byte("-----")
+
+// lineReader wraps a line based reader. It watches for the end of an armor
+// block and records the expected CRC value.
+type lineReader struct {
+ in *bufio.Reader
+ buf []byte
+ eof bool
+ crc uint32
+ crcSet bool
+}
+
+func (l *lineReader) Read(p []byte) (n int, err error) {
+ if l.eof {
+ return 0, io.EOF
+ }
+
+ if len(l.buf) > 0 {
+ n = copy(p, l.buf)
+ l.buf = l.buf[n:]
+ return
+ }
+
+ line, isPrefix, err := l.in.ReadLine()
+ if err != nil {
+ return
+ }
+ if isPrefix {
+ return 0, ArmorCorrupt
+ }
+
+ if bytes.HasPrefix(line, armorEnd) {
+ l.eof = true
+ return 0, io.EOF
+ }
+
+ if len(line) == 5 && line[0] == '=' {
+ // This is the checksum line
+ var expectedBytes [3]byte
+ var m int
+ m, err = base64.StdEncoding.Decode(expectedBytes[0:], line[1:])
+ if m != 3 || err != nil {
+ return
+ }
+ l.crc = uint32(expectedBytes[0])<<16 |
+ uint32(expectedBytes[1])<<8 |
+ uint32(expectedBytes[2])
+
+ line, _, err = l.in.ReadLine()
+ if err != nil && err != io.EOF {
+ return
+ }
+ if !bytes.HasPrefix(line, armorEnd) {
+ return 0, ArmorCorrupt
+ }
+
+ l.eof = true
+ l.crcSet = true
+ return 0, io.EOF
+ }
+
+ if len(line) > 96 {
+ return 0, ArmorCorrupt
+ }
+
+ n = copy(p, line)
+ bytesToSave := len(line) - n
+ if bytesToSave > 0 {
+ if cap(l.buf) < bytesToSave {
+ l.buf = make([]byte, 0, bytesToSave)
+ }
+ l.buf = l.buf[0:bytesToSave]
+ copy(l.buf, line[n:])
+ }
+
+ return
+}
+
+// openpgpReader passes Read calls to the underlying base64 decoder, but keeps
+// a running CRC of the resulting data and checks the CRC against the value
+// found by the lineReader at EOF.
+type openpgpReader struct {
+ lReader *lineReader
+ b64Reader io.Reader
+ currentCRC uint32
+}
+
+func (r *openpgpReader) Read(p []byte) (n int, err error) {
+ n, err = r.b64Reader.Read(p)
+ r.currentCRC = crc24(r.currentCRC, p[:n])
+
+ if err == io.EOF && r.lReader.crcSet && r.lReader.crc != uint32(r.currentCRC&crc24Mask) {
+ return 0, ArmorCorrupt
+ }
+
+ return
+}
+
+// Decode reads a PGP armored block from the given Reader. It will ignore
+// leading garbage. If it doesn't find a block, it will return nil, io.EOF. The
+// given Reader is not usable after calling this function: an arbitrary amount
+// of data may have been read past the end of the block.
+func Decode(in io.Reader) (p *Block, err error) {
+ r := bufio.NewReaderSize(in, 100)
+ var line []byte
+ ignoreNext := false
+
+TryNextBlock:
+ p = nil
+
+ // Skip leading garbage
+ for {
+ ignoreThis := ignoreNext
+ line, ignoreNext, err = r.ReadLine()
+ if err != nil {
+ return
+ }
+ if ignoreNext || ignoreThis {
+ continue
+ }
+ line = bytes.TrimSpace(line)
+ if len(line) > len(armorStart)+len(armorEndOfLine) && bytes.HasPrefix(line, armorStart) {
+ break
+ }
+ }
+
+ p = new(Block)
+ p.Type = string(line[len(armorStart) : len(line)-len(armorEndOfLine)])
+ p.Header = make(map[string]string)
+ nextIsContinuation := false
+ var lastKey string
+
+ // Read headers
+ for {
+ isContinuation := nextIsContinuation
+ line, nextIsContinuation, err = r.ReadLine()
+ if err != nil {
+ p = nil
+ return
+ }
+ if isContinuation {
+ p.Header[lastKey] += string(line)
+ continue
+ }
+ line = bytes.TrimSpace(line)
+ if len(line) == 0 {
+ break
+ }
+
+ i := bytes.Index(line, []byte(":"))
+ if i == -1 {
+ goto TryNextBlock
+ }
+ lastKey = string(line[:i])
+ var value string
+ if len(line) > i+2 {
+ value = string(line[i+2:])
+ }
+ p.Header[lastKey] = value
+ }
+
+ p.lReader.in = r
+ p.oReader.currentCRC = crc24Init
+ p.oReader.lReader = &p.lReader
+ p.oReader.b64Reader = base64.NewDecoder(base64.StdEncoding, &p.lReader)
+ p.Body = &p.oReader
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go
new file mode 100644
index 00000000..5b6e16c1
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go
@@ -0,0 +1,161 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package armor
+
+import (
+ "encoding/base64"
+ "io"
+)
+
+var armorHeaderSep = []byte(": ")
+var blockEnd = []byte("\n=")
+var newline = []byte("\n")
+var armorEndOfLineOut = []byte("-----\n")
+
+// writeSlices writes its arguments to the given Writer.
+func writeSlices(out io.Writer, slices ...[]byte) (err error) {
+ for _, s := range slices {
+ _, err = out.Write(s)
+ if err != nil {
+ return err
+ }
+ }
+ return
+}
+
+// lineBreaker breaks data across several lines, all of the same byte length
+// (except possibly the last). Lines are broken with a single '\n'.
+type lineBreaker struct {
+ lineLength int
+ line []byte
+ used int
+ out io.Writer
+ haveWritten bool
+}
+
+func newLineBreaker(out io.Writer, lineLength int) *lineBreaker {
+ return &lineBreaker{
+ lineLength: lineLength,
+ line: make([]byte, lineLength),
+ used: 0,
+ out: out,
+ }
+}
+
+func (l *lineBreaker) Write(b []byte) (n int, err error) {
+ n = len(b)
+
+ if n == 0 {
+ return
+ }
+
+ if l.used == 0 && l.haveWritten {
+ _, err = l.out.Write([]byte{'\n'})
+ if err != nil {
+ return
+ }
+ }
+
+ if l.used+len(b) < l.lineLength {
+ l.used += copy(l.line[l.used:], b)
+ return
+ }
+
+ l.haveWritten = true
+ _, err = l.out.Write(l.line[0:l.used])
+ if err != nil {
+ return
+ }
+ excess := l.lineLength - l.used
+ l.used = 0
+
+ _, err = l.out.Write(b[0:excess])
+ if err != nil {
+ return
+ }
+
+ _, err = l.Write(b[excess:])
+ return
+}
+
+func (l *lineBreaker) Close() (err error) {
+ if l.used > 0 {
+ _, err = l.out.Write(l.line[0:l.used])
+ if err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// encoding keeps track of a running CRC24 over the data which has been written
+// to it and outputs a OpenPGP checksum when closed, followed by an armor
+// trailer.
+//
+// It's built into a stack of io.Writers:
+//
+// encoding -> base64 encoder -> lineBreaker -> out
+type encoding struct {
+ out io.Writer
+ breaker *lineBreaker
+ b64 io.WriteCloser
+ crc uint32
+ blockType []byte
+}
+
+func (e *encoding) Write(data []byte) (n int, err error) {
+ e.crc = crc24(e.crc, data)
+ return e.b64.Write(data)
+}
+
+func (e *encoding) Close() (err error) {
+ err = e.b64.Close()
+ if err != nil {
+ return
+ }
+ e.breaker.Close()
+
+ var checksumBytes [3]byte
+ checksumBytes[0] = byte(e.crc >> 16)
+ checksumBytes[1] = byte(e.crc >> 8)
+ checksumBytes[2] = byte(e.crc)
+
+ var b64ChecksumBytes [4]byte
+ base64.StdEncoding.Encode(b64ChecksumBytes[:], checksumBytes[:])
+
+ return writeSlices(e.out, blockEnd, b64ChecksumBytes[:], newline, armorEnd, e.blockType, armorEndOfLine)
+}
+
+// Encode returns a WriteCloser which will encode the data written to it in
+// OpenPGP armor.
+func Encode(out io.Writer, blockType string, headers map[string]string) (w io.WriteCloser, err error) {
+ bType := []byte(blockType)
+ err = writeSlices(out, armorStart, bType, armorEndOfLineOut)
+ if err != nil {
+ return
+ }
+
+ for k, v := range headers {
+ err = writeSlices(out, []byte(k), armorHeaderSep, []byte(v), newline)
+ if err != nil {
+ return
+ }
+ }
+
+ _, err = out.Write(newline)
+ if err != nil {
+ return
+ }
+
+ e := &encoding{
+ out: out,
+ breaker: newLineBreaker(out, 64),
+ crc: crc24Init,
+ blockType: bType,
+ }
+ e.b64 = base64.NewEncoder(base64.StdEncoding, e.breaker)
+ return e, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go
new file mode 100644
index 00000000..a94f6150
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go
@@ -0,0 +1,65 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openpgp
+
+import (
+ "hash"
+ "io"
+)
+
+// NewCanonicalTextHash reformats text written to it into the canonical
+// form and then applies the hash h. See RFC 4880, section 5.2.1.
+func NewCanonicalTextHash(h hash.Hash) hash.Hash {
+ return &canonicalTextHash{h, 0}
+}
+
+type canonicalTextHash struct {
+ h hash.Hash
+ s int
+}
+
+var newline = []byte{'\r', '\n'}
+
+func writeCanonical(cw io.Writer, buf []byte, s *int) (int, error) {
+ start := 0
+ for i, c := range buf {
+ switch *s {
+ case 0:
+ if c == '\r' {
+ *s = 1
+ } else if c == '\n' {
+ cw.Write(buf[start:i])
+ cw.Write(newline)
+ start = i + 1
+ }
+ case 1:
+ *s = 0
+ }
+ }
+
+ cw.Write(buf[start:])
+ return len(buf), nil
+}
+
+func (cth *canonicalTextHash) Write(buf []byte) (int, error) {
+ return writeCanonical(cth.h, buf, &cth.s)
+}
+
+func (cth *canonicalTextHash) Sum(in []byte) []byte {
+ return cth.h.Sum(in)
+}
+
+func (cth *canonicalTextHash) Reset() {
+ cth.h.Reset()
+ cth.s = 0
+}
+
+func (cth *canonicalTextHash) Size() int {
+ return cth.h.Size()
+}
+
+func (cth *canonicalTextHash) BlockSize() int {
+ return cth.h.BlockSize()
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go
new file mode 100644
index 00000000..c895bad6
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go
@@ -0,0 +1,210 @@
+// 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 ecdh implements ECDH encryption, suitable for OpenPGP,
+// as specified in RFC 6637, section 8.
+package ecdh
+
+import (
+ "bytes"
+ "errors"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/aes/keywrap"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+)
+
+type KDF struct {
+ Hash algorithm.Hash
+ Cipher algorithm.Cipher
+}
+
+type PublicKey struct {
+ curve ecc.ECDHCurve
+ Point []byte
+ KDF
+}
+
+type PrivateKey struct {
+ PublicKey
+ D []byte
+}
+
+func NewPublicKey(curve ecc.ECDHCurve, kdfHash algorithm.Hash, kdfCipher algorithm.Cipher) *PublicKey {
+ return &PublicKey{
+ curve: curve,
+ KDF: KDF{
+ Hash: kdfHash,
+ Cipher: kdfCipher,
+ },
+ }
+}
+
+func NewPrivateKey(key PublicKey) *PrivateKey {
+ return &PrivateKey{
+ PublicKey: key,
+ }
+}
+
+func (pk *PublicKey) GetCurve() ecc.ECDHCurve {
+ return pk.curve
+}
+
+func (pk *PublicKey) MarshalPoint() []byte {
+ return pk.curve.MarshalBytePoint(pk.Point)
+}
+
+func (pk *PublicKey) UnmarshalPoint(p []byte) error {
+ pk.Point = pk.curve.UnmarshalBytePoint(p)
+ if pk.Point == nil {
+ return errors.New("ecdh: failed to parse EC point")
+ }
+ return nil
+}
+
+func (sk *PrivateKey) MarshalByteSecret() []byte {
+ return sk.curve.MarshalByteSecret(sk.D)
+}
+
+func (sk *PrivateKey) UnmarshalByteSecret(d []byte) error {
+ sk.D = sk.curve.UnmarshalByteSecret(d)
+
+ if sk.D == nil {
+ return errors.New("ecdh: failed to parse scalar")
+ }
+ return nil
+}
+
+func GenerateKey(rand io.Reader, c ecc.ECDHCurve, kdf KDF) (priv *PrivateKey, err error) {
+ priv = new(PrivateKey)
+ priv.PublicKey.curve = c
+ priv.PublicKey.KDF = kdf
+ priv.PublicKey.Point, priv.D, err = c.GenerateECDH(rand)
+ return
+}
+
+func Encrypt(random io.Reader, pub *PublicKey, msg, curveOID, fingerprint []byte) (vsG, c []byte, err error) {
+ if len(msg) > 40 {
+ return nil, nil, errors.New("ecdh: message too long")
+ }
+ // the sender MAY use 21, 13, and 5 bytes of padding for AES-128,
+ // AES-192, and AES-256, respectively, to provide the same number of
+ // octets, 40 total, as an input to the key wrapping method.
+ padding := make([]byte, 40-len(msg))
+ for i := range padding {
+ padding[i] = byte(40 - len(msg))
+ }
+ m := append(msg, padding...)
+
+ ephemeral, zb, err := pub.curve.Encaps(random, pub.Point)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ vsG = pub.curve.MarshalBytePoint(ephemeral)
+
+ z, err := buildKey(pub, zb, curveOID, fingerprint, false, false)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if c, err = keywrap.Wrap(z, m); err != nil {
+ return nil, nil, err
+ }
+
+ return vsG, c, nil
+
+}
+
+func Decrypt(priv *PrivateKey, vsG, c, curveOID, fingerprint []byte) (msg []byte, err error) {
+ var m []byte
+ zb, err := priv.PublicKey.curve.Decaps(priv.curve.UnmarshalBytePoint(vsG), priv.D)
+
+ // Try buildKey three times to workaround an old bug, see comments in buildKey.
+ for i := 0; i < 3; i++ {
+ var z []byte
+ // RFC6637 §8: "Compute Z = KDF( S, Z_len, Param );"
+ z, err = buildKey(&priv.PublicKey, zb, curveOID, fingerprint, i == 1, i == 2)
+ if err != nil {
+ return nil, err
+ }
+
+ // RFC6637 §8: "Compute C = AESKeyWrap( Z, c ) as per [RFC3394]"
+ m, err = keywrap.Unwrap(z, c)
+ if err == nil {
+ break
+ }
+ }
+
+ // Only return an error after we've tried all (required) variants of buildKey.
+ if err != nil {
+ return nil, err
+ }
+
+ // RFC6637 §8: "m = symm_alg_ID || session key || checksum || pkcs5_padding"
+ // The last byte should be the length of the padding, as per PKCS5; strip it off.
+ return m[:len(m)-int(m[len(m)-1])], nil
+}
+
+func buildKey(pub *PublicKey, zb []byte, curveOID, fingerprint []byte, stripLeading, stripTrailing bool) ([]byte, error) {
+ // Param = curve_OID_len || curve_OID || public_key_alg_ID || 03
+ // || 01 || KDF_hash_ID || KEK_alg_ID for AESKeyWrap
+ // || "Anonymous Sender " || recipient_fingerprint;
+ param := new(bytes.Buffer)
+ if _, err := param.Write(curveOID); err != nil {
+ return nil, err
+ }
+ algKDF := []byte{18, 3, 1, pub.KDF.Hash.Id(), pub.KDF.Cipher.Id()}
+ if _, err := param.Write(algKDF); err != nil {
+ return nil, err
+ }
+ if _, err := param.Write([]byte("Anonymous Sender ")); err != nil {
+ return nil, err
+ }
+ // For v5 keys, the 20 leftmost octets of the fingerprint are used.
+ if _, err := param.Write(fingerprint[:20]); err != nil {
+ return nil, err
+ }
+ if param.Len()-len(curveOID) != 45 {
+ return nil, errors.New("ecdh: malformed KDF Param")
+ }
+
+ // MB = Hash ( 00 || 00 || 00 || 01 || ZB || Param );
+ h := pub.KDF.Hash.New()
+ if _, err := h.Write([]byte{0x0, 0x0, 0x0, 0x1}); err != nil {
+ return nil, err
+ }
+ zbLen := len(zb)
+ i := 0
+ j := zbLen - 1
+ if stripLeading {
+ // Work around old go crypto bug where the leading zeros are missing.
+ for i < zbLen && zb[i] == 0 {
+ i++
+ }
+ }
+ if stripTrailing {
+ // Work around old OpenPGP.js bug where insignificant trailing zeros in
+ // this little-endian number are missing.
+ // (See https://github.com/openpgpjs/openpgpjs/pull/853.)
+ for j >= 0 && zb[j] == 0 {
+ j--
+ }
+ }
+ if _, err := h.Write(zb[i : j+1]); err != nil {
+ return nil, err
+ }
+ if _, err := h.Write(param.Bytes()); err != nil {
+ return nil, err
+ }
+ mb := h.Sum(nil)
+
+ return mb[:pub.KDF.Cipher.KeySize()], nil // return oBits leftmost bits of MB.
+
+}
+
+func Validate(priv *PrivateKey) error {
+ return priv.curve.ValidateECDH(priv.Point, priv.D)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go
new file mode 100644
index 00000000..f94ae1b2
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go
@@ -0,0 +1,80 @@
+// Package ecdsa implements ECDSA signature, suitable for OpenPGP,
+// as specified in RFC 6637, section 5.
+package ecdsa
+
+import (
+ "errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+ "io"
+ "math/big"
+)
+
+type PublicKey struct {
+ X, Y *big.Int
+ curve ecc.ECDSACurve
+}
+
+type PrivateKey struct {
+ PublicKey
+ D *big.Int
+}
+
+func NewPublicKey(curve ecc.ECDSACurve) *PublicKey {
+ return &PublicKey{
+ curve: curve,
+ }
+}
+
+func NewPrivateKey(key PublicKey) *PrivateKey {
+ return &PrivateKey{
+ PublicKey: key,
+ }
+}
+
+func (pk *PublicKey) GetCurve() ecc.ECDSACurve {
+ return pk.curve
+}
+
+func (pk *PublicKey) MarshalPoint() []byte {
+ return pk.curve.MarshalIntegerPoint(pk.X, pk.Y)
+}
+
+func (pk *PublicKey) UnmarshalPoint(p []byte) error {
+ pk.X, pk.Y = pk.curve.UnmarshalIntegerPoint(p)
+ if pk.X == nil {
+ return errors.New("ecdsa: failed to parse EC point")
+ }
+ return nil
+}
+
+func (sk *PrivateKey) MarshalIntegerSecret() []byte {
+ return sk.curve.MarshalIntegerSecret(sk.D)
+}
+
+func (sk *PrivateKey) UnmarshalIntegerSecret(d []byte) error {
+ sk.D = sk.curve.UnmarshalIntegerSecret(d)
+
+ if sk.D == nil {
+ return errors.New("ecdsa: failed to parse scalar")
+ }
+ return nil
+}
+
+func GenerateKey(rand io.Reader, c ecc.ECDSACurve) (priv *PrivateKey, err error) {
+ priv = new(PrivateKey)
+ priv.PublicKey.curve = c
+ priv.PublicKey.X, priv.PublicKey.Y, priv.D, err = c.GenerateECDSA(rand)
+ return
+}
+
+func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
+ return priv.PublicKey.curve.Sign(rand, priv.X, priv.Y, priv.D, hash)
+}
+
+func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
+ return pub.curve.Verify(pub.X, pub.Y, hash, r, s)
+}
+
+func Validate(priv *PrivateKey) error {
+ return priv.curve.ValidateECDSA(priv.X, priv.Y, priv.D.Bytes())
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go
new file mode 100644
index 00000000..99ecfc7f
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go
@@ -0,0 +1,91 @@
+// Package eddsa implements EdDSA signature, suitable for OpenPGP, as specified in
+// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-13.7
+package eddsa
+
+import (
+ "errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+ "io"
+)
+
+type PublicKey struct {
+ X []byte
+ curve ecc.EdDSACurve
+}
+
+type PrivateKey struct {
+ PublicKey
+ D []byte
+}
+
+func NewPublicKey(curve ecc.EdDSACurve) *PublicKey {
+ return &PublicKey{
+ curve: curve,
+ }
+}
+
+func NewPrivateKey(key PublicKey) *PrivateKey {
+ return &PrivateKey{
+ PublicKey: key,
+ }
+}
+
+func (pk *PublicKey) GetCurve() ecc.EdDSACurve {
+ return pk.curve
+}
+
+func (pk *PublicKey) MarshalPoint() []byte {
+ return pk.curve.MarshalBytePoint(pk.X)
+}
+
+func (pk *PublicKey) UnmarshalPoint(x []byte) error {
+ pk.X = pk.curve.UnmarshalBytePoint(x)
+
+ if pk.X == nil {
+ return errors.New("eddsa: failed to parse EC point")
+ }
+ return nil
+}
+
+func (sk *PrivateKey) MarshalByteSecret() []byte {
+ return sk.curve.MarshalByteSecret(sk.D)
+}
+
+func (sk *PrivateKey) UnmarshalByteSecret(d []byte) error {
+ sk.D = sk.curve.UnmarshalByteSecret(d)
+
+ if sk.D == nil {
+ return errors.New("eddsa: failed to parse scalar")
+ }
+ return nil
+}
+
+func GenerateKey(rand io.Reader, c ecc.EdDSACurve) (priv *PrivateKey, err error) {
+ priv = new(PrivateKey)
+ priv.PublicKey.curve = c
+ priv.PublicKey.X, priv.D, err = c.GenerateEdDSA(rand)
+ return
+}
+
+func Sign(priv *PrivateKey, message []byte) (r, s []byte, err error) {
+ sig, err := priv.PublicKey.curve.Sign(priv.PublicKey.X, priv.D, message)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ r, s = priv.PublicKey.curve.MarshalSignature(sig)
+ return
+}
+
+func Verify(pub *PublicKey, message, r, s []byte) bool {
+ sig := pub.curve.UnmarshalSignature(r, s)
+ if sig == nil {
+ return false
+ }
+
+ return pub.curve.Verify(pub.X, message, sig)
+}
+
+func Validate(priv *PrivateKey) error {
+ return priv.curve.ValidateEdDSA(priv.PublicKey.X, priv.D)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go
new file mode 100644
index 00000000..bad27743
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go
@@ -0,0 +1,124 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package elgamal implements ElGamal encryption, suitable for OpenPGP,
+// as specified in "A Public-Key Cryptosystem and a Signature Scheme Based on
+// Discrete Logarithms," IEEE Transactions on Information Theory, v. IT-31,
+// n. 4, 1985, pp. 469-472.
+//
+// This form of ElGamal embeds PKCS#1 v1.5 padding, which may make it
+// unsuitable for other protocols. RSA should be used in preference in any
+// case.
+package elgamal // import "github.com/ProtonMail/go-crypto/openpgp/elgamal"
+
+import (
+ "crypto/rand"
+ "crypto/subtle"
+ "errors"
+ "io"
+ "math/big"
+)
+
+// PublicKey represents an ElGamal public key.
+type PublicKey struct {
+ G, P, Y *big.Int
+}
+
+// PrivateKey represents an ElGamal private key.
+type PrivateKey struct {
+ PublicKey
+ X *big.Int
+}
+
+// Encrypt encrypts the given message to the given public key. The result is a
+// pair of integers. Errors can result from reading random, or because msg is
+// too large to be encrypted to the public key.
+func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error) {
+ pLen := (pub.P.BitLen() + 7) / 8
+ if len(msg) > pLen-11 {
+ err = errors.New("elgamal: message too long")
+ return
+ }
+
+ // EM = 0x02 || PS || 0x00 || M
+ em := make([]byte, pLen-1)
+ em[0] = 2
+ ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):]
+ err = nonZeroRandomBytes(ps, random)
+ if err != nil {
+ return
+ }
+ em[len(em)-len(msg)-1] = 0
+ copy(mm, msg)
+
+ m := new(big.Int).SetBytes(em)
+
+ k, err := rand.Int(random, pub.P)
+ if err != nil {
+ return
+ }
+
+ c1 = new(big.Int).Exp(pub.G, k, pub.P)
+ s := new(big.Int).Exp(pub.Y, k, pub.P)
+ c2 = s.Mul(s, m)
+ c2.Mod(c2, pub.P)
+
+ return
+}
+
+// Decrypt takes two integers, resulting from an ElGamal encryption, and
+// returns the plaintext of the message. An error can result only if the
+// ciphertext is invalid. Users should keep in mind that this is a padding
+// oracle and thus, if exposed to an adaptive chosen ciphertext attack, can
+// be used to break the cryptosystem. See “Chosen Ciphertext Attacks
+// Against Protocols Based on the RSA Encryption Standard PKCS #1”, Daniel
+// Bleichenbacher, Advances in Cryptology (Crypto '98),
+func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
+ s := new(big.Int).Exp(c1, priv.X, priv.P)
+ if s.ModInverse(s, priv.P) == nil {
+ return nil, errors.New("elgamal: invalid private key")
+ }
+ s.Mul(s, c2)
+ s.Mod(s, priv.P)
+ em := s.Bytes()
+
+ firstByteIsTwo := subtle.ConstantTimeByteEq(em[0], 2)
+
+ // The remainder of the plaintext must be a string of non-zero random
+ // octets, followed by a 0, followed by the message.
+ // lookingForIndex: 1 iff we are still looking for the zero.
+ // index: the offset of the first zero byte.
+ var lookingForIndex, index int
+ lookingForIndex = 1
+
+ for i := 1; i < len(em); i++ {
+ equals0 := subtle.ConstantTimeByteEq(em[i], 0)
+ index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
+ lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
+ }
+
+ if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 {
+ return nil, errors.New("elgamal: decryption error")
+ }
+ return em[index+1:], nil
+}
+
+// nonZeroRandomBytes fills the given slice with non-zero random octets.
+func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
+ _, err = io.ReadFull(rand, s)
+ if err != nil {
+ return
+ }
+
+ for i := 0; i < len(s); i++ {
+ for s[i] == 0 {
+ _, err = io.ReadFull(rand, s[i:i+1])
+ if err != nil {
+ return
+ }
+ }
+ }
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go
new file mode 100644
index 00000000..17e2bcfe
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go
@@ -0,0 +1,116 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package errors contains common error types for the OpenPGP packages.
+package errors // import "github.com/ProtonMail/go-crypto/openpgp/errors"
+
+import (
+ "strconv"
+)
+
+// A StructuralError is returned when OpenPGP data is found to be syntactically
+// invalid.
+type StructuralError string
+
+func (s StructuralError) Error() string {
+ return "openpgp: invalid data: " + string(s)
+}
+
+// UnsupportedError indicates that, although the OpenPGP data is valid, it
+// makes use of currently unimplemented features.
+type UnsupportedError string
+
+func (s UnsupportedError) Error() string {
+ return "openpgp: unsupported feature: " + string(s)
+}
+
+// InvalidArgumentError indicates that the caller is in error and passed an
+// incorrect value.
+type InvalidArgumentError string
+
+func (i InvalidArgumentError) Error() string {
+ return "openpgp: invalid argument: " + string(i)
+}
+
+// SignatureError indicates that a syntactically valid signature failed to
+// validate.
+type SignatureError string
+
+func (b SignatureError) Error() string {
+ return "openpgp: invalid signature: " + string(b)
+}
+
+var ErrMDCHashMismatch error = SignatureError("MDC hash mismatch")
+var ErrMDCMissing error = SignatureError("MDC packet not found")
+
+type signatureExpiredError int
+
+func (se signatureExpiredError) Error() string {
+ return "openpgp: signature expired"
+}
+
+var ErrSignatureExpired error = signatureExpiredError(0)
+
+type keyExpiredError int
+
+func (ke keyExpiredError) Error() string {
+ return "openpgp: key expired"
+}
+
+var ErrKeyExpired error = keyExpiredError(0)
+
+type keyIncorrectError int
+
+func (ki keyIncorrectError) Error() string {
+ return "openpgp: incorrect key"
+}
+
+var ErrKeyIncorrect error = keyIncorrectError(0)
+
+// KeyInvalidError indicates that the public key parameters are invalid
+// as they do not match the private ones
+type KeyInvalidError string
+
+func (e KeyInvalidError) Error() string {
+ return "openpgp: invalid key: " + string(e)
+}
+
+type unknownIssuerError int
+
+func (unknownIssuerError) Error() string {
+ return "openpgp: signature made by unknown entity"
+}
+
+var ErrUnknownIssuer error = unknownIssuerError(0)
+
+type keyRevokedError int
+
+func (keyRevokedError) Error() string {
+ return "openpgp: signature made by revoked key"
+}
+
+var ErrKeyRevoked error = keyRevokedError(0)
+
+type UnknownPacketTypeError uint8
+
+func (upte UnknownPacketTypeError) Error() string {
+ return "openpgp: unknown packet type: " + strconv.Itoa(int(upte))
+}
+
+// AEADError indicates that there is a problem when initializing or using a
+// AEAD instance, configuration struct, nonces or index values.
+type AEADError string
+
+func (ae AEADError) Error() string {
+ return "openpgp: aead error: " + string(ae)
+}
+
+// ErrDummyPrivateKey results when operations are attempted on a private key
+// that is just a dummy key. See
+// https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/DETAILS;h=fe55ae16ab4e26d8356dc574c9e8bc935e71aef1;hb=23191d7851eae2217ecdac6484349849a24fd94a#l1109
+type ErrDummyPrivateKey string
+
+func (dke ErrDummyPrivateKey) Error() string {
+ return "openpgp: s2k GNU dummy key: " + string(dke)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go
new file mode 100644
index 00000000..526bd777
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go
@@ -0,0 +1,24 @@
+package openpgp
+
+import (
+ "crypto"
+
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+)
+
+// HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP
+// hash id.
+func HashIdToHash(id byte) (h crypto.Hash, ok bool) {
+ return algorithm.HashIdToHash(id)
+}
+
+// HashIdToString returns the name of the hash function corresponding to the
+// given OpenPGP hash id.
+func HashIdToString(id byte) (name string, ok bool) {
+ return algorithm.HashIdToString(id)
+}
+
+// HashToHashId returns an OpenPGP hash id which corresponds the given Hash.
+func HashToHashId(h crypto.Hash) (id byte, ok bool) {
+ return algorithm.HashToHashId(h)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/aead.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/aead.go
new file mode 100644
index 00000000..d0670651
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/aead.go
@@ -0,0 +1,65 @@
+// Copyright (C) 2019 ProtonTech AG
+
+package algorithm
+
+import (
+ "crypto/cipher"
+ "github.com/ProtonMail/go-crypto/eax"
+ "github.com/ProtonMail/go-crypto/ocb"
+)
+
+// AEADMode defines the Authenticated Encryption with Associated Data mode of
+// operation.
+type AEADMode uint8
+
+// Supported modes of operation (see RFC4880bis [EAX] and RFC7253)
+const (
+ AEADModeEAX = AEADMode(1)
+ AEADModeOCB = AEADMode(2)
+ AEADModeGCM = AEADMode(3)
+)
+
+// TagLength returns the length in bytes of authentication tags.
+func (mode AEADMode) TagLength() int {
+ switch mode {
+ case AEADModeEAX:
+ return 16
+ case AEADModeOCB:
+ return 16
+ case AEADModeGCM:
+ return 16
+ default:
+ return 0
+ }
+}
+
+// NonceLength returns the length in bytes of nonces.
+func (mode AEADMode) NonceLength() int {
+ switch mode {
+ case AEADModeEAX:
+ return 16
+ case AEADModeOCB:
+ return 15
+ case AEADModeGCM:
+ return 12
+ default:
+ return 0
+ }
+}
+
+// New returns a fresh instance of the given mode
+func (mode AEADMode) New(block cipher.Block) (alg cipher.AEAD) {
+ var err error
+ switch mode {
+ case AEADModeEAX:
+ alg, err = eax.NewEAX(block)
+ case AEADModeOCB:
+ alg, err = ocb.NewOCB(block)
+ case AEADModeGCM:
+ alg, err = cipher.NewGCM(block)
+ }
+ if err != nil {
+ panic(err.Error())
+ }
+ return alg
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go
new file mode 100644
index 00000000..5760cff8
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go
@@ -0,0 +1,107 @@
+// 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 algorithm
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/des"
+
+ "golang.org/x/crypto/cast5"
+)
+
+// Cipher is an official symmetric key cipher algorithm. See RFC 4880,
+// section 9.2.
+type Cipher interface {
+ // Id returns the algorithm ID, as a byte, of the cipher.
+ Id() uint8
+ // KeySize returns the key size, in bytes, of the cipher.
+ KeySize() int
+ // BlockSize returns the block size, in bytes, of the cipher.
+ BlockSize() int
+ // New returns a fresh instance of the given cipher.
+ New(key []byte) cipher.Block
+}
+
+// The following constants mirror the OpenPGP standard (RFC 4880).
+const (
+ TripleDES = CipherFunction(2)
+ CAST5 = CipherFunction(3)
+ AES128 = CipherFunction(7)
+ AES192 = CipherFunction(8)
+ AES256 = CipherFunction(9)
+)
+
+// CipherById represents the different block ciphers specified for OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
+var CipherById = map[uint8]Cipher{
+ TripleDES.Id(): TripleDES,
+ CAST5.Id(): CAST5,
+ AES128.Id(): AES128,
+ AES192.Id(): AES192,
+ AES256.Id(): AES256,
+}
+
+type CipherFunction uint8
+
+// ID returns the algorithm Id, as a byte, of cipher.
+func (sk CipherFunction) Id() uint8 {
+ return uint8(sk)
+}
+
+var keySizeByID = map[uint8]int{
+ TripleDES.Id(): 24,
+ CAST5.Id(): cast5.KeySize,
+ AES128.Id(): 16,
+ AES192.Id(): 24,
+ AES256.Id(): 32,
+}
+
+// KeySize returns the key size, in bytes, of cipher.
+func (cipher CipherFunction) KeySize() int {
+ switch cipher {
+ case TripleDES:
+ return 24
+ case CAST5:
+ return cast5.KeySize
+ case AES128:
+ return 16
+ case AES192:
+ return 24
+ case AES256:
+ return 32
+ }
+ return 0
+}
+
+// BlockSize returns the block size, in bytes, of cipher.
+func (cipher CipherFunction) BlockSize() int {
+ switch cipher {
+ case TripleDES:
+ return des.BlockSize
+ case CAST5:
+ return 8
+ case AES128, AES192, AES256:
+ return 16
+ }
+ return 0
+}
+
+// New returns a fresh instance of the given cipher.
+func (cipher CipherFunction) New(key []byte) (block cipher.Block) {
+ var err error
+ switch cipher {
+ case TripleDES:
+ block, err = des.NewTripleDESCipher(key)
+ case CAST5:
+ block, err = cast5.NewCipher(key)
+ case AES128, AES192, AES256:
+ block, err = aes.NewCipher(key)
+ }
+ if err != nil {
+ panic(err.Error())
+ }
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go
new file mode 100644
index 00000000..d1a00fc7
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go
@@ -0,0 +1,143 @@
+// 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 algorithm
+
+import (
+ "crypto"
+ "fmt"
+ "hash"
+)
+
+// Hash is an official hash function algorithm. See RFC 4880, section 9.4.
+type Hash interface {
+ // Id returns the algorithm ID, as a byte, of Hash.
+ Id() uint8
+ // Available reports whether the given hash function is linked into the binary.
+ Available() bool
+ // HashFunc simply returns the value of h so that Hash implements SignerOpts.
+ HashFunc() crypto.Hash
+ // New returns a new hash.Hash calculating the given hash function. New
+ // panics if the hash function is not linked into the binary.
+ New() hash.Hash
+ // Size returns the length, in bytes, of a digest resulting from the given
+ // hash function. It doesn't require that the hash function in question be
+ // linked into the program.
+ Size() int
+ // String is the name of the hash function corresponding to the given
+ // OpenPGP hash id.
+ String() string
+}
+
+// The following vars mirror the crypto/Hash supported hash functions.
+var (
+ SHA1 Hash = cryptoHash{2, crypto.SHA1}
+ SHA256 Hash = cryptoHash{8, crypto.SHA256}
+ SHA384 Hash = cryptoHash{9, crypto.SHA384}
+ SHA512 Hash = cryptoHash{10, crypto.SHA512}
+ SHA224 Hash = cryptoHash{11, crypto.SHA224}
+ SHA3_256 Hash = cryptoHash{12, crypto.SHA3_256}
+ SHA3_512 Hash = cryptoHash{14, crypto.SHA3_512}
+)
+
+// HashById represents the different hash functions specified for OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-14
+var (
+ HashById = map[uint8]Hash{
+ SHA256.Id(): SHA256,
+ SHA384.Id(): SHA384,
+ SHA512.Id(): SHA512,
+ SHA224.Id(): SHA224,
+ SHA3_256.Id(): SHA3_256,
+ SHA3_512.Id(): SHA3_512,
+ }
+)
+
+// cryptoHash contains pairs relating OpenPGP's hash identifier with
+// Go's crypto.Hash type. See RFC 4880, section 9.4.
+type cryptoHash struct {
+ id uint8
+ crypto.Hash
+}
+
+// Id returns the algorithm ID, as a byte, of cryptoHash.
+func (h cryptoHash) Id() uint8 {
+ return h.id
+}
+
+var hashNames = map[uint8]string{
+ SHA256.Id(): "SHA256",
+ SHA384.Id(): "SHA384",
+ SHA512.Id(): "SHA512",
+ SHA224.Id(): "SHA224",
+ SHA3_256.Id(): "SHA3-256",
+ SHA3_512.Id(): "SHA3-512",
+}
+
+func (h cryptoHash) String() string {
+ s, ok := hashNames[h.id]
+ if !ok {
+ panic(fmt.Sprintf("Unsupported hash function %d", h.id))
+ }
+ return s
+}
+
+// HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP
+// hash id.
+func HashIdToHash(id byte) (h crypto.Hash, ok bool) {
+ if hash, ok := HashById[id]; ok {
+ return hash.HashFunc(), true
+ }
+ return 0, false
+}
+
+// HashIdToHashWithSha1 returns a crypto.Hash which corresponds to the given OpenPGP
+// hash id, allowing sha1.
+func HashIdToHashWithSha1(id byte) (h crypto.Hash, ok bool) {
+ if hash, ok := HashById[id]; ok {
+ return hash.HashFunc(), true
+ }
+
+ if id == SHA1.Id() {
+ return SHA1.HashFunc(), true
+ }
+
+ return 0, false
+}
+
+// HashIdToString returns the name of the hash function corresponding to the
+// given OpenPGP hash id.
+func HashIdToString(id byte) (name string, ok bool) {
+ if hash, ok := HashById[id]; ok {
+ return hash.String(), true
+ }
+ return "", false
+}
+
+// HashToHashId returns an OpenPGP hash id which corresponds the given Hash.
+func HashToHashId(h crypto.Hash) (id byte, ok bool) {
+ for id, hash := range HashById {
+ if hash.HashFunc() == h {
+ return id, true
+ }
+ }
+
+ return 0, false
+}
+
+// HashToHashIdWithSha1 returns an OpenPGP hash id which corresponds the given Hash,
+// allowing instances of SHA1
+func HashToHashIdWithSha1(h crypto.Hash) (id byte, ok bool) {
+ for id, hash := range HashById {
+ if hash.HashFunc() == h {
+ return id, true
+ }
+ }
+
+ if h == SHA1.HashFunc() {
+ return SHA1.Id(), true
+ }
+
+ return 0, false
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go
new file mode 100644
index 00000000..888767c4
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go
@@ -0,0 +1,171 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/subtle"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ x25519lib "github.com/cloudflare/circl/dh/x25519"
+)
+
+type curve25519 struct{}
+
+func NewCurve25519() *curve25519 {
+ return &curve25519{}
+}
+
+func (c *curve25519) GetCurveName() string {
+ return "curve25519"
+}
+
+// MarshalBytePoint encodes the public point from native format, adding the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6
+func (c *curve25519) MarshalBytePoint(point []byte) []byte {
+ return append([]byte{0x40}, point...)
+}
+
+// UnmarshalBytePoint decodes the public point to native format, removing the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6
+func (c *curve25519) UnmarshalBytePoint(point []byte) []byte {
+ if len(point) != x25519lib.Size+1 {
+ return nil
+ }
+
+ // Remove prefix
+ return point[1:]
+}
+
+// MarshalByteSecret encodes the secret scalar from native format.
+// Note that the EC secret scalar differs from the definition of public keys in
+// [Curve25519] in two ways: (1) the byte-ordering is big-endian, which is
+// more uniform with how big integers are represented in OpenPGP, and (2) the
+// leading zeros are truncated.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6.1.1
+// Note that leading zero bytes are stripped later when encoding as an MPI.
+func (c *curve25519) MarshalByteSecret(secret []byte) []byte {
+ d := make([]byte, x25519lib.Size)
+ copyReversed(d, secret)
+
+ // The following ensures that the private key is a number of the form
+ // 2^{254} + 8 * [0, 2^{251}), in order to avoid the small subgroup of
+ // the curve.
+ //
+ // This masking is done internally in the underlying lib and so is unnecessary
+ // for security, but OpenPGP implementations require that private keys be
+ // pre-masked.
+ d[0] &= 127
+ d[0] |= 64
+ d[31] &= 248
+
+ return d
+}
+
+// UnmarshalByteSecret decodes the secret scalar from native format.
+// Note that the EC secret scalar differs from the definition of public keys in
+// [Curve25519] in two ways: (1) the byte-ordering is big-endian, which is
+// more uniform with how big integers are represented in OpenPGP, and (2) the
+// leading zeros are truncated.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6.1.1
+func (c *curve25519) UnmarshalByteSecret(d []byte) []byte {
+ if len(d) > x25519lib.Size {
+ return nil
+ }
+
+ // Ensure truncated leading bytes are re-added
+ secret := make([]byte, x25519lib.Size)
+ copyReversed(secret, d)
+
+ return secret
+}
+
+// generateKeyPairBytes Generates a private-public key-pair.
+// 'priv' is a private key; a little-endian scalar belonging to the set
+// 2^{254} + 8 * [0, 2^{251}), in order to avoid the small subgroup of the
+// curve. 'pub' is simply 'priv' * G where G is the base point.
+// See https://cr.yp.to/ecdh.html and RFC7748, sec 5.
+func (c *curve25519) generateKeyPairBytes(rand io.Reader) (priv, pub x25519lib.Key, err error) {
+ _, err = io.ReadFull(rand, priv[:])
+ if err != nil {
+ return
+ }
+
+ x25519lib.KeyGen(&pub, &priv)
+ return
+}
+
+func (c *curve25519) GenerateECDH(rand io.Reader) (point []byte, secret []byte, err error) {
+ priv, pub, err := c.generateKeyPairBytes(rand)
+ if err != nil {
+ return
+ }
+
+ return pub[:], priv[:], nil
+}
+
+func (c *genericCurve) MaskSecret(secret []byte) []byte {
+ return secret
+}
+
+func (c *curve25519) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) {
+ // RFC6637 §8: "Generate an ephemeral key pair {v, V=vG}"
+ // ephemeralPrivate corresponds to `v`.
+ // ephemeralPublic corresponds to `V`.
+ ephemeralPrivate, ephemeralPublic, err := c.generateKeyPairBytes(rand)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ // RFC6637 §8: "Obtain the authenticated recipient public key R"
+ // pubKey corresponds to `R`.
+ var pubKey x25519lib.Key
+ copy(pubKey[:], point)
+
+ // RFC6637 §8: "Compute the shared point S = vR"
+ // "VB = convert point V to the octet string"
+ // sharedPoint corresponds to `VB`.
+ var sharedPoint x25519lib.Key
+ x25519lib.Shared(&sharedPoint, &ephemeralPrivate, &pubKey)
+
+ return ephemeralPublic[:], sharedPoint[:], nil
+}
+
+func (c *curve25519) Decaps(vsG, secret []byte) (sharedSecret []byte, err error) {
+ var ephemeralPublic, decodedPrivate, sharedPoint x25519lib.Key
+ // RFC6637 §8: "The decryption is the inverse of the method given."
+ // All quoted descriptions in comments below describe encryption, and
+ // the reverse is performed.
+ // vsG corresponds to `VB` in RFC6637 §8 .
+
+ // RFC6637 §8: "VB = convert point V to the octet string"
+ copy(ephemeralPublic[:], vsG)
+
+ // decodedPrivate corresponds to `r` in RFC6637 §8 .
+ copy(decodedPrivate[:], secret)
+
+ // RFC6637 §8: "Note that the recipient obtains the shared secret by calculating
+ // S = rV = rvG, where (r,R) is the recipient's key pair."
+ // sharedPoint corresponds to `S`.
+ x25519lib.Shared(&sharedPoint, &decodedPrivate, &ephemeralPublic)
+
+ return sharedPoint[:], nil
+}
+
+func (c *curve25519) ValidateECDH(point []byte, secret []byte) (err error) {
+ var pk, sk x25519lib.Key
+ copy(sk[:], secret)
+ x25519lib.KeyGen(&pk, &sk)
+
+ if subtle.ConstantTimeCompare(point, pk[:]) == 0 {
+ return errors.KeyInvalidError("ecc: invalid curve25519 public point")
+ }
+
+ return nil
+}
+
+func copyReversed(out []byte, in []byte) {
+ l := len(in)
+ for i := 0; i < l; i++ {
+ out[i] = in[l-i-1]
+ }
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go
new file mode 100644
index 00000000..35751034
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go
@@ -0,0 +1,140 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "bytes"
+ "crypto/elliptic"
+ "github.com/ProtonMail/go-crypto/bitcurves"
+ "github.com/ProtonMail/go-crypto/brainpool"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+)
+
+type CurveInfo struct {
+ GenName string
+ Oid *encoding.OID
+ Curve Curve
+}
+
+var Curves = []CurveInfo{
+ {
+ // NIST P-256
+ GenName: "P256",
+ Oid: encoding.NewOID([]byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}),
+ Curve: NewGenericCurve(elliptic.P256()),
+ },
+ {
+ // NIST P-384
+ GenName: "P384",
+ Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x22}),
+ Curve: NewGenericCurve(elliptic.P384()),
+ },
+ {
+ // NIST P-521
+ GenName: "P521",
+ Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x23}),
+ Curve: NewGenericCurve(elliptic.P521()),
+ },
+ {
+ // SecP256k1
+ GenName: "SecP256k1",
+ Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x0A}),
+ Curve: NewGenericCurve(bitcurves.S256()),
+ },
+ {
+ // Curve25519
+ GenName: "Curve25519",
+ Oid: encoding.NewOID([]byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01}),
+ Curve: NewCurve25519(),
+ },
+ {
+ // X448
+ GenName: "Curve448",
+ Oid: encoding.NewOID([]byte{0x2B, 0x65, 0x6F}),
+ Curve: NewX448(),
+ },
+ {
+ // Ed25519
+ GenName: "Curve25519",
+ Oid: encoding.NewOID([]byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01}),
+ Curve: NewEd25519(),
+ },
+ {
+ // Ed448
+ GenName: "Curve448",
+ Oid: encoding.NewOID([]byte{0x2B, 0x65, 0x71}),
+ Curve: NewEd448(),
+ },
+ {
+ // BrainpoolP256r1
+ GenName: "BrainpoolP256",
+ Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07}),
+ Curve: NewGenericCurve(brainpool.P256r1()),
+ },
+ {
+ // BrainpoolP384r1
+ GenName: "BrainpoolP384",
+ Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B}),
+ Curve: NewGenericCurve(brainpool.P384r1()),
+ },
+ {
+ // BrainpoolP512r1
+ GenName: "BrainpoolP512",
+ Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D}),
+ Curve: NewGenericCurve(brainpool.P512r1()),
+ },
+}
+
+func FindByCurve(curve Curve) *CurveInfo {
+ for _, curveInfo := range Curves {
+ if curveInfo.Curve.GetCurveName() == curve.GetCurveName() {
+ return &curveInfo
+ }
+ }
+ return nil
+}
+
+func FindByOid(oid encoding.Field) *CurveInfo {
+ var rawBytes = oid.Bytes()
+ for _, curveInfo := range Curves {
+ if bytes.Equal(curveInfo.Oid.Bytes(), rawBytes) {
+ return &curveInfo
+ }
+ }
+ return nil
+}
+
+func FindEdDSAByGenName(curveGenName string) EdDSACurve {
+ for _, curveInfo := range Curves {
+ if curveInfo.GenName == curveGenName {
+ curve, ok := curveInfo.Curve.(EdDSACurve)
+ if ok {
+ return curve
+ }
+ }
+ }
+ return nil
+}
+
+func FindECDSAByGenName(curveGenName string) ECDSACurve {
+ for _, curveInfo := range Curves {
+ if curveInfo.GenName == curveGenName {
+ curve, ok := curveInfo.Curve.(ECDSACurve)
+ if ok {
+ return curve
+ }
+ }
+ }
+ return nil
+}
+
+func FindECDHByGenName(curveGenName string) ECDHCurve {
+ for _, curveInfo := range Curves {
+ if curveInfo.GenName == curveGenName {
+ curve, ok := curveInfo.Curve.(ECDHCurve)
+ if ok {
+ return curve
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go
new file mode 100644
index 00000000..5ed9c93b
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go
@@ -0,0 +1,48 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "io"
+ "math/big"
+)
+
+type Curve interface {
+ GetCurveName() string
+}
+
+type ECDSACurve interface {
+ Curve
+ MarshalIntegerPoint(x, y *big.Int) []byte
+ UnmarshalIntegerPoint([]byte) (x, y *big.Int)
+ MarshalIntegerSecret(d *big.Int) []byte
+ UnmarshalIntegerSecret(d []byte) *big.Int
+ GenerateECDSA(rand io.Reader) (x, y, secret *big.Int, err error)
+ Sign(rand io.Reader, x, y, d *big.Int, hash []byte) (r, s *big.Int, err error)
+ Verify(x, y *big.Int, hash []byte, r, s *big.Int) bool
+ ValidateECDSA(x, y *big.Int, secret []byte) error
+}
+
+type EdDSACurve interface {
+ Curve
+ MarshalBytePoint(x []byte) []byte
+ UnmarshalBytePoint([]byte) (x []byte)
+ MarshalByteSecret(d []byte) []byte
+ UnmarshalByteSecret(d []byte) []byte
+ MarshalSignature(sig []byte) (r, s []byte)
+ UnmarshalSignature(r, s []byte) (sig []byte)
+ GenerateEdDSA(rand io.Reader) (pub, priv []byte, err error)
+ Sign(publicKey, privateKey, message []byte) (sig []byte, err error)
+ Verify(publicKey, message, sig []byte) bool
+ ValidateEdDSA(publicKey, privateKey []byte) (err error)
+}
+type ECDHCurve interface {
+ Curve
+ MarshalBytePoint([]byte) (encoded []byte)
+ UnmarshalBytePoint(encoded []byte) []byte
+ MarshalByteSecret(d []byte) []byte
+ UnmarshalByteSecret(d []byte) []byte
+ GenerateECDH(rand io.Reader) (point []byte, secret []byte, err error)
+ Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error)
+ Decaps(ephemeral, secret []byte) (sharedSecret []byte, err error)
+ ValidateECDH(public []byte, secret []byte) error
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go
new file mode 100644
index 00000000..54a08a8a
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go
@@ -0,0 +1,112 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/subtle"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ ed25519lib "github.com/cloudflare/circl/sign/ed25519"
+)
+
+const ed25519Size = 32
+
+type ed25519 struct{}
+
+func NewEd25519() *ed25519 {
+ return &ed25519{}
+}
+
+func (c *ed25519) GetCurveName() string {
+ return "ed25519"
+}
+
+// MarshalBytePoint encodes the public point from native format, adding the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed25519) MarshalBytePoint(x []byte) []byte {
+ return append([]byte{0x40}, x...)
+}
+
+// UnmarshalBytePoint decodes a point from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed25519) UnmarshalBytePoint(point []byte) (x []byte) {
+ if len(point) != ed25519lib.PublicKeySize+1 {
+ return nil
+ }
+
+ // Return unprefixed
+ return point[1:]
+}
+
+// MarshalByteSecret encodes a scalar in native format.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed25519) MarshalByteSecret(d []byte) []byte {
+ return d
+}
+
+// UnmarshalByteSecret decodes a scalar in native format and re-adds the stripped leading zeroes
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed25519) UnmarshalByteSecret(s []byte) (d []byte) {
+ if len(s) > ed25519lib.SeedSize {
+ return nil
+ }
+
+ // Handle stripped leading zeroes
+ d = make([]byte, ed25519lib.SeedSize)
+ copy(d[ed25519lib.SeedSize-len(s):], s)
+ return
+}
+
+// MarshalSignature splits a signature in R and S.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.2.3.3.1
+func (c *ed25519) MarshalSignature(sig []byte) (r, s []byte) {
+ return sig[:ed25519Size], sig[ed25519Size:]
+}
+
+// UnmarshalSignature decodes R and S in the native format, re-adding the stripped leading zeroes
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.2.3.3.1
+func (c *ed25519) UnmarshalSignature(r, s []byte) (sig []byte) {
+ // Check size
+ if len(r) > 32 || len(s) > 32 {
+ return nil
+ }
+
+ sig = make([]byte, ed25519lib.SignatureSize)
+
+ // Handle stripped leading zeroes
+ copy(sig[ed25519Size-len(r):ed25519Size], r)
+ copy(sig[ed25519lib.SignatureSize-len(s):], s)
+ return sig
+}
+
+func (c *ed25519) GenerateEdDSA(rand io.Reader) (pub, priv []byte, err error) {
+ pk, sk, err := ed25519lib.GenerateKey(rand)
+
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return pk, sk[:ed25519lib.SeedSize], nil
+}
+
+func getEd25519Sk(publicKey, privateKey []byte) ed25519lib.PrivateKey {
+ return append(privateKey, publicKey...)
+}
+
+func (c *ed25519) Sign(publicKey, privateKey, message []byte) (sig []byte, err error) {
+ sig = ed25519lib.Sign(getEd25519Sk(publicKey, privateKey), message)
+ return sig, nil
+}
+
+func (c *ed25519) Verify(publicKey, message, sig []byte) bool {
+ return ed25519lib.Verify(publicKey, message, sig)
+}
+
+func (c *ed25519) ValidateEdDSA(publicKey, privateKey []byte) (err error) {
+ priv := getEd25519Sk(publicKey, privateKey)
+ expectedPriv := ed25519lib.NewKeyFromSeed(priv.Seed())
+ if subtle.ConstantTimeCompare(priv, expectedPriv) == 0 {
+ return errors.KeyInvalidError("ecc: invalid ed25519 secret")
+ }
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go
new file mode 100644
index 00000000..18cd8043
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go
@@ -0,0 +1,111 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/subtle"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ ed448lib "github.com/cloudflare/circl/sign/ed448"
+)
+
+type ed448 struct{}
+
+func NewEd448() *ed448 {
+ return &ed448{}
+}
+
+func (c *ed448) GetCurveName() string {
+ return "ed448"
+}
+
+// MarshalBytePoint encodes the public point from native format, adding the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed448) MarshalBytePoint(x []byte) []byte {
+ // Return prefixed
+ return append([]byte{0x40}, x...)
+}
+
+// UnmarshalBytePoint decodes a point from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed448) UnmarshalBytePoint(point []byte) (x []byte) {
+ if len(point) != ed448lib.PublicKeySize+1 {
+ return nil
+ }
+
+ // Strip prefix
+ return point[1:]
+}
+
+// MarshalByteSecret encoded a scalar from native format to prefixed.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed448) MarshalByteSecret(d []byte) []byte {
+ // Return prefixed
+ return append([]byte{0x40}, d...)
+}
+
+// UnmarshalByteSecret decodes a scalar from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed448) UnmarshalByteSecret(s []byte) (d []byte) {
+ // Check prefixed size
+ if len(s) != ed448lib.SeedSize+1 {
+ return nil
+ }
+
+ // Strip prefix
+ return s[1:]
+}
+
+// MarshalSignature splits a signature in R and S, where R is in prefixed native format and
+// S is an MPI with value zero.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.2.3.3.2
+func (c *ed448) MarshalSignature(sig []byte) (r, s []byte) {
+ return append([]byte{0x40}, sig...), []byte{}
+}
+
+// UnmarshalSignature decodes R and S in the native format. Only R is used, in prefixed native format.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.2.3.3.2
+func (c *ed448) UnmarshalSignature(r, s []byte) (sig []byte) {
+ if len(r) != ed448lib.SignatureSize+1 {
+ return nil
+ }
+
+ return r[1:]
+}
+
+func (c *ed448) GenerateEdDSA(rand io.Reader) (pub, priv []byte, err error) {
+ pk, sk, err := ed448lib.GenerateKey(rand)
+
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return pk, sk[:ed448lib.SeedSize], nil
+}
+
+func getEd448Sk(publicKey, privateKey []byte) ed448lib.PrivateKey {
+ return append(privateKey, publicKey...)
+}
+
+func (c *ed448) Sign(publicKey, privateKey, message []byte) (sig []byte, err error) {
+ // Ed448 is used with the empty string as a context string.
+ // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-13.7
+ sig = ed448lib.Sign(getEd448Sk(publicKey, privateKey), message, "")
+
+ return sig, nil
+}
+
+func (c *ed448) Verify(publicKey, message, sig []byte) bool {
+ // Ed448 is used with the empty string as a context string.
+ // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-13.7
+ return ed448lib.Verify(publicKey, message, sig, "")
+}
+
+func (c *ed448) ValidateEdDSA(publicKey, privateKey []byte) (err error) {
+ priv := getEd448Sk(publicKey, privateKey)
+ expectedPriv := ed448lib.NewKeyFromSeed(priv.Seed())
+ if subtle.ConstantTimeCompare(priv, expectedPriv) == 0 {
+ return errors.KeyInvalidError("ecc: invalid ed448 secret")
+ }
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/generic.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/generic.go
new file mode 100644
index 00000000..e28d7c71
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/generic.go
@@ -0,0 +1,149 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "fmt"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "io"
+ "math/big"
+)
+
+type genericCurve struct {
+ Curve elliptic.Curve
+}
+
+func NewGenericCurve(c elliptic.Curve) *genericCurve {
+ return &genericCurve{
+ Curve: c,
+ }
+}
+
+func (c *genericCurve) GetCurveName() string {
+ return c.Curve.Params().Name
+}
+
+func (c *genericCurve) MarshalBytePoint(point []byte) []byte {
+ return point
+}
+
+func (c *genericCurve) UnmarshalBytePoint(point []byte) []byte {
+ return point
+}
+
+func (c *genericCurve) MarshalIntegerPoint(x, y *big.Int) []byte {
+ return elliptic.Marshal(c.Curve, x, y)
+}
+
+func (c *genericCurve) UnmarshalIntegerPoint(point []byte) (x, y *big.Int) {
+ return elliptic.Unmarshal(c.Curve, point)
+}
+
+func (c *genericCurve) MarshalByteSecret(d []byte) []byte {
+ return d
+}
+
+func (c *genericCurve) UnmarshalByteSecret(d []byte) []byte {
+ return d
+}
+
+func (c *genericCurve) MarshalIntegerSecret(d *big.Int) []byte {
+ return d.Bytes()
+}
+
+func (c *genericCurve) UnmarshalIntegerSecret(d []byte) *big.Int {
+ return new(big.Int).SetBytes(d)
+}
+
+func (c *genericCurve) GenerateECDH(rand io.Reader) (point, secret []byte, err error) {
+ secret, x, y, err := elliptic.GenerateKey(c.Curve, rand)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ point = elliptic.Marshal(c.Curve, x, y)
+ return point, secret, nil
+}
+
+func (c *genericCurve) GenerateECDSA(rand io.Reader) (x, y, secret *big.Int, err error) {
+ priv, err := ecdsa.GenerateKey(c.Curve, rand)
+ if err != nil {
+ return
+ }
+
+ return priv.X, priv.Y, priv.D, nil
+}
+
+func (c *genericCurve) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) {
+ xP, yP := elliptic.Unmarshal(c.Curve, point)
+ if xP == nil {
+ panic("invalid point")
+ }
+
+ d, x, y, err := elliptic.GenerateKey(c.Curve, rand)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ vsG := elliptic.Marshal(c.Curve, x, y)
+ zbBig, _ := c.Curve.ScalarMult(xP, yP, d)
+
+ byteLen := (c.Curve.Params().BitSize + 7) >> 3
+ zb := make([]byte, byteLen)
+ zbBytes := zbBig.Bytes()
+ copy(zb[byteLen-len(zbBytes):], zbBytes)
+
+ return vsG, zb, nil
+}
+
+func (c *genericCurve) Decaps(ephemeral, secret []byte) (sharedSecret []byte, err error) {
+ x, y := elliptic.Unmarshal(c.Curve, ephemeral)
+ zbBig, _ := c.Curve.ScalarMult(x, y, secret)
+ byteLen := (c.Curve.Params().BitSize + 7) >> 3
+ zb := make([]byte, byteLen)
+ zbBytes := zbBig.Bytes()
+ copy(zb[byteLen-len(zbBytes):], zbBytes)
+
+ return zb, nil
+}
+
+func (c *genericCurve) Sign(rand io.Reader, x, y, d *big.Int, hash []byte) (r, s *big.Int, err error) {
+ priv := &ecdsa.PrivateKey{D: d, PublicKey: ecdsa.PublicKey{X: x, Y: y, Curve: c.Curve}}
+ return ecdsa.Sign(rand, priv, hash)
+}
+
+func (c *genericCurve) Verify(x, y *big.Int, hash []byte, r, s *big.Int) bool {
+ pub := &ecdsa.PublicKey{X: x, Y: y, Curve: c.Curve}
+ return ecdsa.Verify(pub, hash, r, s)
+}
+
+func (c *genericCurve) validate(xP, yP *big.Int, secret []byte) error {
+ // the public point should not be at infinity (0,0)
+ zero := new(big.Int)
+ if xP.Cmp(zero) == 0 && yP.Cmp(zero) == 0 {
+ return errors.KeyInvalidError(fmt.Sprintf("ecc (%s): infinity point", c.Curve.Params().Name))
+ }
+
+ // re-derive the public point Q' = (X,Y) = dG
+ // to compare to declared Q in public key
+ expectedX, expectedY := c.Curve.ScalarBaseMult(secret)
+ if xP.Cmp(expectedX) != 0 || yP.Cmp(expectedY) != 0 {
+ return errors.KeyInvalidError(fmt.Sprintf("ecc (%s): invalid point", c.Curve.Params().Name))
+ }
+
+ return nil
+}
+
+func (c *genericCurve) ValidateECDSA(xP, yP *big.Int, secret []byte) error {
+ return c.validate(xP, yP, secret)
+}
+
+func (c *genericCurve) ValidateECDH(point []byte, secret []byte) error {
+ xP, yP := elliptic.Unmarshal(c.Curve, point)
+ if xP == nil {
+ return errors.KeyInvalidError(fmt.Sprintf("ecc (%s): invalid point", c.Curve.Params().Name))
+ }
+
+ return c.validate(xP, yP, secret)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go
new file mode 100644
index 00000000..df04262e
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go
@@ -0,0 +1,107 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/subtle"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ x448lib "github.com/cloudflare/circl/dh/x448"
+)
+
+type x448 struct{}
+
+func NewX448() *x448 {
+ return &x448{}
+}
+
+func (c *x448) GetCurveName() string {
+ return "x448"
+}
+
+// MarshalBytePoint encodes the public point from native format, adding the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6
+func (c *x448) MarshalBytePoint(point []byte) []byte {
+ return append([]byte{0x40}, point...)
+}
+
+// UnmarshalBytePoint decodes a point from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6
+func (c *x448) UnmarshalBytePoint(point []byte) []byte {
+ if len(point) != x448lib.Size+1 {
+ return nil
+ }
+
+ return point[1:]
+}
+
+// MarshalByteSecret encoded a scalar from native format to prefixed.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6.1.2
+func (c *x448) MarshalByteSecret(d []byte) []byte {
+ return append([]byte{0x40}, d...)
+}
+
+// UnmarshalByteSecret decodes a scalar from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6.1.2
+func (c *x448) UnmarshalByteSecret(d []byte) []byte {
+ if len(d) != x448lib.Size+1 {
+ return nil
+ }
+
+ // Store without prefix
+ return d[1:]
+}
+
+func (c *x448) generateKeyPairBytes(rand io.Reader) (sk, pk x448lib.Key, err error) {
+ if _, err = rand.Read(sk[:]); err != nil {
+ return
+ }
+
+ x448lib.KeyGen(&pk, &sk)
+ return
+}
+
+func (c *x448) GenerateECDH(rand io.Reader) (point []byte, secret []byte, err error) {
+ priv, pub, err := c.generateKeyPairBytes(rand)
+ if err != nil {
+ return
+ }
+
+ return pub[:], priv[:], nil
+}
+
+func (c *x448) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) {
+ var pk, ss x448lib.Key
+ seed, e, err := c.generateKeyPairBytes(rand)
+ if err != nil {
+ return nil, nil, err
+ }
+ copy(pk[:], point)
+ x448lib.Shared(&ss, &seed, &pk)
+
+ return e[:], ss[:], nil
+}
+
+func (c *x448) Decaps(ephemeral, secret []byte) (sharedSecret []byte, err error) {
+ var ss, sk, e x448lib.Key
+
+ copy(sk[:], secret)
+ copy(e[:], ephemeral)
+ x448lib.Shared(&ss, &sk, &e)
+
+ return ss[:], nil
+}
+
+func (c *x448) ValidateECDH(point []byte, secret []byte) error {
+ var sk, pk, expectedPk x448lib.Key
+
+ copy(pk[:], point)
+ copy(sk[:], secret)
+ x448lib.KeyGen(&expectedPk, &sk)
+
+ if subtle.ConstantTimeCompare(expectedPk[:], pk[:]) == 0 {
+ return errors.KeyInvalidError("ecc: invalid curve25519 public point")
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/encoding.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/encoding.go
new file mode 100644
index 00000000..6c921481
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/encoding.go
@@ -0,0 +1,27 @@
+// 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 encoding implements openpgp packet field encodings as specified in
+// RFC 4880 and 6637.
+package encoding
+
+import "io"
+
+// Field is an encoded field of an openpgp packet.
+type Field interface {
+ // Bytes returns the decoded data.
+ Bytes() []byte
+
+ // BitLength is the size in bits of the decoded data.
+ BitLength() uint16
+
+ // EncodedBytes returns the encoded data.
+ EncodedBytes() []byte
+
+ // EncodedLength is the size in bytes of the encoded data.
+ EncodedLength() uint16
+
+ // ReadFrom reads the next Field from r.
+ ReadFrom(r io.Reader) (int64, error)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/mpi.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/mpi.go
new file mode 100644
index 00000000..02e5e695
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/mpi.go
@@ -0,0 +1,91 @@
+// 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 encoding
+
+import (
+ "io"
+ "math/big"
+ "math/bits"
+)
+
+// An MPI is used to store the contents of a big integer, along with the bit
+// length that was specified in the original input. This allows the MPI to be
+// reserialized exactly.
+type MPI struct {
+ bytes []byte
+ bitLength uint16
+}
+
+// NewMPI returns a MPI initialized with bytes.
+func NewMPI(bytes []byte) *MPI {
+ for len(bytes) != 0 && bytes[0] == 0 {
+ bytes = bytes[1:]
+ }
+ if len(bytes) == 0 {
+ bitLength := uint16(0)
+ return &MPI{bytes, bitLength}
+ }
+ bitLength := 8*uint16(len(bytes)-1) + uint16(bits.Len8(bytes[0]))
+ return &MPI{bytes, bitLength}
+}
+
+// Bytes returns the decoded data.
+func (m *MPI) Bytes() []byte {
+ return m.bytes
+}
+
+// BitLength is the size in bits of the decoded data.
+func (m *MPI) BitLength() uint16 {
+ return m.bitLength
+}
+
+// EncodedBytes returns the encoded data.
+func (m *MPI) EncodedBytes() []byte {
+ return append([]byte{byte(m.bitLength >> 8), byte(m.bitLength)}, m.bytes...)
+}
+
+// EncodedLength is the size in bytes of the encoded data.
+func (m *MPI) EncodedLength() uint16 {
+ return uint16(2 + len(m.bytes))
+}
+
+// ReadFrom reads into m the next MPI from r.
+func (m *MPI) ReadFrom(r io.Reader) (int64, error) {
+ var buf [2]byte
+ n, err := io.ReadFull(r, buf[0:])
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return int64(n), err
+ }
+
+ m.bitLength = uint16(buf[0])<<8 | uint16(buf[1])
+ m.bytes = make([]byte, (int(m.bitLength)+7)/8)
+
+ nn, err := io.ReadFull(r, m.bytes)
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+
+ // remove leading zero bytes from malformed GnuPG encoded MPIs:
+ // https://bugs.gnupg.org/gnupg/issue1853
+ // for _, b := range m.bytes {
+ // if b != 0 {
+ // break
+ // }
+ // m.bytes = m.bytes[1:]
+ // m.bitLength -= 8
+ // }
+
+ return int64(n) + int64(nn), err
+}
+
+// SetBig initializes m with the bits from n.
+func (m *MPI) SetBig(n *big.Int) *MPI {
+ m.bytes = n.Bytes()
+ m.bitLength = uint16(n.BitLen())
+ return m
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/oid.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/oid.go
new file mode 100644
index 00000000..c9df9fe2
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/oid.go
@@ -0,0 +1,88 @@
+// 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 encoding
+
+import (
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// OID is used to store a variable-length field with a one-octet size
+// prefix. See https://tools.ietf.org/html/rfc6637#section-9.
+type OID struct {
+ bytes []byte
+}
+
+const (
+ // maxOID is the maximum number of bytes in a OID.
+ maxOID = 254
+ // reservedOIDLength1 and reservedOIDLength2 are OID lengths that the RFC
+ // specifies are reserved.
+ reservedOIDLength1 = 0
+ reservedOIDLength2 = 0xff
+)
+
+// NewOID returns a OID initialized with bytes.
+func NewOID(bytes []byte) *OID {
+ switch len(bytes) {
+ case reservedOIDLength1, reservedOIDLength2:
+ panic("encoding: NewOID argument length is reserved")
+ default:
+ if len(bytes) > maxOID {
+ panic("encoding: NewOID argument too large")
+ }
+ }
+
+ return &OID{
+ bytes: bytes,
+ }
+}
+
+// Bytes returns the decoded data.
+func (o *OID) Bytes() []byte {
+ return o.bytes
+}
+
+// BitLength is the size in bits of the decoded data.
+func (o *OID) BitLength() uint16 {
+ return uint16(len(o.bytes) * 8)
+}
+
+// EncodedBytes returns the encoded data.
+func (o *OID) EncodedBytes() []byte {
+ return append([]byte{byte(len(o.bytes))}, o.bytes...)
+}
+
+// EncodedLength is the size in bytes of the encoded data.
+func (o *OID) EncodedLength() uint16 {
+ return uint16(1 + len(o.bytes))
+}
+
+// ReadFrom reads into b the next OID from r.
+func (o *OID) ReadFrom(r io.Reader) (int64, error) {
+ var buf [1]byte
+ n, err := io.ReadFull(r, buf[:])
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return int64(n), err
+ }
+
+ switch buf[0] {
+ case reservedOIDLength1, reservedOIDLength2:
+ return int64(n), errors.UnsupportedError("reserved for future extensions")
+ }
+
+ o.bytes = make([]byte, buf[0])
+
+ nn, err := io.ReadFull(r, o.bytes)
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+
+ return int64(n) + int64(nn), err
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go
new file mode 100644
index 00000000..0e71934c
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go
@@ -0,0 +1,389 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openpgp
+
+import (
+ "crypto"
+ "crypto/rand"
+ "crypto/rsa"
+ goerrors "errors"
+ "io"
+ "math/big"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdh"
+ "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
+ "github.com/ProtonMail/go-crypto/openpgp/eddsa"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+)
+
+// NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
+// single identity composed of the given full name, comment and email, any of
+// which may be empty but must not contain any of "()<>\x00".
+// If config is nil, sensible defaults will be used.
+func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
+ creationTime := config.Now()
+ keyLifetimeSecs := config.KeyLifetime()
+
+ // Generate a primary signing key
+ primaryPrivRaw, err := newSigner(config)
+ if err != nil {
+ return nil, err
+ }
+ primary := packet.NewSignerPrivateKey(creationTime, primaryPrivRaw)
+ if config != nil && config.V5Keys {
+ primary.UpgradeToV5()
+ }
+
+ e := &Entity{
+ PrimaryKey: &primary.PublicKey,
+ PrivateKey: primary,
+ Identities: make(map[string]*Identity),
+ Subkeys: []Subkey{},
+ }
+
+ err = e.addUserId(name, comment, email, config, creationTime, keyLifetimeSecs)
+ if err != nil {
+ return nil, err
+ }
+
+ // NOTE: No key expiry here, but we will not return this subkey in EncryptionKey()
+ // if the primary/master key has expired.
+ err = e.addEncryptionSubkey(config, creationTime, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ return e, nil
+}
+
+func (t *Entity) AddUserId(name, comment, email string, config *packet.Config) error {
+ creationTime := config.Now()
+ keyLifetimeSecs := config.KeyLifetime()
+ return t.addUserId(name, comment, email, config, creationTime, keyLifetimeSecs)
+}
+
+func (t *Entity) addUserId(name, comment, email string, config *packet.Config, creationTime time.Time, keyLifetimeSecs uint32) error {
+ uid := packet.NewUserId(name, comment, email)
+ if uid == nil {
+ return errors.InvalidArgumentError("user id field contained invalid characters")
+ }
+
+ if _, ok := t.Identities[uid.Id]; ok {
+ return errors.InvalidArgumentError("user id exist")
+ }
+
+ primary := t.PrivateKey
+
+ isPrimaryId := len(t.Identities) == 0
+
+ selfSignature := createSignaturePacket(&primary.PublicKey, packet.SigTypePositiveCert, config)
+ selfSignature.CreationTime = creationTime
+ selfSignature.KeyLifetimeSecs = &keyLifetimeSecs
+ selfSignature.IsPrimaryId = &isPrimaryId
+ selfSignature.FlagsValid = true
+ selfSignature.FlagSign = true
+ selfSignature.FlagCertify = true
+ selfSignature.SEIPDv1 = true // true by default, see 5.8 vs. 5.14
+ selfSignature.SEIPDv2 = config.AEAD() != nil
+
+ // Set the PreferredHash for the SelfSignature from the packet.Config.
+ // If it is not the must-implement algorithm from rfc4880bis, append that.
+ hash, ok := algorithm.HashToHashId(config.Hash())
+ if !ok {
+ return errors.UnsupportedError("unsupported preferred hash function")
+ }
+
+ selfSignature.PreferredHash = []uint8{hash}
+ if config.Hash() != crypto.SHA256 {
+ selfSignature.PreferredHash = append(selfSignature.PreferredHash, hashToHashId(crypto.SHA256))
+ }
+
+ // Likewise for DefaultCipher.
+ selfSignature.PreferredSymmetric = []uint8{uint8(config.Cipher())}
+ if config.Cipher() != packet.CipherAES128 {
+ selfSignature.PreferredSymmetric = append(selfSignature.PreferredSymmetric, uint8(packet.CipherAES128))
+ }
+
+ // We set CompressionNone as the preferred compression algorithm because
+ // of compression side channel attacks, then append the configured
+ // DefaultCompressionAlgo if any is set (to signal support for cases
+ // where the application knows that using compression is safe).
+ selfSignature.PreferredCompression = []uint8{uint8(packet.CompressionNone)}
+ if config.Compression() != packet.CompressionNone {
+ selfSignature.PreferredCompression = append(selfSignature.PreferredCompression, uint8(config.Compression()))
+ }
+
+ // And for DefaultMode.
+ modes := []uint8{uint8(config.AEAD().Mode())}
+ if config.AEAD().Mode() != packet.AEADModeOCB {
+ modes = append(modes, uint8(packet.AEADModeOCB))
+ }
+
+ // For preferred (AES256, GCM), we'll generate (AES256, GCM), (AES256, OCB), (AES128, GCM), (AES128, OCB)
+ for _, cipher := range selfSignature.PreferredSymmetric {
+ for _, mode := range modes {
+ selfSignature.PreferredCipherSuites = append(selfSignature.PreferredCipherSuites, [2]uint8{cipher, mode})
+ }
+ }
+
+ // User ID binding signature
+ err := selfSignature.SignUserId(uid.Id, &primary.PublicKey, primary, config)
+ if err != nil {
+ return err
+ }
+ t.Identities[uid.Id] = &Identity{
+ Name: uid.Id,
+ UserId: uid,
+ SelfSignature: selfSignature,
+ Signatures: []*packet.Signature{selfSignature},
+ }
+ return nil
+}
+
+// AddSigningSubkey adds a signing keypair as a subkey to the Entity.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) AddSigningSubkey(config *packet.Config) error {
+ creationTime := config.Now()
+ keyLifetimeSecs := config.KeyLifetime()
+
+ subPrivRaw, err := newSigner(config)
+ if err != nil {
+ return err
+ }
+ sub := packet.NewSignerPrivateKey(creationTime, subPrivRaw)
+ sub.IsSubkey = true
+ if config != nil && config.V5Keys {
+ sub.UpgradeToV5()
+ }
+
+ subkey := Subkey{
+ PublicKey: &sub.PublicKey,
+ PrivateKey: sub,
+ }
+ subkey.Sig = createSignaturePacket(e.PrimaryKey, packet.SigTypeSubkeyBinding, config)
+ subkey.Sig.CreationTime = creationTime
+ subkey.Sig.KeyLifetimeSecs = &keyLifetimeSecs
+ subkey.Sig.FlagsValid = true
+ subkey.Sig.FlagSign = true
+ subkey.Sig.EmbeddedSignature = createSignaturePacket(subkey.PublicKey, packet.SigTypePrimaryKeyBinding, config)
+ subkey.Sig.EmbeddedSignature.CreationTime = creationTime
+
+ err = subkey.Sig.EmbeddedSignature.CrossSignKey(subkey.PublicKey, e.PrimaryKey, subkey.PrivateKey, config)
+ if err != nil {
+ return err
+ }
+
+ err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
+ if err != nil {
+ return err
+ }
+
+ e.Subkeys = append(e.Subkeys, subkey)
+ return nil
+}
+
+// AddEncryptionSubkey adds an encryption keypair as a subkey to the Entity.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) AddEncryptionSubkey(config *packet.Config) error {
+ creationTime := config.Now()
+ keyLifetimeSecs := config.KeyLifetime()
+ return e.addEncryptionSubkey(config, creationTime, keyLifetimeSecs)
+}
+
+func (e *Entity) addEncryptionSubkey(config *packet.Config, creationTime time.Time, keyLifetimeSecs uint32) error {
+ subPrivRaw, err := newDecrypter(config)
+ if err != nil {
+ return err
+ }
+ sub := packet.NewDecrypterPrivateKey(creationTime, subPrivRaw)
+ sub.IsSubkey = true
+ if config != nil && config.V5Keys {
+ sub.UpgradeToV5()
+ }
+
+ subkey := Subkey{
+ PublicKey: &sub.PublicKey,
+ PrivateKey: sub,
+ }
+ subkey.Sig = createSignaturePacket(e.PrimaryKey, packet.SigTypeSubkeyBinding, config)
+ subkey.Sig.CreationTime = creationTime
+ subkey.Sig.KeyLifetimeSecs = &keyLifetimeSecs
+ subkey.Sig.FlagsValid = true
+ subkey.Sig.FlagEncryptStorage = true
+ subkey.Sig.FlagEncryptCommunications = true
+
+ err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
+ if err != nil {
+ return err
+ }
+
+ e.Subkeys = append(e.Subkeys, subkey)
+ return nil
+}
+
+// Generates a signing key
+func newSigner(config *packet.Config) (signer interface{}, err error) {
+ switch config.PublicKeyAlgorithm() {
+ case packet.PubKeyAlgoRSA:
+ bits := config.RSAModulusBits()
+ if bits < 1024 {
+ return nil, errors.InvalidArgumentError("bits must be >= 1024")
+ }
+ if config != nil && len(config.RSAPrimes) >= 2 {
+ primes := config.RSAPrimes[0:2]
+ config.RSAPrimes = config.RSAPrimes[2:]
+ return generateRSAKeyWithPrimes(config.Random(), 2, bits, primes)
+ }
+ return rsa.GenerateKey(config.Random(), bits)
+ case packet.PubKeyAlgoEdDSA:
+ curve := ecc.FindEdDSAByGenName(string(config.CurveName()))
+ if curve == nil {
+ return nil, errors.InvalidArgumentError("unsupported curve")
+ }
+
+ priv, err := eddsa.GenerateKey(config.Random(), curve)
+ if err != nil {
+ return nil, err
+ }
+ return priv, nil
+ case packet.PubKeyAlgoECDSA:
+ curve := ecc.FindECDSAByGenName(string(config.CurveName()))
+ if curve == nil {
+ return nil, errors.InvalidArgumentError("unsupported curve")
+ }
+
+ priv, err := ecdsa.GenerateKey(config.Random(), curve)
+ if err != nil {
+ return nil, err
+ }
+ return priv, nil
+ default:
+ return nil, errors.InvalidArgumentError("unsupported public key algorithm")
+ }
+}
+
+// Generates an encryption/decryption key
+func newDecrypter(config *packet.Config) (decrypter interface{}, err error) {
+ switch config.PublicKeyAlgorithm() {
+ case packet.PubKeyAlgoRSA:
+ bits := config.RSAModulusBits()
+ if bits < 1024 {
+ return nil, errors.InvalidArgumentError("bits must be >= 1024")
+ }
+ if config != nil && len(config.RSAPrimes) >= 2 {
+ primes := config.RSAPrimes[0:2]
+ config.RSAPrimes = config.RSAPrimes[2:]
+ return generateRSAKeyWithPrimes(config.Random(), 2, bits, primes)
+ }
+ return rsa.GenerateKey(config.Random(), bits)
+ case packet.PubKeyAlgoEdDSA, packet.PubKeyAlgoECDSA:
+ fallthrough // When passing EdDSA or ECDSA, we generate an ECDH subkey
+ case packet.PubKeyAlgoECDH:
+ var kdf = ecdh.KDF{
+ Hash: algorithm.SHA512,
+ Cipher: algorithm.AES256,
+ }
+ curve := ecc.FindECDHByGenName(string(config.CurveName()))
+ if curve == nil {
+ return nil, errors.InvalidArgumentError("unsupported curve")
+ }
+ return ecdh.GenerateKey(config.Random(), curve, kdf)
+ default:
+ return nil, errors.InvalidArgumentError("unsupported public key algorithm")
+ }
+}
+
+var bigOne = big.NewInt(1)
+
+// generateRSAKeyWithPrimes generates a multi-prime RSA keypair of the
+// given bit size, using the given random source and prepopulated primes.
+func generateRSAKeyWithPrimes(random io.Reader, nprimes int, bits int, prepopulatedPrimes []*big.Int) (*rsa.PrivateKey, error) {
+ priv := new(rsa.PrivateKey)
+ priv.E = 65537
+
+ if nprimes < 2 {
+ return nil, goerrors.New("generateRSAKeyWithPrimes: nprimes must be >= 2")
+ }
+
+ if bits < 1024 {
+ return nil, goerrors.New("generateRSAKeyWithPrimes: bits must be >= 1024")
+ }
+
+ primes := make([]*big.Int, nprimes)
+
+NextSetOfPrimes:
+ for {
+ todo := bits
+ // crypto/rand should set the top two bits in each prime.
+ // Thus each prime has the form
+ // p_i = 2^bitlen(p_i) × 0.11... (in base 2).
+ // And the product is:
+ // P = 2^todo × α
+ // where α is the product of nprimes numbers of the form 0.11...
+ //
+ // If α < 1/2 (which can happen for nprimes > 2), we need to
+ // shift todo to compensate for lost bits: the mean value of 0.11...
+ // is 7/8, so todo + shift - nprimes * log2(7/8) ~= bits - 1/2
+ // will give good results.
+ if nprimes >= 7 {
+ todo += (nprimes - 2) / 5
+ }
+ for i := 0; i < nprimes; i++ {
+ var err error
+ if len(prepopulatedPrimes) == 0 {
+ primes[i], err = rand.Prime(random, todo/(nprimes-i))
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ primes[i] = prepopulatedPrimes[0]
+ prepopulatedPrimes = prepopulatedPrimes[1:]
+ }
+
+ todo -= primes[i].BitLen()
+ }
+
+ // Make sure that primes is pairwise unequal.
+ for i, prime := range primes {
+ for j := 0; j < i; j++ {
+ if prime.Cmp(primes[j]) == 0 {
+ continue NextSetOfPrimes
+ }
+ }
+ }
+
+ n := new(big.Int).Set(bigOne)
+ totient := new(big.Int).Set(bigOne)
+ pminus1 := new(big.Int)
+ for _, prime := range primes {
+ n.Mul(n, prime)
+ pminus1.Sub(prime, bigOne)
+ totient.Mul(totient, pminus1)
+ }
+ if n.BitLen() != bits {
+ // This should never happen for nprimes == 2 because
+ // crypto/rand should set the top two bits in each prime.
+ // For nprimes > 2 we hope it does not happen often.
+ continue NextSetOfPrimes
+ }
+
+ priv.D = new(big.Int)
+ e := big.NewInt(int64(priv.E))
+ ok := priv.D.ModInverse(e, totient)
+
+ if ok != nil {
+ priv.Primes = primes
+ priv.N = n
+ break
+ }
+ }
+
+ priv.Precompute()
+ return priv, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go
new file mode 100644
index 00000000..2d7b0cf3
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go
@@ -0,0 +1,842 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openpgp
+
+import (
+ goerrors "errors"
+ "io"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/armor"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+)
+
+// PublicKeyType is the armor type for a PGP public key.
+var PublicKeyType = "PGP PUBLIC KEY BLOCK"
+
+// PrivateKeyType is the armor type for a PGP private key.
+var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
+
+// An Entity represents the components of an OpenPGP key: a primary public key
+// (which must be a signing key), one or more identities claimed by that key,
+// and zero or more subkeys, which may be encryption keys.
+type Entity struct {
+ PrimaryKey *packet.PublicKey
+ PrivateKey *packet.PrivateKey
+ Identities map[string]*Identity // indexed by Identity.Name
+ Revocations []*packet.Signature
+ Subkeys []Subkey
+}
+
+// An Identity represents an identity claimed by an Entity and zero or more
+// assertions by other entities about that claim.
+type Identity struct {
+ Name string // by convention, has the form "Full Name (comment) "
+ UserId *packet.UserId
+ SelfSignature *packet.Signature
+ Revocations []*packet.Signature
+ Signatures []*packet.Signature // all (potentially unverified) self-signatures, revocations, and third-party signatures
+}
+
+// A Subkey is an additional public key in an Entity. Subkeys can be used for
+// encryption.
+type Subkey struct {
+ PublicKey *packet.PublicKey
+ PrivateKey *packet.PrivateKey
+ Sig *packet.Signature
+ Revocations []*packet.Signature
+}
+
+// A Key identifies a specific public key in an Entity. This is either the
+// Entity's primary key or a subkey.
+type Key struct {
+ Entity *Entity
+ PublicKey *packet.PublicKey
+ PrivateKey *packet.PrivateKey
+ SelfSignature *packet.Signature
+ Revocations []*packet.Signature
+}
+
+// A KeyRing provides access to public and private keys.
+type KeyRing interface {
+ // KeysById returns the set of keys that have the given key id.
+ KeysById(id uint64) []Key
+ // KeysByIdAndUsage returns the set of keys with the given id
+ // that also meet the key usage given by requiredUsage.
+ // The requiredUsage is expressed as the bitwise-OR of
+ // packet.KeyFlag* values.
+ KeysByIdUsage(id uint64, requiredUsage byte) []Key
+ // DecryptionKeys returns all private keys that are valid for
+ // decryption.
+ DecryptionKeys() []Key
+}
+
+// PrimaryIdentity returns an Identity, preferring non-revoked identities,
+// identities marked as primary, or the latest-created identity, in that order.
+func (e *Entity) PrimaryIdentity() *Identity {
+ var primaryIdentity *Identity
+ for _, ident := range e.Identities {
+ if shouldPreferIdentity(primaryIdentity, ident) {
+ primaryIdentity = ident
+ }
+ }
+ return primaryIdentity
+}
+
+func shouldPreferIdentity(existingId, potentialNewId *Identity) bool {
+ if existingId == nil {
+ return true
+ }
+
+ if len(existingId.Revocations) > len(potentialNewId.Revocations) {
+ return true
+ }
+
+ if len(existingId.Revocations) < len(potentialNewId.Revocations) {
+ return false
+ }
+
+ if existingId.SelfSignature == nil {
+ return true
+ }
+
+ if existingId.SelfSignature.IsPrimaryId != nil && *existingId.SelfSignature.IsPrimaryId &&
+ !(potentialNewId.SelfSignature.IsPrimaryId != nil && *potentialNewId.SelfSignature.IsPrimaryId) {
+ return false
+ }
+
+ if !(existingId.SelfSignature.IsPrimaryId != nil && *existingId.SelfSignature.IsPrimaryId) &&
+ potentialNewId.SelfSignature.IsPrimaryId != nil && *potentialNewId.SelfSignature.IsPrimaryId {
+ return true
+ }
+
+ return potentialNewId.SelfSignature.CreationTime.After(existingId.SelfSignature.CreationTime)
+}
+
+// EncryptionKey returns the best candidate Key for encrypting a message to the
+// given Entity.
+func (e *Entity) EncryptionKey(now time.Time) (Key, bool) {
+ // Fail to find any encryption key if the...
+ i := e.PrimaryIdentity()
+ if e.PrimaryKey.KeyExpired(i.SelfSignature, now) || // primary key has expired
+ i.SelfSignature == nil || // user ID has no self-signature
+ i.SelfSignature.SigExpired(now) || // user ID self-signature has expired
+ e.Revoked(now) || // primary key has been revoked
+ i.Revoked(now) { // user ID has been revoked
+ return Key{}, false
+ }
+
+ // Iterate the keys to find the newest, unexpired one
+ candidateSubkey := -1
+ var maxTime time.Time
+ for i, subkey := range e.Subkeys {
+ if subkey.Sig.FlagsValid &&
+ subkey.Sig.FlagEncryptCommunications &&
+ subkey.PublicKey.PubKeyAlgo.CanEncrypt() &&
+ !subkey.PublicKey.KeyExpired(subkey.Sig, now) &&
+ !subkey.Sig.SigExpired(now) &&
+ !subkey.Revoked(now) &&
+ (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) {
+ candidateSubkey = i
+ maxTime = subkey.Sig.CreationTime
+ }
+ }
+
+ if candidateSubkey != -1 {
+ subkey := e.Subkeys[candidateSubkey]
+ return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true
+ }
+
+ // If we don't have any subkeys for encryption and the primary key
+ // is marked as OK to encrypt with, then we can use it.
+ if i.SelfSignature.FlagsValid && i.SelfSignature.FlagEncryptCommunications &&
+ e.PrimaryKey.PubKeyAlgo.CanEncrypt() {
+ return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature, e.Revocations}, true
+ }
+
+ return Key{}, false
+}
+
+// CertificationKey return the best candidate Key for certifying a key with this
+// Entity.
+func (e *Entity) CertificationKey(now time.Time) (Key, bool) {
+ return e.CertificationKeyById(now, 0)
+}
+
+// CertificationKeyById return the Key for key certification with this
+// Entity and keyID.
+func (e *Entity) CertificationKeyById(now time.Time, id uint64) (Key, bool) {
+ return e.signingKeyByIdUsage(now, id, packet.KeyFlagCertify)
+}
+
+// SigningKey return the best candidate Key for signing a message with this
+// Entity.
+func (e *Entity) SigningKey(now time.Time) (Key, bool) {
+ return e.SigningKeyById(now, 0)
+}
+
+// SigningKeyById return the Key for signing a message with this
+// Entity and keyID.
+func (e *Entity) SigningKeyById(now time.Time, id uint64) (Key, bool) {
+ return e.signingKeyByIdUsage(now, id, packet.KeyFlagSign)
+}
+
+func (e *Entity) signingKeyByIdUsage(now time.Time, id uint64, flags int) (Key, bool) {
+ // Fail to find any signing key if the...
+ i := e.PrimaryIdentity()
+ if e.PrimaryKey.KeyExpired(i.SelfSignature, now) || // primary key has expired
+ i.SelfSignature == nil || // user ID has no self-signature
+ i.SelfSignature.SigExpired(now) || // user ID self-signature has expired
+ e.Revoked(now) || // primary key has been revoked
+ i.Revoked(now) { // user ID has been revoked
+ return Key{}, false
+ }
+
+ // Iterate the keys to find the newest, unexpired one
+ candidateSubkey := -1
+ var maxTime time.Time
+ for idx, subkey := range e.Subkeys {
+ if subkey.Sig.FlagsValid &&
+ (flags&packet.KeyFlagCertify == 0 || subkey.Sig.FlagCertify) &&
+ (flags&packet.KeyFlagSign == 0 || subkey.Sig.FlagSign) &&
+ subkey.PublicKey.PubKeyAlgo.CanSign() &&
+ !subkey.PublicKey.KeyExpired(subkey.Sig, now) &&
+ !subkey.Sig.SigExpired(now) &&
+ !subkey.Revoked(now) &&
+ (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) &&
+ (id == 0 || subkey.PublicKey.KeyId == id) {
+ candidateSubkey = idx
+ maxTime = subkey.Sig.CreationTime
+ }
+ }
+
+ if candidateSubkey != -1 {
+ subkey := e.Subkeys[candidateSubkey]
+ return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true
+ }
+
+ // If we don't have any subkeys for signing and the primary key
+ // is marked as OK to sign with, then we can use it.
+ if i.SelfSignature.FlagsValid &&
+ (flags&packet.KeyFlagCertify == 0 || i.SelfSignature.FlagCertify) &&
+ (flags&packet.KeyFlagSign == 0 || i.SelfSignature.FlagSign) &&
+ e.PrimaryKey.PubKeyAlgo.CanSign() &&
+ (id == 0 || e.PrimaryKey.KeyId == id) {
+ return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature, e.Revocations}, true
+ }
+
+ // No keys with a valid Signing Flag or no keys matched the id passed in
+ return Key{}, false
+}
+
+func revoked(revocations []*packet.Signature, now time.Time) bool {
+ for _, revocation := range revocations {
+ if revocation.RevocationReason != nil && *revocation.RevocationReason == packet.KeyCompromised {
+ // If the key is compromised, the key is considered revoked even before the revocation date.
+ return true
+ }
+ if !revocation.SigExpired(now) {
+ return true
+ }
+ }
+ return false
+}
+
+// Revoked returns whether the entity has any direct key revocation signatures.
+// Note that third-party revocation signatures are not supported.
+// Note also that Identity and Subkey revocation should be checked separately.
+func (e *Entity) Revoked(now time.Time) bool {
+ return revoked(e.Revocations, now)
+}
+
+// EncryptPrivateKeys encrypts all non-encrypted keys in the entity with the same key
+// derived from the provided passphrase. Public keys and dummy keys are ignored,
+// and don't cause an error to be returned.
+func (e *Entity) EncryptPrivateKeys(passphrase []byte, config *packet.Config) error {
+ var keysToEncrypt []*packet.PrivateKey
+ // Add entity private key to encrypt.
+ if e.PrivateKey != nil && !e.PrivateKey.Dummy() && !e.PrivateKey.Encrypted {
+ keysToEncrypt = append(keysToEncrypt, e.PrivateKey)
+ }
+
+ // Add subkeys to encrypt.
+ for _, sub := range e.Subkeys {
+ if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && !sub.PrivateKey.Encrypted {
+ keysToEncrypt = append(keysToEncrypt, sub.PrivateKey)
+ }
+ }
+ return packet.EncryptPrivateKeys(keysToEncrypt, passphrase, config)
+}
+
+// DecryptPrivateKeys decrypts all encrypted keys in the entitiy with the given passphrase.
+// Avoids recomputation of similar s2k key derivations. Public keys and dummy keys are ignored,
+// and don't cause an error to be returned.
+func (e *Entity) DecryptPrivateKeys(passphrase []byte) error {
+ var keysToDecrypt []*packet.PrivateKey
+ // Add entity private key to decrypt.
+ if e.PrivateKey != nil && !e.PrivateKey.Dummy() && e.PrivateKey.Encrypted {
+ keysToDecrypt = append(keysToDecrypt, e.PrivateKey)
+ }
+
+ // Add subkeys to decrypt.
+ for _, sub := range e.Subkeys {
+ if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted {
+ keysToDecrypt = append(keysToDecrypt, sub.PrivateKey)
+ }
+ }
+ return packet.DecryptPrivateKeys(keysToDecrypt, passphrase)
+}
+
+// Revoked returns whether the identity has been revoked by a self-signature.
+// Note that third-party revocation signatures are not supported.
+func (i *Identity) Revoked(now time.Time) bool {
+ return revoked(i.Revocations, now)
+}
+
+// Revoked returns whether the subkey has been revoked by a self-signature.
+// Note that third-party revocation signatures are not supported.
+func (s *Subkey) Revoked(now time.Time) bool {
+ return revoked(s.Revocations, now)
+}
+
+// Revoked returns whether the key or subkey has been revoked by a self-signature.
+// Note that third-party revocation signatures are not supported.
+// Note also that Identity revocation should be checked separately.
+// Normally, it's not necessary to call this function, except on keys returned by
+// KeysById or KeysByIdUsage.
+func (key *Key) Revoked(now time.Time) bool {
+ return revoked(key.Revocations, now)
+}
+
+// An EntityList contains one or more Entities.
+type EntityList []*Entity
+
+// KeysById returns the set of keys that have the given key id.
+func (el EntityList) KeysById(id uint64) (keys []Key) {
+ for _, e := range el {
+ if e.PrimaryKey.KeyId == id {
+ ident := e.PrimaryIdentity()
+ selfSig := ident.SelfSignature
+ keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig, e.Revocations})
+ }
+
+ for _, subKey := range e.Subkeys {
+ if subKey.PublicKey.KeyId == id {
+ keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig, subKey.Revocations})
+ }
+ }
+ }
+ return
+}
+
+// KeysByIdAndUsage returns the set of keys with the given id that also meet
+// the key usage given by requiredUsage. The requiredUsage is expressed as
+// the bitwise-OR of packet.KeyFlag* values.
+func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) {
+ for _, key := range el.KeysById(id) {
+ if requiredUsage != 0 {
+ if key.SelfSignature == nil || !key.SelfSignature.FlagsValid {
+ continue
+ }
+
+ var usage byte
+ if key.SelfSignature.FlagCertify {
+ usage |= packet.KeyFlagCertify
+ }
+ if key.SelfSignature.FlagSign {
+ usage |= packet.KeyFlagSign
+ }
+ if key.SelfSignature.FlagEncryptCommunications {
+ usage |= packet.KeyFlagEncryptCommunications
+ }
+ if key.SelfSignature.FlagEncryptStorage {
+ usage |= packet.KeyFlagEncryptStorage
+ }
+ if usage&requiredUsage != requiredUsage {
+ continue
+ }
+ }
+
+ keys = append(keys, key)
+ }
+ return
+}
+
+// DecryptionKeys returns all private keys that are valid for decryption.
+func (el EntityList) DecryptionKeys() (keys []Key) {
+ for _, e := range el {
+ for _, subKey := range e.Subkeys {
+ if subKey.PrivateKey != nil && subKey.Sig.FlagsValid && (subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
+ keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig, subKey.Revocations})
+ }
+ }
+ }
+ return
+}
+
+// ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
+func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
+ block, err := armor.Decode(r)
+ if err == io.EOF {
+ return nil, errors.InvalidArgumentError("no armored data found")
+ }
+ if err != nil {
+ return nil, err
+ }
+ if block.Type != PublicKeyType && block.Type != PrivateKeyType {
+ return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type)
+ }
+
+ return ReadKeyRing(block.Body)
+}
+
+// ReadKeyRing reads one or more public/private keys. Unsupported keys are
+// ignored as long as at least a single valid key is found.
+func ReadKeyRing(r io.Reader) (el EntityList, err error) {
+ packets := packet.NewReader(r)
+ var lastUnsupportedError error
+
+ for {
+ var e *Entity
+ e, err = ReadEntity(packets)
+ if err != nil {
+ // TODO: warn about skipped unsupported/unreadable keys
+ if _, ok := err.(errors.UnsupportedError); ok {
+ lastUnsupportedError = err
+ err = readToNextPublicKey(packets)
+ } else if _, ok := err.(errors.StructuralError); ok {
+ // Skip unreadable, badly-formatted keys
+ lastUnsupportedError = err
+ err = readToNextPublicKey(packets)
+ }
+ if err == io.EOF {
+ err = nil
+ break
+ }
+ if err != nil {
+ el = nil
+ break
+ }
+ } else {
+ el = append(el, e)
+ }
+ }
+
+ if len(el) == 0 && err == nil {
+ err = lastUnsupportedError
+ }
+ return
+}
+
+// readToNextPublicKey reads packets until the start of the entity and leaves
+// the first packet of the new entity in the Reader.
+func readToNextPublicKey(packets *packet.Reader) (err error) {
+ var p packet.Packet
+ for {
+ p, err = packets.Next()
+ if err == io.EOF {
+ return
+ } else if err != nil {
+ if _, ok := err.(errors.UnsupportedError); ok {
+ err = nil
+ continue
+ }
+ return
+ }
+
+ if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
+ packets.Unread(p)
+ return
+ }
+ }
+}
+
+// ReadEntity reads an entity (public key, identities, subkeys etc) from the
+// given Reader.
+func ReadEntity(packets *packet.Reader) (*Entity, error) {
+ e := new(Entity)
+ e.Identities = make(map[string]*Identity)
+
+ p, err := packets.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ var ok bool
+ if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
+ if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
+ packets.Unread(p)
+ return nil, errors.StructuralError("first packet was not a public/private key")
+ }
+ e.PrimaryKey = &e.PrivateKey.PublicKey
+ }
+
+ if !e.PrimaryKey.PubKeyAlgo.CanSign() {
+ return nil, errors.StructuralError("primary key cannot be used for signatures")
+ }
+
+ var revocations []*packet.Signature
+EachPacket:
+ for {
+ p, err := packets.Next()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return nil, err
+ }
+
+ switch pkt := p.(type) {
+ case *packet.UserId:
+ if err := addUserID(e, packets, pkt); err != nil {
+ return nil, err
+ }
+ case *packet.Signature:
+ if pkt.SigType == packet.SigTypeKeyRevocation {
+ revocations = append(revocations, pkt)
+ } else if pkt.SigType == packet.SigTypeDirectSignature {
+ // TODO: RFC4880 5.2.1 permits signatures
+ // directly on keys (eg. to bind additional
+ // revocation keys).
+ }
+ // Else, ignoring the signature as it does not follow anything
+ // we would know to attach it to.
+ case *packet.PrivateKey:
+ if !pkt.IsSubkey {
+ packets.Unread(p)
+ break EachPacket
+ }
+ err = addSubkey(e, packets, &pkt.PublicKey, pkt)
+ if err != nil {
+ return nil, err
+ }
+ case *packet.PublicKey:
+ if !pkt.IsSubkey {
+ packets.Unread(p)
+ break EachPacket
+ }
+ err = addSubkey(e, packets, pkt, nil)
+ if err != nil {
+ return nil, err
+ }
+ default:
+ // we ignore unknown packets
+ }
+ }
+
+ if len(e.Identities) == 0 {
+ return nil, errors.StructuralError("entity without any identities")
+ }
+
+ for _, revocation := range revocations {
+ err = e.PrimaryKey.VerifyRevocationSignature(revocation)
+ if err == nil {
+ e.Revocations = append(e.Revocations, revocation)
+ } else {
+ // TODO: RFC 4880 5.2.3.15 defines revocation keys.
+ return nil, errors.StructuralError("revocation signature signed by alternate key")
+ }
+ }
+
+ return e, nil
+}
+
+func addUserID(e *Entity, packets *packet.Reader, pkt *packet.UserId) error {
+ // Make a new Identity object, that we might wind up throwing away.
+ // We'll only add it if we get a valid self-signature over this
+ // userID.
+ identity := new(Identity)
+ identity.Name = pkt.Id
+ identity.UserId = pkt
+
+ for {
+ p, err := packets.Next()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return err
+ }
+
+ sig, ok := p.(*packet.Signature)
+ if !ok {
+ packets.Unread(p)
+ break
+ }
+
+ if sig.SigType != packet.SigTypeGenericCert &&
+ sig.SigType != packet.SigTypePersonaCert &&
+ sig.SigType != packet.SigTypeCasualCert &&
+ sig.SigType != packet.SigTypePositiveCert &&
+ sig.SigType != packet.SigTypeCertificationRevocation {
+ return errors.StructuralError("user ID signature with wrong type")
+ }
+
+ if sig.CheckKeyIdOrFingerprint(e.PrimaryKey) {
+ if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil {
+ return errors.StructuralError("user ID self-signature invalid: " + err.Error())
+ }
+ if sig.SigType == packet.SigTypeCertificationRevocation {
+ identity.Revocations = append(identity.Revocations, sig)
+ } else if identity.SelfSignature == nil || sig.CreationTime.After(identity.SelfSignature.CreationTime) {
+ identity.SelfSignature = sig
+ }
+ identity.Signatures = append(identity.Signatures, sig)
+ e.Identities[pkt.Id] = identity
+ } else {
+ identity.Signatures = append(identity.Signatures, sig)
+ }
+ }
+
+ return nil
+}
+
+func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
+ var subKey Subkey
+ subKey.PublicKey = pub
+ subKey.PrivateKey = priv
+
+ for {
+ p, err := packets.Next()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return errors.StructuralError("subkey signature invalid: " + err.Error())
+ }
+
+ sig, ok := p.(*packet.Signature)
+ if !ok {
+ packets.Unread(p)
+ break
+ }
+
+ if sig.SigType != packet.SigTypeSubkeyBinding && sig.SigType != packet.SigTypeSubkeyRevocation {
+ return errors.StructuralError("subkey signature with wrong type")
+ }
+
+ if err := e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, sig); err != nil {
+ return errors.StructuralError("subkey signature invalid: " + err.Error())
+ }
+
+ switch sig.SigType {
+ case packet.SigTypeSubkeyRevocation:
+ subKey.Revocations = append(subKey.Revocations, sig)
+ case packet.SigTypeSubkeyBinding:
+ if subKey.Sig == nil || sig.CreationTime.After(subKey.Sig.CreationTime) {
+ subKey.Sig = sig
+ }
+ }
+ }
+
+ if subKey.Sig == nil {
+ return errors.StructuralError("subkey packet not followed by signature")
+ }
+
+ e.Subkeys = append(e.Subkeys, subKey)
+
+ return nil
+}
+
+// SerializePrivate serializes an Entity, including private key material, but
+// excluding signatures from other entities, to the given Writer.
+// Identities and subkeys are re-signed in case they changed since NewEntry.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
+ if e.PrivateKey.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy private key cannot re-sign identities")
+ }
+ return e.serializePrivate(w, config, true)
+}
+
+// SerializePrivateWithoutSigning serializes an Entity, including private key
+// material, but excluding signatures from other entities, to the given Writer.
+// Self-signatures of identities and subkeys are not re-signed. This is useful
+// when serializing GNU dummy keys, among other things.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SerializePrivateWithoutSigning(w io.Writer, config *packet.Config) (err error) {
+ return e.serializePrivate(w, config, false)
+}
+
+func (e *Entity) serializePrivate(w io.Writer, config *packet.Config, reSign bool) (err error) {
+ if e.PrivateKey == nil {
+ return goerrors.New("openpgp: private key is missing")
+ }
+ err = e.PrivateKey.Serialize(w)
+ if err != nil {
+ return
+ }
+ for _, revocation := range e.Revocations {
+ err := revocation.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ for _, ident := range e.Identities {
+ err = ident.UserId.Serialize(w)
+ if err != nil {
+ return
+ }
+ if reSign {
+ if ident.SelfSignature == nil {
+ return goerrors.New("openpgp: can't re-sign identity without valid self-signature")
+ }
+ err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config)
+ if err != nil {
+ return
+ }
+ }
+ for _, sig := range ident.Signatures {
+ err = sig.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ for _, subkey := range e.Subkeys {
+ err = subkey.PrivateKey.Serialize(w)
+ if err != nil {
+ return
+ }
+ if reSign {
+ err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
+ if err != nil {
+ return
+ }
+ if subkey.Sig.EmbeddedSignature != nil {
+ err = subkey.Sig.EmbeddedSignature.CrossSignKey(subkey.PublicKey, e.PrimaryKey,
+ subkey.PrivateKey, config)
+ if err != nil {
+ return
+ }
+ }
+ }
+ for _, revocation := range subkey.Revocations {
+ err := revocation.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ err = subkey.Sig.Serialize(w)
+ if err != nil {
+ return
+ }
+ }
+ return nil
+}
+
+// Serialize writes the public part of the given Entity to w, including
+// signatures from other entities. No private key material will be output.
+func (e *Entity) Serialize(w io.Writer) error {
+ err := e.PrimaryKey.Serialize(w)
+ if err != nil {
+ return err
+ }
+ for _, revocation := range e.Revocations {
+ err := revocation.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ for _, ident := range e.Identities {
+ err = ident.UserId.Serialize(w)
+ if err != nil {
+ return err
+ }
+ for _, sig := range ident.Signatures {
+ err = sig.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ for _, subkey := range e.Subkeys {
+ err = subkey.PublicKey.Serialize(w)
+ if err != nil {
+ return err
+ }
+ for _, revocation := range subkey.Revocations {
+ err := revocation.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ err = subkey.Sig.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// SignIdentity adds a signature to e, from signer, attesting that identity is
+// associated with e. The provided identity must already be an element of
+// e.Identities and the private key of signer must have been decrypted if
+// necessary.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error {
+ certificationKey, ok := signer.CertificationKey(config.Now())
+ if !ok {
+ return errors.InvalidArgumentError("no valid certification key found")
+ }
+
+ if certificationKey.PrivateKey.Encrypted {
+ return errors.InvalidArgumentError("signing Entity's private key must be decrypted")
+ }
+
+ ident, ok := e.Identities[identity]
+ if !ok {
+ return errors.InvalidArgumentError("given identity string not found in Entity")
+ }
+
+ sig := createSignaturePacket(certificationKey.PublicKey, packet.SigTypeGenericCert, config)
+
+ signingUserID := config.SigningUserId()
+ if signingUserID != "" {
+ if _, ok := signer.Identities[signingUserID]; !ok {
+ return errors.InvalidArgumentError("signer identity string not found in signer Entity")
+ }
+ sig.SignerUserId = &signingUserID
+ }
+
+ if err := sig.SignUserId(identity, e.PrimaryKey, certificationKey.PrivateKey, config); err != nil {
+ return err
+ }
+ ident.Signatures = append(ident.Signatures, sig)
+ return nil
+}
+
+// RevokeKey generates a key revocation signature (packet.SigTypeKeyRevocation) with the
+// specified reason code and text (RFC4880 section-5.2.3.23).
+// If config is nil, sensible defaults will be used.
+func (e *Entity) RevokeKey(reason packet.ReasonForRevocation, reasonText string, config *packet.Config) error {
+ revSig := createSignaturePacket(e.PrimaryKey, packet.SigTypeKeyRevocation, config)
+ revSig.RevocationReason = &reason
+ revSig.RevocationReasonText = reasonText
+
+ if err := revSig.RevokeKey(e.PrimaryKey, e.PrivateKey, config); err != nil {
+ return err
+ }
+ e.Revocations = append(e.Revocations, revSig)
+ return nil
+}
+
+// RevokeSubkey generates a subkey revocation signature (packet.SigTypeSubkeyRevocation) for
+// a subkey with the specified reason code and text (RFC4880 section-5.2.3.23).
+// If config is nil, sensible defaults will be used.
+func (e *Entity) RevokeSubkey(sk *Subkey, reason packet.ReasonForRevocation, reasonText string, config *packet.Config) error {
+ if err := e.PrimaryKey.VerifyKeySignature(sk.PublicKey, sk.Sig); err != nil {
+ return errors.InvalidArgumentError("given subkey is not associated with this key")
+ }
+
+ revSig := createSignaturePacket(e.PrimaryKey, packet.SigTypeSubkeyRevocation, config)
+ revSig.RevocationReason = &reason
+ revSig.RevocationReasonText = reasonText
+
+ if err := revSig.RevokeSubkey(sk.PublicKey, e.PrivateKey, config); err != nil {
+ return err
+ }
+
+ sk.Revocations = append(sk.Revocations, revSig)
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/keys_test_data.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys_test_data.go
new file mode 100644
index 00000000..108fd096
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys_test_data.go
@@ -0,0 +1,538 @@
+package openpgp
+
+const expiringKeyHex = "c6c04d0451d0c680010800abbb021fd03ffc4e96618901180c3fdcb060ee69eeead97b91256d11420d80b5f1b51930248044130bd300605cf8a05b7a40d3d8cfb0a910be2e3db50dcd50a9c54064c2a5550801daa834ff4480b33d3d3ca495ff8a4e84a886977d17d998f881241a874083d8b995beab555b6d22b8a4817ab17ac3e7304f7d4d2c05c495fb2218348d3bc13651db1d92732e368a9dd7dcefa6eddff30b94706a9aaee47e9d39321460b740c59c6fc3c2fd8ab6c0fb868cb87c0051f0321301fe0f0e1820b15e7fb7063395769b525005c7e30a7ce85984f5cac00504e7b4fdc45d74958de8388436fd5c7ba9ea121f1c851b5911dd1b47a14d81a09e92ef37721e2325b6790011010001cd00c2c07b041001080025050251d0c680050900278d00060b09070803020415080a0203160201021901021b03021e01000a0910e7b484133a890a35ae4b0800a1beb82e7f28eaf5273d6af9d3391314f6280b2b624eaca2851f89a9ebcaf80ac589ebd509f168bc4322106ca2e2ce77a76e071a3c7444787d65216b5f05e82c77928860b92aace3b7d0327db59492f422eb9dfab7249266d37429870b091a98aba8724c2259ebf8f85093f21255eafa75aa841e31d94f2ac891b9755fed455e539044ee69fc47950b80e003fc9f298d695660f28329eaa38037c367efde1727458e514faf990d439a21461b719edaddf9296d3d0647b43ca56cb8dbf63b4fcf8b9968e7928c463470fab3b98e44d0d95645062f94b2d04fe56bd52822b71934db8ce845622c40b92fcbe765a142e7f38b61a6aa9606c8e8858dcd3b6eb1894acec04d0451d1f06b01080088bea67444e1789390e7c0335c86775502d58ec783d99c8ef4e06de235ed3dd4b0467f6f358d818c7d8989d43ec6d69fcbc8c32632d5a1b605e3fa8e41d695fcdcaa535936cd0157f9040dce362519803b908eafe838bb13216c885c6f93e9e8d5745607f0d062322085d6bdc760969149a8ff8dd9f5c18d9bfe2e6f63a06e17694cf1f67587c6fb70e9aebf90ffc528ca3b615ac7c9d4a21ea4f7c06f2e98fbbd90a859b8608bf9ea638e3a54289ce44c283110d0c45fa458de6251cd6e7baf71f80f12c8978340490fd90c92b81736ae902ed958e478dceae2835953d189c45d182aff02ea2be61b81d8e94430f041d638647b43e2fcb45fd512fbf5068b810011010001c2c06504180108000f050251d1f06b050900081095021b0c000a0910e7b484133a890a35e63407fe2ec88d6d1e6c9ce7553ece0cb2524747217bad29f251d33df84599ffcc900141a355abd62126800744068a5e05dc167056aa9205273dc7765a2ed49db15c2a83b8d6e6429c902136f1e12229086c1c10c0053242c2a4ae1930db58163387a48cad64607ff2153c320e42843dec28e3fce90e7399d63ac0affa2fee1f0adc0953c89eb3f46ef1d6c04328ed13b491669d5120a3782e3ffb7c69575fb77eebd108794f4dda9d34be2bae57e8e59ec8ebfda2f6f06104b2321be408ea146e2db482b00c5055c8618de36ac9716f80da2617e225556d0fce61b01c8cea2d1e0ea982c31711060ca370f2739366e1e708f38405d784b49d16a26cf62d152eae734327cec04d0451d1f07b010800d5af91c5e7c2fd8951c8d254eab0c97cdcb66822f868b79b78c366255059a68fd74ebca9adb9b970cd9e586690e6e0756705432306878c897b10a4b4ca0005966f99ac8fa4e6f9caf54bf8e53844544beee9872a7ac64c119cf1393d96e674254b661f61ee975633d0e8a8672531edb6bb8e211204e7754a9efa802342118eee850beea742bac95a3f706cc2024cf6037a308bb68162b2f53b9a6346a96e6d31871a2456186e24a1c7a82b82ac04afdfd57cd7fb9ba77a9c760d40b76a170f7be525e5fb6a9848cc726e806187710d9b190387df28700f321f988a392899f93815cc937f309129eb94d5299c5547cb2c085898e6639496e70d746c9d3fb9881d0011010001c2c06504180108000f050251d1f07b050900266305021b0c000a0910e7b484133a890a35bff207fd10dfe8c4a6ea1dd30568012b6fd6891a763c87ad0f7a1d112aad9e8e3239378a3b85588c235865bac2e614348cb4f216d7217f53b3ef48c192e0a4d31d64d7bfa5faccf21155965fa156e887056db644a05ad08a85cc6152d1377d9e37b46f4ff462bbe68ace2dc586ef90070314576c985d8037c2ba63f0a7dc17a62e15bd77e88bc61d9d00858979709f12304264a4cf4225c5cf86f12c8e19486cb9cdcc69f18f027e5f16f4ca8b50e28b3115eaff3a345acd21f624aef81f6ede515c1b55b26b84c1e32264754eab672d5489b287e7277ea855e0a5ff2aa9e8b8c76d579a964ec225255f4d57bf66639ccb34b64798846943e162a41096a7002ca21c7f56"
+const subkeyUsageHex = "988d04533a52bc010400d26af43085558f65b9e7dbc90cb9238015259aed5e954637adcfa2181548b2d0b60c65f1f42ec5081cbf1bc0a8aa4900acfb77070837c58f26012fbce297d70afe96e759ad63531f0037538e70dbf8e384569b9720d99d8eb39d8d0a2947233ed242436cb6ac7dfe74123354b3d0119b5c235d3dd9c9d6c004f8ffaf67ad8583001101000188b7041f010200210502533b8552170c8001ce094aa433f7040bb2ddf0be3893cb843d0fe70c020700000a0910a42704b92866382aa98404009d63d916a27543da4221c60087c33f1c44bec9998c5438018ed370cca4962876c748e94b73eb39c58eb698063f3fd6346d58dd2a11c0247934c4a9d71f24754f7468f96fb24c3e791dd2392b62f626148ad724189498cbf993db2df7c0cdc2d677c35da0f16cb16c9ce7c33b4de65a4a91b1d21a130ae9cc26067718910ef8e2b417556d627261203c756d627261407379642e65642e61753e88b80413010200220502533a52bc021b03060b090807030206150802090a0b0416020301021e01021780000a0910a42704b92866382a47840400c0c2bd04f5fca586de408b395b3c280a278259c93eaaa8b79a53b97003f8ed502a8a00446dd9947fb462677e4fcac0dac2f0701847d15130aadb6cd9e0705ea0cf5f92f129136c7be21a718d46c8e641eb7f044f2adae573e11ae423a0a9ca51324f03a8a2f34b91fa40c3cc764bee4dccadedb54c768ba0469b683ea53f1c29b88d04533a52bc01040099c92a5d6f8b744224da27bc2369127c35269b58bec179de6bbc038f749344222f85a31933224f26b70243c4e4b2d242f0c4777eaef7b5502f9dad6d8bf3aaeb471210674b74de2d7078af497d55f5cdad97c7bedfbc1b41e8065a97c9c3d344b21fc81d27723af8e374bc595da26ea242dccb6ae497be26eea57e563ed517e90011010001889f0418010200090502533a52bc021b0c000a0910a42704b92866382afa1403ff70284c2de8a043ff51d8d29772602fa98009b7861c540535f874f2c230af8caf5638151a636b21f8255003997ccd29747fdd06777bb24f9593bd7d98a3e887689bf902f999915fcc94625ae487e5d13e6616f89090ebc4fdc7eb5cad8943e4056995bb61c6af37f8043016876a958ec7ebf39c43d20d53b7f546cfa83e8d2604b88d04533b8283010400c0b529316dbdf58b4c54461e7e669dc11c09eb7f73819f178ccd4177b9182b91d138605fcf1e463262fabefa73f94a52b5e15d1904635541c7ea540f07050ce0fb51b73e6f88644cec86e91107c957a114f69554548a85295d2b70bd0b203992f76eb5d493d86d9eabcaa7ef3fc7db7e458438db3fcdb0ca1cc97c638439a9170011010001889f0418010200090502533b8283021b0c000a0910a42704b92866382adc6d0400cfff6258485a21675adb7a811c3e19ebca18851533f75a7ba317950b9997fda8d1a4c8c76505c08c04b6c2cc31dc704d33da36a21273f2b388a1a706f7c3378b66d887197a525936ed9a69acb57fe7f718133da85ec742001c5d1864e9c6c8ea1b94f1c3759cebfd93b18606066c063a63be86085b7e37bdbc65f9a915bf084bb901a204533b85cd110400aed3d2c52af2b38b5b67904b0ef73d6dd7aef86adb770e2b153cd22489654dcc91730892087bb9856ae2d9f7ed1eb48f214243fe86bfe87b349ebd7c30e630e49c07b21fdabf78b7a95c8b7f969e97e3d33f2e074c63552ba64a2ded7badc05ce0ea2be6d53485f6900c7860c7aa76560376ce963d7271b9b54638a4028b573f00a0d8854bfcdb04986141568046202192263b9b67350400aaa1049dbc7943141ef590a70dcb028d730371d92ea4863de715f7f0f16d168bd3dc266c2450457d46dcbbf0b071547e5fbee7700a820c3750b236335d8d5848adb3c0da010e998908dfd93d961480084f3aea20b247034f8988eccb5546efaa35a92d0451df3aaf1aee5aa36a4c4d462c760ecd9cebcabfbe1412b1f21450f203fd126687cd486496e971a87fd9e1a8a765fe654baa219a6871ab97768596ab05c26c1aeea8f1a2c72395a58dbc12ef9640d2b95784e974a4d2d5a9b17c25fedacfe551bda52602de8f6d2e48443f5dd1a2a2a8e6a5e70ecdb88cd6e766ad9745c7ee91d78cc55c3d06536b49c3fee6c3d0b6ff0fb2bf13a314f57c953b8f4d93bf88e70418010200090502533b85cd021b0200520910a42704b92866382a47200419110200060502533b85cd000a091042ce2c64bc0ba99214b2009e26b26852c8b13b10c35768e40e78fbbb48bd084100a0c79d9ea0844fa5853dd3c85ff3ecae6f2c9dd6c557aa04008bbbc964cd65b9b8299d4ebf31f41cc7264b8cf33a00e82c5af022331fac79efc9563a822497ba012953cefe2629f1242fcdcb911dbb2315985bab060bfd58261ace3c654bdbbe2e8ed27a46e836490145c86dc7bae15c011f7e1ffc33730109b9338cd9f483e7cef3d2f396aab5bd80efb6646d7e778270ee99d934d187dd98"
+const revokedKeyHex = "988d045331ce82010400c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be10011010001889f04200102000905025331d0e3021d03000a0910a401d9f09a34f7c042aa040086631196405b7e6af71026b88e98012eab44aa9849f6ef3fa930c7c9f23deaedba9db1538830f8652fb7648ec3fcade8dbcbf9eaf428e83c6cbcc272201bfe2fbb90d41963397a7c0637a1a9d9448ce695d9790db2dc95433ad7be19eb3de72dacf1d6db82c3644c13eae2a3d072b99bb341debba012c5ce4006a7d34a1f4b94b444526567205265766f6b657220283c52656727732022424d204261726973746122204b657920262530305c303e5c29203c72656740626d626172697374612e636f2e61753e88b704130102002205025331ce82021b03060b090807030206150802090a0b0416020301021e01021780000a0910a401d9f09a34f7c0019c03f75edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56889c04100102000605025331cfb5000a0910fe9645554e8266b64b4303fc084075396674fb6f778d302ac07cef6bc0b5d07b66b2004c44aef711cbac79617ef06d836b4957522d8772dd94bf41a2f4ac8b1ee6d70c57503f837445a74765a076d07b829b8111fc2a918423ddb817ead7ca2a613ef0bfb9c6b3562aec6c3cf3c75ef3031d81d95f6563e4cdcc9960bcb386c5d757b104fcca5fe11fc709df884604101102000605025331cfe7000a09107b15a67f0b3ddc0317f6009e360beea58f29c1d963a22b962b80788c3fa6c84e009d148cfde6b351469b8eae91187eff07ad9d08fcaab88d045331ce820104009f25e20a42b904f3fa555530fe5c46737cf7bd076c35a2a0d22b11f7e0b61a69320b768f4a80fe13980ce380d1cfc4a0cd8fbe2d2e2ef85416668b77208baa65bf973fe8e500e78cc310d7c8705cdb34328bf80e24f0385fce5845c33bc7943cf6b11b02348a23da0bf6428e57c05135f2dc6bd7c1ce325d666d5a5fd2fd5e410011010001889f04180102000905025331ce82021b0c000a0910a401d9f09a34f7c0418003fe34feafcbeaef348a800a0d908a7a6809cc7304017d820f70f0474d5e23cb17e38b67dc6dca282c6ca00961f4ec9edf2738d0f087b1d81e4871ef08e1798010863afb4eac4c44a376cb343be929c5be66a78cfd4456ae9ec6a99d97f4e1c3ff3583351db2147a65c0acef5c003fb544ab3a2e2dc4d43646f58b811a6c3a369d1f"
+const revokedSubkeyHex = "988d04533121f6010400aefc803a3e4bb1a61c86e8a86d2726c6a43e0079e9f2713f1fa017e9854c83877f4aced8e331d675c67ea83ddab80aacbfa0b9040bb12d96f5a3d6be09455e2a76546cbd21677537db941cab710216b6d24ec277ee0bd65b910f416737ed120f6b93a9d3b306245c8cfd8394606fdb462e5cf43c551438d2864506c63367fc890011010001b41d416c696365203c616c69636540626d626172697374612e636f2e61753e88bb041301020025021b03060b090807030206150802090a0b0416020301021e01021780050253312798021901000a09104ef7e4beccde97f015a803ff5448437780f63263b0df8442a995e7f76c221351a51edd06f2063d8166cf3157aada4923dfc44aa0f2a6a4da5cf83b7fe722ba8ab416c976e77c6b5682e7f1069026673bd0de56ba06fd5d7a9f177607f277d9b55ff940a638c3e68525c67517e2b3d976899b93ca267f705b3e5efad7d61220e96b618a4497eab8d04403d23f8846041011020006050253312910000a09107b15a67f0b3ddc03d96e009f50b6365d86c4be5d5e9d0ea42d5e56f5794c617700a0ab274e19c2827780016d23417ce89e0a2c0d987d889c04100102000605025331cf7a000a0910a401d9f09a34f7c0ee970400aca292f213041c9f3b3fc49148cbda9d84afee6183c8dd6c5ff2600b29482db5fecd4303797be1ee6d544a20a858080fec43412061c9a71fae4039fd58013b4ae341273e6c66ad4c7cdd9e68245bedb260562e7b166f2461a1032f2b38c0e0e5715fb3d1656979e052b55ca827a76f872b78a9fdae64bc298170bfcebedc1271b41a416c696365203c616c696365407379646973702e6f722e61753e88b804130102002205025331278b021b03060b090807030206150802090a0b0416020301021e01021780000a09104ef7e4beccde97f06a7003fa03c3af68d272ebc1fa08aa72a03b02189c26496a2833d90450801c4e42c5b5f51ad96ce2d2c9cef4b7c02a6a2fcf1412d6a2d486098eb762f5010a201819c17fd2888aec8eda20c65a3b75744de7ee5cc8ac7bfc470cbe3cb982720405a27a3c6a8c229cfe36905f881b02ed5680f6a8f05866efb9d6c5844897e631deb949ca8846041011020006050253312910000a09107b15a67f0b3ddc0347bc009f7fa35db59147469eb6f2c5aaf6428accb138b22800a0caa2f5f0874bacc5909c652a57a31beda65eddd5889c04100102000605025331cf7a000a0910a401d9f09a34f7c0316403ff46f2a5c101256627f16384d34a38fb47a6c88ba60506843e532d91614339fccae5f884a5741e7582ffaf292ba38ee10a270a05f139bde3814b6a077e8cd2db0f105ebea2a83af70d385f13b507fac2ad93ff79d84950328bb86f3074745a8b7f9b64990fb142e2a12976e27e8d09a28dc5621f957ac49091116da410ac3cbde1b88d04533121f6010400cbd785b56905e4192e2fb62a720727d43c4fa487821203cf72138b884b78b701093243e1d8c92a0248a6c0203a5a88693da34af357499abacaf4b3309c640797d03093870a323b4b6f37865f6eaa2838148a67df4735d43a90ca87942554cdf1c4a751b1e75f9fd4ce4e97e278d6c1c7ed59d33441df7d084f3f02beb68896c70011010001889f0418010200090502533121f6021b0c000a09104ef7e4beccde97f0b98b03fc0a5ccf6a372995835a2f5da33b282a7d612c0ab2a97f59cf9fff73e9110981aac2858c41399afa29624a7fd8a0add11654e3d882c0fd199e161bdad65e5e2548f7b68a437ea64293db1246e3011cbb94dc1bcdeaf0f2539bd88ff16d95547144d97cead6a8c5927660a91e6db0d16eb36b7b49a3525b54d1644e65599b032b7eb901a204533127a0110400bd3edaa09eff9809c4edc2c2a0ebe52e53c50a19c1e49ab78e6167bf61473bb08f2050d78a5cbbc6ed66aff7b42cd503f16b4a0b99fa1609681fca9b7ce2bbb1a5b3864d6cdda4d7ef7849d156d534dea30fb0efb9e4cf8959a2b2ce623905882d5430b995a15c3b9fe92906086788b891002924f94abe139b42cbbfaaabe42f00a0b65dc1a1ad27d798adbcb5b5ad02d2688c89477b03ff4eebb6f7b15a73b96a96bed201c0e5e4ea27e4c6e2dd1005b94d4b90137a5b1cf5e01c6226c070c4cc999938101578877ee76d296b9aab8246d57049caacf489e80a3f40589cade790a020b1ac146d6f7a6241184b8c7fcde680eae3188f5dcbe846d7f7bdad34f6fcfca08413e19c1d5df83fc7c7c627d493492e009c2f52a80400a2fe82de87136fd2e8845888c4431b032ba29d9a29a804277e31002a8201fb8591a3e55c7a0d0881496caf8b9fb07544a5a4879291d0dc026a0ea9e5bd88eb4aa4947bbd694b25012e208a250d65ddc6f1eea59d3aed3b4ec15fcab85e2afaa23a40ab1ef9ce3e11e1bc1c34a0e758e7aa64deb8739276df0af7d4121f834a9b88e70418010200090502533127a0021b02005209104ef7e4beccde97f047200419110200060502533127a0000a0910dbce4ee19529437fe045009c0b32f5ead48ee8a7e98fac0dea3d3e6c0e2c552500a0ad71fadc5007cfaf842d9b7db3335a8cdad15d3d1a6404009b08e2c68fe8f3b45c1bb72a4b3278cdf3012aa0f229883ad74aa1f6000bb90b18301b2f85372ca5d6b9bf478d235b733b1b197d19ccca48e9daf8e890cb64546b4ce1b178faccfff07003c172a2d4f5ebaba9f57153955f3f61a9b80a4f5cb959908f8b211b03b7026a8a82fc612bfedd3794969bcf458c4ce92be215a1176ab88d045331d144010400a5063000c5aaf34953c1aa3bfc95045b3aab9882b9a8027fecfe2142dc6b47ba8aca667399990244d513dd0504716908c17d92c65e74219e004f7b83fc125e575dd58efec3ab6dd22e3580106998523dea42ec75bf9aa111734c82df54630bebdff20fe981cfc36c76f865eb1c2fb62c9e85bc3a6e5015a361a2eb1c8431578d0011010001889f04280102000905025331d433021d03000a09104ef7e4beccde97f02e5503ff5e0630d1b65291f4882b6d40a29da4616bb5088717d469fbcc3648b8276de04a04988b1f1b9f3e18f52265c1f8b6c85861691c1a6b8a3a25a1809a0b32ad330aec5667cb4262f4450649184e8113849b05e5ad06a316ea80c001e8e71838190339a6e48bbde30647bcf245134b9a97fa875c1d83a9862cae87ffd7e2c4ce3a1b89013d04180102000905025331d144021b0200a809104ef7e4beccde97f09d2004190102000605025331d144000a0910677815e371c2fd23522203fe22ab62b8e7a151383cea3edd3a12995693911426f8ccf125e1f6426388c0010f88d9ca7da2224aee8d1c12135998640c5e1813d55a93df472faae75bef858457248db41b4505827590aeccf6f9eb646da7f980655dd3050c6897feddddaca90676dee856d66db8923477d251712bb9b3186b4d0114daf7d6b59272b53218dd1da94a03ff64006fcbe71211e5daecd9961fba66cdb6de3f914882c58ba5beddeba7dcb950c1156d7fba18c19ea880dccc800eae335deec34e3b84ac75ffa24864f782f87815cda1c0f634b3dd2fa67cea30811d21723d21d9551fa12ccbcfa62b6d3a15d01307b99925707992556d50065505b090aadb8579083a20fe65bd2a270da9b011"
+
+const missingCrossSignatureKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Charset: UTF-8
+
+mQENBFMYynYBCACVOZ3/e8Bm2b9KH9QyIlHGo/i1bnkpqsgXj8tpJ2MIUOnXMMAY
+ztW7kKFLCmgVdLIC0vSoLA4yhaLcMojznh/2CcUglZeb6Ao8Gtelr//Rd5DRfPpG
+zqcfUo+m+eO1co2Orabw0tZDfGpg5p3AYl0hmxhUyYSc/xUq93xL1UJzBFgYXY54
+QsM8dgeQgFseSk/YvdP5SMx1ev+eraUyiiUtWzWrWC1TdyRa5p4UZg6Rkoppf+WJ
+QrW6BWrhAtqATHc8ozV7uJjeONjUEq24roRc/OFZdmQQGK6yrzKnnbA6MdHhqpdo
+9kWDcXYb7pSE63Lc+OBa5X2GUVvXJLS/3nrtABEBAAG0F2ludmFsaWQtc2lnbmlu
+Zy1zdWJrZXlziQEoBBMBAgASBQJTnKB5AhsBAgsHAhUIAh4BAAoJEO3UDQUIHpI/
+dN4H/idX4FQ1LIZCnpHS/oxoWQWfpRgdKAEM0qCqjMgiipJeEwSQbqjTCynuh5/R
+JlODDz85ABR06aoF4l5ebGLQWFCYifPnJZ/Yf5OYcMGtb7dIbqxWVFL9iLMO/oDL
+ioI3dotjPui5e+2hI9pVH1UHB/bZ/GvMGo6Zg0XxLPolKQODMVjpjLAQ0YJ3spew
+RAmOGre6tIvbDsMBnm8qREt7a07cBJ6XK7xjxYaZHQBiHVxyEWDa6gyANONx8duW
+/fhQ/zDTnyVM/ik6VO0Ty9BhPpcEYLFwh5c1ilFari1ta3e6qKo6ZGa9YMk/REhu
+yBHd9nTkI+0CiQUmbckUiVjDKKe5AQ0EUxjKdgEIAJcXQeP+NmuciE99YcJoffxv
+2gVLU4ZXBNHEaP0mgaJ1+tmMD089vUQAcyGRvw8jfsNsVZQIOAuRxY94aHQhIRHR
+bUzBN28ofo/AJJtfx62C15xt6fDKRV6HXYqAiygrHIpEoRLyiN69iScUsjIJeyFL
+C8wa72e8pSL6dkHoaV1N9ZH/xmrJ+k0vsgkQaAh9CzYufncDxcwkoP+aOlGtX1gP
+WwWoIbz0JwLEMPHBWvDDXQcQPQTYQyj+LGC9U6f9VZHN25E94subM1MjuT9OhN9Y
+MLfWaaIc5WyhLFyQKW2Upofn9wSFi8ubyBnv640Dfd0rVmaWv7LNTZpoZ/GbJAMA
+EQEAAYkBHwQYAQIACQUCU5ygeQIbAgAKCRDt1A0FCB6SP0zCB/sEzaVR38vpx+OQ
+MMynCBJrakiqDmUZv9xtplY7zsHSQjpd6xGflbU2n+iX99Q+nav0ETQZifNUEd4N
+1ljDGQejcTyKD6Pkg6wBL3x9/RJye7Zszazm4+toJXZ8xJ3800+BtaPoI39akYJm
++ijzbskvN0v/j5GOFJwQO0pPRAFtdHqRs9Kf4YanxhedB4dIUblzlIJuKsxFit6N
+lgGRblagG3Vv2eBszbxzPbJjHCgVLR3RmrVezKOsZjr/2i7X+xLWIR0uD3IN1qOW
+CXQxLBizEEmSNVNxsp7KPGTLnqO3bPtqFirxS9PJLIMPTPLNBY7ZYuPNTMqVIUWF
+4artDmrG
+=7FfJ
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const invalidCrossSignatureKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBFMYynYBCACVOZ3/e8Bm2b9KH9QyIlHGo/i1bnkpqsgXj8tpJ2MIUOnXMMAY
+ztW7kKFLCmgVdLIC0vSoLA4yhaLcMojznh/2CcUglZeb6Ao8Gtelr//Rd5DRfPpG
+zqcfUo+m+eO1co2Orabw0tZDfGpg5p3AYl0hmxhUyYSc/xUq93xL1UJzBFgYXY54
+QsM8dgeQgFseSk/YvdP5SMx1ev+eraUyiiUtWzWrWC1TdyRa5p4UZg6Rkoppf+WJ
+QrW6BWrhAtqATHc8ozV7uJjeONjUEq24roRc/OFZdmQQGK6yrzKnnbA6MdHhqpdo
+9kWDcXYb7pSE63Lc+OBa5X2GUVvXJLS/3nrtABEBAAG0F2ludmFsaWQtc2lnbmlu
+Zy1zdWJrZXlziQEoBBMBAgASBQJTnKB5AhsBAgsHAhUIAh4BAAoJEO3UDQUIHpI/
+dN4H/idX4FQ1LIZCnpHS/oxoWQWfpRgdKAEM0qCqjMgiipJeEwSQbqjTCynuh5/R
+JlODDz85ABR06aoF4l5ebGLQWFCYifPnJZ/Yf5OYcMGtb7dIbqxWVFL9iLMO/oDL
+ioI3dotjPui5e+2hI9pVH1UHB/bZ/GvMGo6Zg0XxLPolKQODMVjpjLAQ0YJ3spew
+RAmOGre6tIvbDsMBnm8qREt7a07cBJ6XK7xjxYaZHQBiHVxyEWDa6gyANONx8duW
+/fhQ/zDTnyVM/ik6VO0Ty9BhPpcEYLFwh5c1ilFari1ta3e6qKo6ZGa9YMk/REhu
+yBHd9nTkI+0CiQUmbckUiVjDKKe5AQ0EUxjKdgEIAIINDqlj7X6jYKc6DjwrOkjQ
+UIRWbQQar0LwmNilehmt70g5DCL1SYm9q4LcgJJ2Nhxj0/5qqsYib50OSWMcKeEe
+iRXpXzv1ObpcQtI5ithp0gR53YPXBib80t3bUzomQ5UyZqAAHzMp3BKC54/vUrSK
+FeRaxDzNLrCeyI00+LHNUtwghAqHvdNcsIf8VRumK8oTm3RmDh0TyjASWYbrt9c8
+R1Um3zuoACOVy+mEIgIzsfHq0u7dwYwJB5+KeM7ZLx+HGIYdUYzHuUE1sLwVoELh
++SHIGHI1HDicOjzqgajShuIjj5hZTyQySVprrsLKiXS6NEwHAP20+XjayJ/R3tEA
+EQEAAYkCPgQYAQIBKAUCU5ygeQIbAsBdIAQZAQIABgUCU5ygeQAKCRCpVlnFZmhO
+52RJB/9uD1MSa0wjY6tHOIgquZcP3bHBvHmrHNMw9HR2wRCMO91ZkhrpdS3ZHtgb
+u3/55etj0FdvDo1tb8P8FGSVtO5Vcwf5APM8sbbqoi8L951Q3i7qt847lfhu6sMl
+w0LWFvPTOLHrliZHItPRjOltS1WAWfr2jUYhsU9ytaDAJmvf9DujxEOsN5G1YJep
+54JCKVCkM/y585Zcnn+yxk/XwqoNQ0/iJUT9qRrZWvoeasxhl1PQcwihCwss44A+
+YXaAt3hbk+6LEQuZoYS73yR3WHj+42tfm7YxRGeubXfgCEz/brETEWXMh4pe0vCL
+bfWrmfSPq2rDegYcAybxRQz0lF8PAAoJEO3UDQUIHpI/exkH/0vQfdHA8g/N4T6E
+i6b1CUVBAkvtdJpCATZjWPhXmShOw62gkDw306vHPilL4SCvEEi4KzG72zkp6VsB
+DSRcpxCwT4mHue+duiy53/aRMtSJ+vDfiV1Vhq+3sWAck/yUtfDU9/u4eFaiNok1
+8/Gd7reyuZt5CiJnpdPpjCwelK21l2w7sHAnJF55ITXdOxI8oG3BRKufz0z5lyDY
+s2tXYmhhQIggdgelN8LbcMhWs/PBbtUr6uZlNJG2lW1yscD4aI529VjwJlCeo745
+U7pO4eF05VViUJ2mmfoivL3tkhoTUWhx8xs8xCUcCg8DoEoSIhxtOmoTPR22Z9BL
+6LCg2mg=
+=Dhm4
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const goodCrossSignatureKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mI0EVUqeVwEEAMufHRrMPWK3gyvi0O0tABCs/oON9zV9KDZlr1a1M91ShCSFwCPo
+7r80PxdWVWcj0V5h50/CJYtpN3eE/mUIgW2z1uDYQF1OzrQ8ubrksfsJvpAhENom
+lTQEppv9mV8qhcM278teb7TX0pgrUHLYF5CfPdp1L957JLLXoQR/lwLVABEBAAG0
+E2dvb2Qtc2lnbmluZy1zdWJrZXmIuAQTAQIAIgUCVUqeVwIbAwYLCQgHAwIGFQgC
+CQoLBBYCAwECHgECF4AACgkQNRjL95IRWP69XQQAlH6+eyXJN4DZTLX78KGjHrsw
+6FCvxxClEPtPUjcJy/1KCRQmtLAt9PbbA78dvgzjDeZMZqRAwdjyJhjyg/fkU2OH
+7wq4ktjUu+dLcOBb+BFMEY+YjKZhf6EJuVfxoTVr5f82XNPbYHfTho9/OABKH6kv
+X70PaKZhbwnwij8Nts65AaIEVUqftREEAJ3WxZfqAX0bTDbQPf2CMT2IVMGDfhK7
+GyubOZgDFFjwUJQvHNvsrbeGLZ0xOBumLINyPO1amIfTgJNm1iiWFWfmnHReGcDl
+y5mpYG60Mb79Whdcer7CMm3AqYh/dW4g6IB02NwZMKoUHo3PXmFLxMKXnWyJ0clw
+R0LI/Qn509yXAKDh1SO20rqrBM+EAP2c5bfI98kyNwQAi3buu94qo3RR1ZbvfxgW
+CKXDVm6N99jdZGNK7FbRifXqzJJDLcXZKLnstnC4Sd3uyfyf1uFhmDLIQRryn5m+
+LBYHfDBPN3kdm7bsZDDq9GbTHiFZUfm/tChVKXWxkhpAmHhU/tH6GGzNSMXuIWSO
+aOz3Rqq0ED4NXyNKjdF9MiwD/i83S0ZBc0LmJYt4Z10jtH2B6tYdqnAK29uQaadx
+yZCX2scE09UIm32/w7pV77CKr1Cp/4OzAXS1tmFzQ+bX7DR+Gl8t4wxr57VeEMvl
+BGw4Vjh3X8//m3xynxycQU18Q1zJ6PkiMyPw2owZ/nss3hpSRKFJsxMLhW3fKmKr
+Ey2KiOcEGAECAAkFAlVKn7UCGwIAUgkQNRjL95IRWP5HIAQZEQIABgUCVUqftQAK
+CRD98VjDN10SqkWrAKDTpEY8D8HC02E/KVC5YUI01B30wgCgurpILm20kXEDCeHp
+C5pygfXw1DJrhAP+NyPJ4um/bU1I+rXaHHJYroYJs8YSweiNcwiHDQn0Engh/mVZ
+SqLHvbKh2dL/RXymC3+rjPvQf5cup9bPxNMa6WagdYBNAfzWGtkVISeaQW+cTEp/
+MtgVijRGXR/lGLGETPg2X3Afwn9N9bLMBkBprKgbBqU7lpaoPupxT61bL70=
+=vtbN
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const revokedUserIDKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBFsgO5EBCADhREPmcjsPkXe1z7ctvyWL0S7oa9JaoGZ9oPDHFDlQxd0qlX2e
+DZJZDg0qYvVixmaULIulApq1puEsaJCn3lHUbHlb4PYKwLEywYXM28JN91KtLsz/
+uaEX2KC5WqeP40utmzkNLq+oRX/xnRMgwbO7yUNVG2UlEa6eI+xOXO3YtLdmJMBW
+ClQ066ZnOIzEo1JxnIwha1CDBMWLLfOLrg6l8InUqaXbtEBbnaIYO6fXVXELUjkx
+nmk7t/QOk0tXCy8muH9UDqJkwDUESY2l79XwBAcx9riX8vY7vwC34pm22fAUVLCJ
+x1SJx0J8bkeNp38jKM2Zd9SUQqSbfBopQ4pPABEBAAG0I0dvbGFuZyBHb3BoZXIg
+PG5vLXJlcGx5QGdvbGFuZy5jb20+iQFUBBMBCgA+FiEE5Ik5JLcNx6l6rZfw1oFy
+9I6cUoMFAlsgO5ECGwMFCQPCZwAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ
+1oFy9I6cUoMIkwf8DNPeD23i4jRwd/pylbvxwZintZl1fSwTJW1xcOa1emXaEtX2
+depuqhP04fjlRQGfsYAQh7X9jOJxAHjTmhqFBi5sD7QvKU00cPFYbJ/JTx0B41bl
+aXnSbGhRPh63QtEZL7ACAs+shwvvojJqysx7kyVRu0EW2wqjXdHwR/SJO6nhNBa2
+DXzSiOU/SUA42mmG+5kjF8Aabq9wPwT9wjraHShEweNerNMmOqJExBOy3yFeyDpa
+XwEZFzBfOKoxFNkIaVf5GSdIUGhFECkGvBMB935khftmgR8APxdU4BE7XrXexFJU
+8RCuPXonm4WQOwTWR0vQg64pb2WKAzZ8HhwTGbQiR29sYW5nIEdvcGhlciA8cmV2
+b2tlZEBnb2xhbmcuY29tPokBNgQwAQoAIBYhBOSJOSS3Dcepeq2X8NaBcvSOnFKD
+BQJbIDv3Ah0AAAoJENaBcvSOnFKDfWMIAKhI/Tvu3h8fSUxp/gSAcduT6bC1JttG
+0lYQ5ilKB/58lBUA5CO3ZrKDKlzW3M8VEcvohVaqeTMKeoQd5rCZq8KxHn/KvN6N
+s85REfXfniCKfAbnGgVXX3kDmZ1g63pkxrFu0fDZjVDXC6vy+I0sGyI/Inro0Pzb
+tvn0QCsxjapKK15BtmSrpgHgzVqVg0cUp8vqZeKFxarYbYB2idtGRci4b9tObOK0
+BSTVFy26+I/mrFGaPrySYiy2Kz5NMEcRhjmTxJ8jSwEr2O2sUR0yjbgUAXbTxDVE
+/jg5fQZ1ACvBRQnB7LvMHcInbzjyeTM3FazkkSYQD6b97+dkWwb1iWG5AQ0EWyA7
+kQEIALkg04REDZo1JgdYV4x8HJKFS4xAYWbIva1ZPqvDNmZRUbQZR2+gpJGEwn7z
+VofGvnOYiGW56AS5j31SFf5kro1+1bZQ5iOONBng08OOo58/l1hRseIIVGB5TGSa
+PCdChKKHreJI6hS3mShxH6hdfFtiZuB45rwoaArMMsYcjaezLwKeLc396cpUwwcZ
+snLUNd1Xu5EWEF2OdFkZ2a1qYdxBvAYdQf4+1Nr+NRIx1u1NS9c8jp3PuMOkrQEi
+bNtc1v6v0Jy52mKLG4y7mC/erIkvkQBYJdxPaP7LZVaPYc3/xskcyijrJ/5ufoD8
+K71/ShtsZUXSQn9jlRaYR0EbojMAEQEAAYkBPAQYAQoAJhYhBOSJOSS3Dcepeq2X
+8NaBcvSOnFKDBQJbIDuRAhsMBQkDwmcAAAoJENaBcvSOnFKDkFMIAIt64bVZ8x7+
+TitH1bR4pgcNkaKmgKoZz6FXu80+SnbuEt2NnDyf1cLOSimSTILpwLIuv9Uft5Pb
+OraQbYt3xi9yrqdKqGLv80bxqK0NuryNkvh9yyx5WoG1iKqMj9/FjGghuPrRaT4l
+QinNAghGVkEy1+aXGFrG2DsOC1FFI51CC2WVTzZ5RwR2GpiNRfESsU1rZAUqf/2V
+yJl9bD5R4SUNy8oQmhOxi+gbhD4Ao34e4W0ilibslI/uawvCiOwlu5NGd8zv5n+U
+heiQvzkApQup5c+BhH5zFDFdKJ2CBByxw9+7QjMFI/wgLixKuE0Ob2kAokXf7RlB
+7qTZOahrETw=
+=IKnw
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const keyWithFirstUserIDRevoked = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: OpenPGP.js v4.10.10
+Comment: https://openpgpjs.org
+
+xsBNBFsgO5EBCADhREPmcjsPkXe1z7ctvyWL0S7oa9JaoGZ9oPDHFDlQxd0q
+lX2eDZJZDg0qYvVixmaULIulApq1puEsaJCn3lHUbHlb4PYKwLEywYXM28JN
+91KtLsz/uaEX2KC5WqeP40utmzkNLq+oRX/xnRMgwbO7yUNVG2UlEa6eI+xO
+XO3YtLdmJMBWClQ066ZnOIzEo1JxnIwha1CDBMWLLfOLrg6l8InUqaXbtEBb
+naIYO6fXVXELUjkxnmk7t/QOk0tXCy8muH9UDqJkwDUESY2l79XwBAcx9riX
+8vY7vwC34pm22fAUVLCJx1SJx0J8bkeNp38jKM2Zd9SUQqSbfBopQ4pPABEB
+AAHNIkdvbGFuZyBHb3BoZXIgPHJldm9rZWRAZ29sYW5nLmNvbT7CwI0EMAEK
+ACAWIQTkiTkktw3HqXqtl/DWgXL0jpxSgwUCWyA79wIdAAAhCRDWgXL0jpxS
+gxYhBOSJOSS3Dcepeq2X8NaBcvSOnFKDfWMIAKhI/Tvu3h8fSUxp/gSAcduT
+6bC1JttG0lYQ5ilKB/58lBUA5CO3ZrKDKlzW3M8VEcvohVaqeTMKeoQd5rCZ
+q8KxHn/KvN6Ns85REfXfniCKfAbnGgVXX3kDmZ1g63pkxrFu0fDZjVDXC6vy
++I0sGyI/Inro0Pzbtvn0QCsxjapKK15BtmSrpgHgzVqVg0cUp8vqZeKFxarY
+bYB2idtGRci4b9tObOK0BSTVFy26+I/mrFGaPrySYiy2Kz5NMEcRhjmTxJ8j
+SwEr2O2sUR0yjbgUAXbTxDVE/jg5fQZ1ACvBRQnB7LvMHcInbzjyeTM3Fazk
+kSYQD6b97+dkWwb1iWHNI0dvbGFuZyBHb3BoZXIgPG5vLXJlcGx5QGdvbGFu
+Zy5jb20+wsCrBBMBCgA+FiEE5Ik5JLcNx6l6rZfw1oFy9I6cUoMFAlsgO5EC
+GwMFCQPCZwAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AAIQkQ1oFy9I6cUoMW
+IQTkiTkktw3HqXqtl/DWgXL0jpxSgwiTB/wM094PbeLiNHB3+nKVu/HBmKe1
+mXV9LBMlbXFw5rV6ZdoS1fZ16m6qE/Th+OVFAZ+xgBCHtf2M4nEAeNOaGoUG
+LmwPtC8pTTRw8Vhsn8lPHQHjVuVpedJsaFE+HrdC0RkvsAICz6yHC++iMmrK
+zHuTJVG7QRbbCqNd0fBH9Ik7qeE0FrYNfNKI5T9JQDjaaYb7mSMXwBpur3A/
+BP3COtodKETB416s0yY6okTEE7LfIV7IOlpfARkXMF84qjEU2QhpV/kZJ0hQ
+aEUQKQa8EwH3fmSF+2aBHwA/F1TgETtetd7EUlTxEK49eiebhZA7BNZHS9CD
+rilvZYoDNnweHBMZzsBNBFsgO5EBCAC5INOERA2aNSYHWFeMfByShUuMQGFm
+yL2tWT6rwzZmUVG0GUdvoKSRhMJ+81aHxr5zmIhluegEuY99UhX+ZK6NftW2
+UOYjjjQZ4NPDjqOfP5dYUbHiCFRgeUxkmjwnQoSih63iSOoUt5kocR+oXXxb
+YmbgeOa8KGgKzDLGHI2nsy8Cni3N/enKVMMHGbJy1DXdV7uRFhBdjnRZGdmt
+amHcQbwGHUH+PtTa/jUSMdbtTUvXPI6dz7jDpK0BImzbXNb+r9CcudpiixuM
+u5gv3qyJL5EAWCXcT2j+y2VWj2HN/8bJHMoo6yf+bn6A/Cu9f0obbGVF0kJ/
+Y5UWmEdBG6IzABEBAAHCwJMEGAEKACYWIQTkiTkktw3HqXqtl/DWgXL0jpxS
+gwUCWyA7kQIbDAUJA8JnAAAhCRDWgXL0jpxSgxYhBOSJOSS3Dcepeq2X8NaB
+cvSOnFKDkFMIAIt64bVZ8x7+TitH1bR4pgcNkaKmgKoZz6FXu80+SnbuEt2N
+nDyf1cLOSimSTILpwLIuv9Uft5PbOraQbYt3xi9yrqdKqGLv80bxqK0NuryN
+kvh9yyx5WoG1iKqMj9/FjGghuPrRaT4lQinNAghGVkEy1+aXGFrG2DsOC1FF
+I51CC2WVTzZ5RwR2GpiNRfESsU1rZAUqf/2VyJl9bD5R4SUNy8oQmhOxi+gb
+hD4Ao34e4W0ilibslI/uawvCiOwlu5NGd8zv5n+UheiQvzkApQup5c+BhH5z
+FDFdKJ2CBByxw9+7QjMFI/wgLixKuE0Ob2kAokXf7RlB7qTZOahrETw=
+=+2T8
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const keyWithOnlyUserIDRevoked = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mDMEYYwB7RYJKwYBBAHaRw8BAQdARimqhPPzyGAXmfQJjcqM1QVPzLtURJSzNVll
+JV4tEaW0KVJldm9rZWQgUHJpbWFyeSBVc2VyIElEIDxyZXZva2VkQGtleS5jb20+
+iHgEMBYIACAWIQSpyJZAXYqVEFkjyKutFcS0yeB0LQUCYYwCtgIdAAAKCRCtFcS0
+yeB0LbSsAQD8OYMaaBjrdzzpwIkP1stgmPd4/kzN/ZG28Ywl6a5F5QEA5Xg7aq4e
+/t6Fsb4F5iqB956kSPe6YJrikobD/tBbMwSIkAQTFggAOBYhBKnIlkBdipUQWSPI
+q60VxLTJ4HQtBQJhjAHtAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEK0V
+xLTJ4HQtBaoBAPZL7luTCji+Tqhn7XNfFE/0QIahCt8k9wfO1cGlB3inAQDf8Tzw
+ZGR5fNluUcNoVxQT7bUSFStbaGo3k0BaOYPbCLg4BGGMAe0SCisGAQQBl1UBBQEB
+B0DLwSpveSrbIO/IVZD13yrs1XuB3FURZUnafGrRq7+jUAMBCAeIeAQYFggAIBYh
+BKnIlkBdipUQWSPIq60VxLTJ4HQtBQJhjAHtAhsMAAoJEK0VxLTJ4HQtZ1oA/j9u
+8+p3xTNzsmabTL6BkNbMeB/RUKCrlm6woM6AV+vxAQCcXTn3JC2sNoNrLoXuVzaA
+mcG3/TwG5GSQUUPkrDsGDA==
+=mFWy
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const keyWithSubKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mI0EWyKwKQEEALwXhKBnyaaNFeK3ljfc/qn9X/QFw+28EUfgZPHjRmHubuXLE2uR
+s3ZoSXY2z7Dkv+NyHYMt8p+X8q5fR7JvUjK2XbPyKoiJVnHINll83yl67DaWfKNL
+EjNoO0kIfbXfCkZ7EG6DL+iKtuxniGTcnGT47e+HJSqb/STpLMnWwXjBABEBAAG0
+I0dvbGFuZyBHb3BoZXIgPG5vLXJlcGx5QGdvbGFuZy5jb20+iM4EEwEKADgWIQQ/
+lRafP/p9PytHbwxMvYJsOQdOOAUCWyKwKQIbAwULCQgHAwUVCgkICwUWAgMBAAIe
+AQIXgAAKCRBMvYJsOQdOOOsFBAC62mXww8XuqvYLcVOvHkWLT6mhxrQOJXnlfpn7
+2uBV9CMhoG/Ycd43NONsJrB95Apr9TDIqWnVszNbqPCuBhZQSGLdbiDKjxnCWBk0
+69qv4RNtkpOhYB7jK4s8F5oQZqId6JasT/PmJTH92mhBYhhTQr0GYFuPX2UJdkw9
+Sn9C67iNBFsisDUBBAC3A+Yo9lgCnxi/pfskyLrweYif6kIXWLAtLTsM6g/6jt7b
+wTrknuCPyTv0QKGXsAEe/cK/Xq3HvX9WfXPGIHc/X56ZIsHQ+RLowbZV/Lhok1IW
+FAuQm8axr/by80cRwFnzhfPc/ukkAq2Qyj4hLsGblu6mxeAhzcp8aqmWOO2H9QAR
+AQABiLYEKAEKACAWIQQ/lRafP/p9PytHbwxMvYJsOQdOOAUCWyK16gIdAAAKCRBM
+vYJsOQdOOB1vA/4u4uLONsE+2GVOyBsHyy7uTdkuxaR9b54A/cz6jT/tzUbeIzgx
+22neWhgvIEghnUZd0vEyK9k1wy5vbDlEo6nKzHso32N1QExGr5upRERAxweDxGOj
+7luDwNypI7QcifE64lS/JmlnunwRCdRWMKc0Fp+7jtRc5mpwyHN/Suf5RokBagQY
+AQoAIBYhBD+VFp8/+n0/K0dvDEy9gmw5B044BQJbIrA1AhsCAL8JEEy9gmw5B044
+tCAEGQEKAB0WIQSNdnkaWY6t62iX336UXbGvYdhXJwUCWyKwNQAKCRCUXbGvYdhX
+JxJSA/9fCPHP6sUtGF1o3G1a3yvOUDGr1JWcct9U+QpbCt1mZoNopCNDDQAJvDWl
+mvDgHfuogmgNJRjOMznvahbF+wpTXmB7LS0SK412gJzl1fFIpK4bgnhu0TwxNsO1
+8UkCZWqxRMgcNUn9z6XWONK8dgt5JNvHSHrwF4CxxwjL23AAtK+FA/UUoi3U4kbC
+0XnSr1Sl+mrzQi1+H7xyMe7zjqe+gGANtskqexHzwWPUJCPZ5qpIa2l8ghiUim6b
+4ymJ+N8/T8Yva1FaPEqfMzzqJr8McYFm0URioXJPvOAlRxdHPteZ0qUopt/Jawxl
+Xt6B9h1YpeLoJwjwsvbi98UTRs0jXwoY
+=3fWu
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const keyWithSubKeyAndBadSelfSigOrder = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mI0EWyLLDQEEAOqIOpJ/ha1OYAGduu9tS3rBz5vyjbNgJO4sFveEM0mgsHQ0X9/L
+plonW+d0gRoO1dhJ8QICjDAc6+cna1DE3tEb5m6JtQ30teLZuqrR398Cf6w7NNVz
+r3lrlmnH9JaKRuXl7tZciwyovneBfZVCdtsRZjaLI1uMQCz/BToiYe3DABEBAAG0
+I0dvbGFuZyBHb3BoZXIgPG5vLXJlcGx5QGdvbGFuZy5jb20+iM4EEwEKADgWIQRZ
+sixZOfQcZdW0wUqmgmdsv1O9xgUCWyLLDQIbAwULCQgHAwUVCgkICwUWAgMBAAIe
+AQIXgAAKCRCmgmdsv1O9xql2A/4pix98NxjhdsXtazA9agpAKeADf9tG4Za27Gj+
+3DCww/E4iP2X35jZimSm/30QRB6j08uGCqd9vXkkJxtOt63y/IpVOtWX6vMWSTUm
+k8xKkaYMP0/IzKNJ1qC/qYEUYpwERBKg9Z+k99E2Ql4kRHdxXUHq6OzY79H18Y+s
+GdeM/riNBFsiyxsBBAC54Pxg/8ZWaZX1phGdwfe5mek27SOYpC0AxIDCSOdMeQ6G
+HPk38pywl1d+S+KmF/F4Tdi+kWro62O4eG2uc/T8JQuRDUhSjX0Qa51gPzJrUOVT
+CFyUkiZ/3ZDhtXkgfuso8ua2ChBgR9Ngr4v43tSqa9y6AK7v0qjxD1x+xMrjXQAR
+AQABiQFxBBgBCgAmAhsCFiEEWbIsWTn0HGXVtMFKpoJnbL9TvcYFAlsizTIFCQAN
+MRcAv7QgBBkBCgAdFiEEJcoVUVJIk5RWj1c/o62jUpRPICQFAlsiyxsACgkQo62j
+UpRPICQq5gQApoWIigZxXFoM0uw4uJBS5JFZtirTANvirZV5RhndwHeMN6JttaBS
+YnjyA4+n1D+zB2VqliD2QrsX12KJN6rGOehCtEIClQ1Hodo9nC6kMzzAwW1O8bZs
+nRJmXV+bsvD4sidLZLjdwOVa3Cxh6pvq4Uur6a7/UYx121hEY0Qx0s8JEKaCZ2y/
+U73GGi0D/i20VW8AWYAPACm2zMlzExKTOAV01YTQH/3vW0WLrOse53WcIVZga6es
+HuO4So0SOEAvxKMe5HpRIu2dJxTvd99Bo9xk9xJU0AoFrO0vNCRnL+5y68xMlODK
+lEw5/kl0jeaTBp6xX0HDQOEVOpPGUwWV4Ij2EnvfNDXaE1vK1kffiQFrBBgBCgAg
+AhsCFiEEWbIsWTn0HGXVtMFKpoJnbL9TvcYFAlsi0AYAv7QgBBkBCgAdFiEEJcoV
+UVJIk5RWj1c/o62jUpRPICQFAlsiyxsACgkQo62jUpRPICQq5gQApoWIigZxXFoM
+0uw4uJBS5JFZtirTANvirZV5RhndwHeMN6JttaBSYnjyA4+n1D+zB2VqliD2QrsX
+12KJN6rGOehCtEIClQ1Hodo9nC6kMzzAwW1O8bZsnRJmXV+bsvD4sidLZLjdwOVa
+3Cxh6pvq4Uur6a7/UYx121hEY0Qx0s8JEKaCZ2y/U73GRl0EAJokkXmy4zKDHWWi
+wvK9gi2gQgRkVnu2AiONxJb5vjeLhM/07BRmH6K1o+w3fOeEQp4FjXj1eQ5fPSM6
+Hhwx2CTl9SDnPSBMiKXsEFRkmwQ2AAsQZLmQZvKBkLZYeBiwf+IY621eYDhZfo+G
+1dh1WoUCyREZsJQg2YoIpWIcvw+a
+=bNRo
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const onlySubkeyNoPrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1
+
+lQCVBFggvocBBAC7vBsHn7MKmS6IiiZNTXdciplVgS9cqVd+RTdIAoyNTcsiV1H0
+GQ3QtodOPeDlQDNoqinqaobd7R9g3m3hS53Nor7yBZkCWQ5x9v9JxRtoAq0sklh1
+I1X2zEqZk2l6YrfBF/64zWrhjnW3j23szkrAIVu0faQXbQ4z56tmZrw11wARAQAB
+/gdlAkdOVQG0CUdOVSBEdW1teYi4BBMBAgAiBQJYIL6HAhsDBgsJCAcDAgYVCAIJ
+CgsEFgIDAQIeAQIXgAAKCRCd1xxWp1CYAnjGA/9synn6ZXJUKAXQzySgmCZvCIbl
+rqBfEpxwLG4Q/lONhm5vthAE0z49I8hj5Gc5e2tLYUtq0o0OCRdCrYHa/efOYWpJ
+6RsK99bePOisVzmOABLIgZkcr022kHoMCmkPgv9CUGKP1yqbGl+zzAwQfUjRUmvD
+ZIcWLHi2ge4GzPMPi50B2ARYIL6cAQQAxWHnicKejAFcFcF1/3gUSgSH7eiwuBPX
+M7vDdgGzlve1o1jbV4tzrjN9jsCl6r0nJPDMfBSzgLr1auNTRG6HpJ4abcOx86ED
+Ad+avDcQPZb7z3dPhH/gb2lQejZsHh7bbeOS8WMSzHV3RqCLd8J/xwWPNR5zKn1f
+yp4IGfopidMAEQEAAQAD+wQOelnR82+dxyM2IFmZdOB9wSXQeCVOvxSaNMh6Y3lk
+UOOkO8Nlic4x0ungQRvjoRs4wBmCuwFK/MII6jKui0B7dn/NDf51i7rGdNGuJXDH
+e676By1sEY/NGkc74jr74T+5GWNU64W0vkpfgVmjSAzsUtpmhJMXsc7beBhJdnVl
+AgDKCb8hZqj1alcdmLoNvb7ibA3K/V8J462CPD7bMySPBa/uayoFhNxibpoXml2r
+oOtHa5izF3b0/9JY97F6rqkdAgD6GdTJ+xmlCoz1Sewoif1I6krq6xoa7gOYpIXo
+UL1Afr+LiJeyAnF/M34j/kjIVmPanZJjry0kkjHE5ILjH3uvAf4/6n9np+Th8ujS
+YDCIzKwR7639+H+qccOaddCep8Y6KGUMVdD/vTKEx1rMtK+hK/CDkkkxnFslifMJ
+kqoqv3WUqCWJAT0EGAECAAkFAlggvpwCGwIAqAkQndccVqdQmAKdIAQZAQIABgUC
+WCC+nAAKCRDmGUholQPwvQk+A/9latnSsR5s5/1A9TFki11GzSEnfLbx46FYOdkW
+n3YBxZoPQGxNA1vIn8GmouxZInw9CF4jdOJxEdzLlYQJ9YLTLtN5tQEMl/19/bR8
+/qLacAZ9IOezYRWxxZsyn6//jfl7A0Y+FV59d4YajKkEfItcIIlgVBSW6T+TNQT3
+R+EH5HJ/A/4/AN0CmBhhE2vGzTnVU0VPrE4V64pjn1rufFdclgpixNZCuuqpKpoE
+VVHn6mnBf4njKjZrAGPs5kfQ+H4NsM7v3Zz4yV6deu9FZc4O6E+V1WJ38rO8eBix
+7G2jko106CC6vtxsCPVIzY7aaG3H5pjRtomw+pX7SzrQ7FUg2PGumg==
+=F/T0
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const ecdsaPrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+xaUEX1KsSRMIKoZIzj0DAQcCAwTpYqJsnJiFhKKh+8TulWD+lVmerBFNS+Ii
+B+nlG3T0xQQ4Sy5eIjJ0CExIQQzi3EElF/Z2l4F3WC5taFA11NgA/gkDCHSS
+PThf1M2K4LN8F1MRcvR+sb7i0nH55ojkwuVB1DE6jqIT9m9i+mX1tzjSAS+6
+lPQiweCJvG7xTC7Hs3AzRapf/r1At4TB+v+5G2/CKynNFEJpbGwgPGJpbGxA
+aG9tZS5jb20+wncEEBMIAB8FAl9SrEkGCwkHCAMCBBUICgIDFgIBAhkBAhsD
+Ah4BAAoJEMpwT3+q3+xqw5UBAMebZN9isEZ1ML+R/jWAAWMwa/knMugrEZ1v
+Bl9+ZwM0AQCZdf80/wYY4Nve01qSRFv8OmKswLli3TvDv6FKc4cLz8epBF9S
+rEkSCCqGSM49AwEHAgMEAjKnT9b5wY2bf9TpAV3d7OUfPOxKj9c4VzeVzSrH
+AtQgo/MuI1cdYVURicV4i76DNjFhQHQFTk7BrC+C2u1yqQMBCAf+CQMIHImA
+iYfzQtjgQWSFZYUkCFpbbwhNF0ch+3HNaZkaHCnZRIsWsRnc6FCb6lRQyK9+
+Dq59kHlduE5QgY40894jfmP2JdJHU6nBdYrivbEdbMJhBBgTCAAJBQJfUqxJ
+AhsMAAoJEMpwT3+q3+xqUI0BAMykhV08kQ4Ip9Qlbss6Jdufv7YrU0Vd5hou
+b5TmiPd0APoDBh3qIic+aLLUcAuG3+Gt1P1AbUlmqV61ozn1WfHxfw==
+=KLN8
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const dsaPrivateKeyWithElGamalSubkey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+lQOBBF9/MLsRCACeaF6BI0jTgDAs86t8/kXPfwlPvR2MCYzB0BCqAdcq1hV/GTYd
+oNmJRna/ZJfsI/vf+d8Nv+EYOQkPheFS1MJVBitkAXjQPgm8i1tQWen1FCWZxqGk
+/vwZYF4yo8GhZ+Wxi3w09W9Cp9QM/CTmyE1Xe7wpPBGe+oD+me8Zxjyt8JBS4Qx+
+gvWbfHxfHnggh4pz7U8QkItlLsBNQEdX4R5+zwRN66g2ZSX/shaa/EkVnihUhD7r
+njP9I51ORWucTQD6OvgooaNQZCkQ/Se9TzdakwWKS2XSIFXiY/e2E5ZgKI/pfKDU
+iA/KessxddPb7nP/05OIJqg9AoDrD4vmehLzAQD+zsUS3LDU1m9/cG4LMsQbT2VK
+Te4HqbGIAle+eu/asQf8DDJMrbZpiJZvADum9j0TJ0oep6VdMbzo9RSDKvlLKT9m
+kG63H8oDWnCZm1a+HmGq9YIX+JHWmsLXXsFLeEouLzHO+mZo0X28eji3V2T87hyR
+MmUM0wFo4k7jK8uVmkDXv3XwNp2uByWxUKZd7EnWmcEZWqIiexJ7XpCS0Pg3tRaI
+zxve0SRe/dxfUPnTk/9KQ9hS6DWroBKquL182zx1Fggh4LIWWE2zq+UYn8BI0E8A
+rmIDFJdF8ymFQGRrEy6g79NnkPmkrZWsgMRYY65P6v4zLVmqohJKkpm3/Uxa6QAP
+CCoPh/JTOvPeCP2bOJH8z4Z9Py3ouMIjofQW8sXqRgf/RIHbh0KsINHrwwZ4gVIr
+MK3RofpaYxw1ztPIWb4cMWoWZHH1Pxh7ggTGSBpAhKXkiWw2Rxat8QF5aA7e962c
+bLvVv8dqsPrD/RnVJHag89cbPTzjn7gY9elE8EM8ithV3oQkwHTr4avYlpDZsgNd
+hUW3YgRwGo31tdzxoG04AcpV2t+07P8XMPr9hsfWs4rHohXPi38Hseu1Ji+dBoWQ
+3+1w/HH3o55s+jy4Ruaz78AIrjbmAJq+6rA2mIcCgrhw3DnzuwQAKeBvSeqn9zfS
+ZC812osMBVmkycwelpaIh64WZ0vWL3GvdXDctV2kXM+qVpDTLEny0LuiXxrwCKQL
+Ev4HAwK9uQBcreDEEud7pfRb8EYP5lzO2ZA7RaIvje6EWAGBvJGMRT0QQE5SGqc7
+Fw5geigBdt+vVyRuNNhg3c2fdn/OBQaYu0J/8AiOogG8EaM8tCFlbGdhbWFsQGRz
+YS5jb20gPGVsZ2FtYWxAZHNhLmNvbT6IkAQTEQgAOBYhBI+gnfiHQxB35/Dp0XAQ
+aE/rsWC5BQJffzC7AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEHAQaE/r
+sWC5A4EA/0GcJmyPtN+Klc7b9sVT3JgKTRnB/URxOJfYJofP0hZLAQCkqyMO+adV
+JvbgDH0zaITQWZSSXPqpgMpCA6juTrDsd50CawRffzC7EAgAxFFFSAAEQzWTgKU5
+EBtpxxoPzHqcChawTHRxHxjcELXzmUBS5PzfA1HXSPnNqK/x3Ut5ycC3CsW41Fnt
+Gm3706Wu9VFbFZVn55F9lPiplUo61n5pqMvOr1gmuQsdXiTa0t5FRa4TZ2VSiHFw
+vdAVSPTUsT4ZxJ1rPyFYRtq1n3pQcvdZowd07r0JnzTMjLLMFYCKhwIowoOC4zqJ
+iB8enjwOlpaqBATRm9xpVF7SJkroPF6/B1vdhj7E3c1aJyHlo0PYBAg756sSHWHg
+UuLyUQ4TA0hcCVenn/L/aSY2LnbdZB1EBhlYjA7dTCgwIqsQhfQmPkjz6g64A7+Y
+HbbrLwADBQgAk14QIEQ+J/VHetpQV/jt2pNsFK1kVK7mXK0spTExaC2yj2sXlHjL
+Ie3bO5T/KqmIaBEB5db5fA5xK9cZt79qrQHDKsEqUetUeMUWLBx77zBsus3grIgy
+bwDZKseRzQ715pwxquxQlScGoDIBKEh08HpwHkq140eIj3w+MAIfndaZaSCNaxaP
+Snky7BQmJ7Wc7qrIwoQP6yrnUqyW2yNi81nJYUhxjChqaFSlwzLs/iNGryBKo0ic
+BqVIRjikKHBlwBng6WyrltQo/Vt9GG8w+lqaAVXbJRlaBZJUR+2NKi/YhP3qQse3
+v8fi4kns0gh5LK+2C01RvdX4T49QSExuIf4HAwLJqYIGwadA2uem5v7/765ZtFWV
+oL0iZ0ueTJDby4wTFDpLVzzDi/uVcB0ZRFrGOp7w6OYcNYTtV8n3xmli2Q5Trw0c
+wZVzvg+ABKWiv7faBjMczIFF8y6WZKOIeAQYEQgAIBYhBI+gnfiHQxB35/Dp0XAQ
+aE/rsWC5BQJffzC7AhsMAAoJEHAQaE/rsWC5ZmIA/jhS4r4lClbvjuPWt0Yqdn7R
+fss2SPMYvMrrDh42aE0OAQD8xn4G6CN8UtW9xihXOY6FpxiJ/sMc2VaneeUd34oa
+4g==
+=XZm8
+-----END PGP PRIVATE KEY BLOCK-----`
+
+// https://tests.sequoia-pgp.org/#Certificate_expiration
+// P _ U p
+const expiringPrimaryUIDKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+xsDNBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv
+/seOXpgecTdOcVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz
+/56fW2O0F23qIRd8UUJp5IIlN4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/
+5whqsyroEWDJoSV0yOb25B/iwk/pLUFoyhDG9bj0kIzDxrEqW+7Ba8nocQlecMF3
+X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8Je/ECwUWYUiAZxLIlMv
+9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx5wRZ4F0
+qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7eb
+SGXrl5ZMpbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wb
+vLIwa3T4CyshfT0AEQEAAc0hQm9iIEJhYmJhZ2UgPGJvYkBvcGVucGdwLmV4YW1w
+bGU+wsFcBBMBCgCQBYJhesp/BYkEWQPJBQsJCAcCCRD7/MgqAV5zMEcUAAAAAAAe
+ACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmeEOQlNyTLFkc9I/elp+BpY
+495V7KatqtDmsyDr+zDAdwYVCgkICwIEFgIDAQIXgAIbAwIeARYhBNGmbhojsYLJ
+mA94jPv8yCoBXnMwAABSCQv/av8hKyynMtXVKFuWOGJw0mR8auDm84WdhMFRZg8t
+yTJ1L88+Ny4WUAFeqo2j7DU2yPGrm5rmuvzlEedFYFeOWt+A4adz+oumgRd0nsgG
+Lf3QYUWQhLWVlz+H7zubgKqSB2A2RqV65S7mTTVro42nb2Mng6rvGWiqeKG5nrXN
+/01p1mIBQGR/KnZSqYLzA2Pw2PiJoSkXT26PDz/kiEMXpjKMR6sicV4bKVlEdUvm
+pIImIPBHZq1EsKXEyWtWC41w/pc+FofGE+uSFs2aef1vvEHFkj3BHSK8gRcH3kfR
+eFroTET8C2q9V1AOELWm+Ys6PzGzF72URK1MKXlThuL4t4LjvXWGNA78IKW+/RQH
+DzK4U0jqSO0mL6qxqVS5Ij6jjL6OTrVEGdtDf5n0vI8tcUTBKtVqYAYk+t2YGT05
+ayxALtb7viVKo8f10WEcCuKshn0gdsEFMRZQzJ89uQIY3R3FbsdRCaE6OEaDgKMQ
+UTFROyfhthgzRKbRxfcplMUCzsDNBF2lnPIBDADWML9cbGMrp12CtF9b2P6z9TTT
+74S8iyBOzaSvdGDQY/sUtZXRg21HWamXnn9sSXvIDEINOQ6A9QxdxoqWdCHrOuW3
+ofneYXoG+zeKc4dC86wa1TR2q9vW+RMXSO4uImA+Uzula/6k1DogDf28qhCxMwG/
+i/m9g1c/0aApuDyKdQ1PXsHHNlgd/Dn6rrd5y2AObaifV7wIhEJnvqgFXDN2RXGj
+LeCOHV4Q2WTYPg/S4k1nMXVDwZXrvIsA0YwIMgIT86Rafp1qKlgPNbiIlC1g9RY/
+iFaGN2b4Ir6GDohBQSfZW2+LXoPZuVE/wGlQ01rh827KVZW4lXvqsge+wtnWlszc
+selGATyzqOK9LdHPdZGzROZYI2e8c+paLNDdVPL6vdRBUnkCaEkOtl1mr2JpQi5n
+TU+gTX4IeInC7E+1a9UDF/Y85ybUz8XV8rUnR76UqVC7KidNepdHbZjjXCt8/Zo+
+Tec9JNbYNQB/e9ExmDntmlHEsSEQzFwzj8sxH48AEQEAAcLA9gQYAQoAIBYhBNGm
+bhojsYLJmA94jPv8yCoBXnMwBQJdpZzyAhsMAAoJEPv8yCoBXnMw6f8L/26C34dk
+jBffTzMj5Bdzm8MtF67OYneJ4TQMw7+41IL4rVcSKhIhk/3Ud5knaRtP2ef1+5F6
+6h9/RPQOJ5+tvBwhBAcUWSupKnUrdVaZQanYmtSxcVV2PL9+QEiNN3tzluhaWO//
+rACxJ+K/ZXQlIzwQVTpNhfGzAaMVV9zpf3u0k14itcv6alKY8+rLZvO1wIIeRZLm
+U0tZDD5HtWDvUV7rIFI1WuoLb+KZgbYn3OWjCPHVdTrdZ2CqnZbG3SXw6awH9bzR
+LV9EXkbhIMez0deCVdeo+wFFklh8/5VK2b0vk/+wqMJxfpa1lHvJLobzOP9fvrsw
+sr92MA2+k901WeISR7qEzcI0Fdg8AyFAExaEK6VyjP7SXGLwvfisw34OxuZr3qmx
+1Sufu4toH3XrB7QJN8XyqqbsGxUCBqWif9RSK4xjzRTe56iPeiSJJOIciMP9i2ld
+I+KgLycyeDvGoBj0HCLO3gVaBe4ubVrj5KjhX2PVNEJd3XZRzaXZE2aAMQ==
+=AmgT
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const rsa2048PrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: gpg (GnuPG) 2.2.27 with libgcrypt 1.9.4
+
+lQPGBGL07P0BCADL0etN8efyAXA6sL2WfQvHe5wEKYXPWeN2+jiqSppfeRZAOlzP
+kZ3U+cloeJriplYvVJwI3ID2aw52Z/TRn8iKRP5eOUFrEgcgl06lazLtOndK7o7p
+oBV5mLtHEirFHm6W61fNt10jzM0jx0PV6nseLhFB2J42F1cmU/aBgFo41wjLSZYr
+owR+v+O9S5sUXblQF6sEDcY01sBEu09zrIgT49VFwQ1Cvdh9XZEOTQBfdiugoj5a
+DS3fAqAka3r1VoQK4eR7/upnYSgSACGeaQ4pUelKku5rpm50gdWTY8ppq0k9e1eT
+y2x0OQcW3hWE+j4os1ca0ZEADMdqr/99MOxrABEBAAH+BwMCJWxU4VOZOJ7/I6vX
+FxdfBhIBEXlJ52FM3S/oYtXqLhkGyrtmZOeEazVvUtuCe3M3ScHI8xCthcmE8E0j
+bi+ZEHPS2NiBZtgHFF27BLn7zZuTc+oD5WKduZdK3463egnyThTqIIMl25WZBuab
+k5ycwYrWwBH0jfA4gwJ13ai4pufKC2RM8qIu6YAVPglYBKFLKGvvJHa5vI+LuA0E
+K+k35hIic7yVUcQneNnAF2598X5yWiieYnOZpmHlRw1zfbMwOJr3ZNj2v94u7b+L
+sTa/1Uv9887Vb6sJp0c2Sh4cwEccoPYkvMqFn3ZrJUr3UdDu1K2vWohPtswzhrYV
++RdPZE5RLoCQufKvlPezk0Pzhzb3bBU7XjUbdGY1nH/EyQeBNp+Gw6qldKvzcBaB
+cyOK1c6hPSszpJX93m5UxCN55IeifmcNjmbDh8vGCCdajy6d56qV2n4F3k7vt1J1
+0UlxIGhqijJoaTCX66xjLMC6VXkSz6aHQ35rnXosm/cqPcQshsZTdlfSyWkorfdr
+4Hj8viBER26mjYurTMLBKDtUN724ZrR0Ev5jorX9uoKlgl87bDZHty2Ku2S+vR68
+VAvnj6Fi1BYNclnDoqxdRB2z5T9JbWE52HuG83/QsplhEqXxESDxriTyTHMbNxEe
+88soVCDh4tgflZFa2ucUr6gEKJKij7jgahARnyaXfPZlQBUAS1YUeILYmN+VR+M/
+sHENpwDWc7TInn8VN638nJV+ScZGMih3AwWZTIoiLju3MMt1K0YZ3NuiqwGH4Jwg
+/BbEdTWeCci9y3NEQHQ3uZZ5p6j2CwFVlK11idemCMvAiTVxF+gKdaLMkeCwKxru
+J3YzhKEo+iDVYbPYBYizx/EHBn2U5kITQ5SBXzjTaaFMNZJEf9JYsL1ybPB6HOFY
+VNVB2KT8CGVwtCJHb2xhbmcgR29waGVyIDxnb2xhbmdAZXhhbXBsZS5vcmc+iQFO
+BBMBCgA4FiEEC6K7U7f4qesybTnqSkra7gHusm0FAmL07P0CGwMFCwkIBwIGFQoJ
+CAsCBBYCAwECHgECF4AACgkQSkra7gHusm1MvwgAxpClWkeSqIhMQfbiuz0+lOkE
+89y1DCFw8bHjZoUf4/4K8hFA3dGkk+q72XFgiyaCpfXxMt6Gi+dN47t+tTv9NIqC
+sukbaoJBmJDhN6+djmJOgOYy+FWsW2LAk2LOwKYulpnBZdcA5rlMAhBg7gevQpF+
+ruSU69P7UUaFJl/DC7hDmaIcj+4cjBE/HO26SnVQjoTfjZT82rDh1Wsuf8LnkJUk
+b3wezBLpXKjDvdHikdv4gdlR4AputVM38aZntYYglh/EASo5TneyZ7ZscdLNRdcF
+r5O2fKqrOJLOdaoYRFZZWOvP5GtEVFDU7WGivOSVfiszBE0wZR3dgZRJipHCXJ0D
+xgRi9Oz9AQgAtMJcJqLLVANJHl90tWuoizDkm+Imcwq2ubQAjpclnNrODnDK+7o4
+pBsWmXbZSdkC4gY+LhOQA6bPDD0JEHM58DOnrm49BddxXAyK0HPsk4sGGt2SS86B
+OawWNdfJVyqw4bAiHWDmQg4PcjBbt3ocOIxAR6I5kBSiQVxuGQs9T+Zvg3G1r3Or
+fS6DzlgY3HFUML5YsGH4lOxNSOoKAP68GIH/WNdUZ+feiRg9knIib6I3Hgtf5eO8
+JRH7aWE/TD7eNu36bLLjT5TZPq5r6xaD2plbtPOyXbNPWs9qI1yG+VnErfaLY0w8
+Qo0aqzbgID+CTZVomXSOpOcQseaFKw8ZfQARAQAB/gcDArha6+/+d4OY/w9N32K9
+hFNYt4LufTETMQ+k/sBeaMuAVzmT47DlAXzkrZhGW4dZOtXMu1rXaUwHlqkhEyzL
+L4MYEWVXfD+LbZNEK3MEFss6RK+UAMeT/PTV9aA8cXQVPcSJYzfBXHQ1U1hnOgrO
+apn92MN8RmkhX8wJLyeWTMMuP4lXByJMmmGo8WvifeRD2kFY4y0WVBDAXJAV4Ljf
+Di/bBiwoc5a+gxHuZT2W9ZSxBQJNXdt4Un2IlyZuo58s5MLx2N0EaNJ8PwRUE6fM
+RZYO8aZCEPUtINE4njbvsWOMCtrblsMPwZ1B0SiIaWmLaNyGdCNKea+fCIW7kasC
+JYMhnLumpUTXg5HNexkCsl7ABWj0PYBflOE61h8EjWpnQ7JBBVKS2ua4lMjwHRX7
+5o5yxym9k5UZNFdGoXVL7xpizCcdGawxTJvwhs3vBqu1ZWYCegOAZWDrOkCyhUpq
+8uKMROZFbn+FwE+7tjt+v2ed62FVEvD6g4V3ThCA6mQqeOARfJWN8GZY8BDm8lht
+crOXriUkrx+FlrgGtm2CkwjW5/9Xd7AhFpHnQdFeozOHyq1asNSgJF9sNi9Lz94W
+skQSVRi0IExxSXYGI3Y0nnAZUe2BAQflYPJdEveSr3sKlUqXiETTA1VXsTPK3kOC
+92CbLzj/Hz199jZvywwyu53I+GKMpF42rMq7zxr2oa61YWY4YE/GDezwwys/wLx/
+QpCW4X3ppI7wJjCSSqEV0baYZSSli1ayheS6dxi8QnSpX1Bmpz6gU7m/M9Sns+hl
+J7ZvgpjCAiV7KJTjtclr5/S02zP78LTVkoTWoz/6MOTROwaP63VBUXX8pbJhf/vu
+DLmNnDk8joMJxoDXWeNU0EnNl4hP7Z/jExRBOEO4oAnUf/Sf6gCWQhL5qcajtg6w
+tGv7vx3f2IkBNgQYAQoAIBYhBAuiu1O3+KnrMm056kpK2u4B7rJtBQJi9Oz9AhsM
+AAoJEEpK2u4B7rJt6lgIAMBWqP4BCOGnQXBbgJ0+ACVghpkFUXZTb/tXJc8UUvTM
+8uov6k/RsqDGZrvhhufD7Wwt7j9v7dD7VPp7bPyjVWyimglQzWguTUUqLDGlstYH
+5uYv1pzma0ZsAGNqFeGlTLsKOSGKFMH4rB2KfN2n51L8POvtp1y7GKZQbWIWneaB
+cZr3BINU5GMvYYU7pAYcoR+mJPdJx5Up3Ocn+bn8Tu1sy9C/ArtCQucazGnoE9u1
+HhNLrh0CdzzX7TNH6TQ8LwPOvq0K5l/WqbN9lE0WBBhMv2HydxhluO8AhU+A5GqC
+C+wET7nVDnhoOm/fstIeb7/LN7OYejKPeHdFBJEL9GA=
+=u442
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const curve25519PrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: gpg (GnuPG) 2.2.27 with libgcrypt 1.9.4
+
+lFgEYvTtQBYJKwYBBAHaRw8BAQdAxsNXLbrk5xOjpO24VhOMvQ0/F+JcyIkckMDH
+X3FIGxcAAQDFOlunZWYuPsCx5JLp78vKqUTfgef9TGG4oD6I/Sa0zBMstCJHb2xh
+bmcgR29waGVyIDxnb2xhbmdAZXhhbXBsZS5vcmc+iJAEExYIADgWIQSFQHEOazmo
+h1ldII4MvfnLQ4JBNwUCYvTtQAIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAK
+CRAMvfnLQ4JBN5yeAQCKdry8B5ScCPrev2+UByMCss7Sdu5RhomCFsHdNPLcKAEA
+8ugei+1owHsV+3cGwWWzKk6sLa8ZN87i3SKuOGp9DQycXQRi9O1AEgorBgEEAZdV
+AQUBAQdA5CubPp8l7lrVQ25h7Hx5XN2C8xanRnnpcjzEooCaEA0DAQgHAAD/Rpc+
+sOZUXrFk9HOWB1XU41LoWbDBoG8sP8RWAVYwD5AQRYh4BBgWCAAgFiEEhUBxDms5
+qIdZXSCODL35y0OCQTcFAmL07UACGwwACgkQDL35y0OCQTcvdwEA7lb5g/YisrEf
+iq660uwMGoepLUfvtqKzuQ6heYe83y0BAN65Ffg5HYOJzUEi0kZQRf7OhdtuL2kJ
+SRXn8DmCTfEB
+=cELM
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const curve448PrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: C1DB 65D5 80D7 B922 7254 4B1E A699 9895 FABA CE52
+
+xYUEYV2UmRYDK2VxAc9AFyxgh5xnSbyt50TWl558mw9xdMN+/UBLr5+UMP8IsrvV
+MdXuTIE8CyaUQKSotHtH2RkYEXj5nsMAAAHPQIbTMSzjIWug8UFECzAex5FHgAgH
+gYF3RK+TS8D24wX8kOu2C/NoVxwGY+p+i0JHaB+7yljriSKAGxs6wsBEBB8WCgCD
+BYJhXZSZBYkFpI+9AwsJBwkQppmYlfq6zlJHFAAAAAAAHgAgc2FsdEBub3RhdGlv
+bnMuc2VxdW9pYS1wZ3Aub3Jn5wSpIutJ5HncJWk4ruUV8GzQF390rR5+qWEAnAoY
+akcDFQoIApsBAh4BFiEEwdtl1YDXuSJyVEseppmYlfq6zlIAALzdA5dA/fsgYg/J
+qaQriYKaPUkyHL7EB3BXhV2d1h/gk+qJLvXQuU2WEJ/XSs3GrsBRiiZwvPH4o+7b
+mleAxjy5wpS523vqrrBR2YZ5FwIku7WS4litSdn4AtVam/TlLdMNIf41CtFeZKBe
+c5R5VNdQy8y7qy8AAADNEUN1cnZlNDQ4IE9wdGlvbiA4wsBHBBMWCgCGBYJhXZSZ
+BYkFpI+9AwsJBwkQppmYlfq6zlJHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2Vx
+dW9pYS1wZ3Aub3JnD55UsYMzE6OACP+mgw5zvT+BBgol8/uFQjHg4krjUCMDFQoI
+ApkBApsBAh4BFiEEwdtl1YDXuSJyVEseppmYlfq6zlIAAPQJA5dA0Xqwzn/0uwCq
+RlsOVCB3f5NOj1exKnlBvRw0xT1VBee1yxvlUt5eIAoCxWoRlWBJob3TTkhm9AEA
+8dyhwPmyGfWHzPw5NFG3xsXrZdNXNvit9WMVAPcmsyR7teXuDlJItxRAdJJc/qfJ
+YVbBFoaNrhYAAADHhQRhXZSZFgMrZXEBz0BL7THZ9MnCLfSPJ1FMLim9eGkQ3Bfn
+M3he5rOwO3t14QI1LjI96OjkeJipMgcFAmEP1Bq/ZHGO7oAAAc9AFnE8iNBaT3OU
+EFtxkmWHXtdaYMmGGRdopw9JPXr/UxuunDln5o9dxPxf7q7z26zXrZen+qed/Isa
+HsDCwSwEGBYKAWsFgmFdlJkFiQWkj70JEKaZmJX6us5SRxQAAAAAAB4AIHNhbHRA
+bm90YXRpb25zLnNlcXVvaWEtcGdwLm9yZxREUizdTcepBzgSMOv2VWQCWbl++3CZ
+EbgAWDryvSsyApsCwDGgBBkWCgBvBYJhXZSZCRBKo3SL4S5djkcUAAAAAAAeACBz
+YWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmemoGTDjmNQiIzw6HOEddvS0OB7
+UZ/P07jM/EVmnYxTlBYhBAxsnkGpx1UCiH6gUUqjdIvhLl2OAAALYQOXQAMB1oKq
+OWxSFmvmgCKNcbAAyA3piF5ERIqs4z07oJvqDYrOWt75UsEIH/04gU/vHc4EmfG2
+JDLJgOLlyTUPkL/08f0ydGZPofFQBhn8HkuFFjnNtJ5oz3GIP4cdWMQFaUw0uvjb
+PM9Tm3ptENGd6Ts1AAAAFiEEwdtl1YDXuSJyVEseppmYlfq6zlIAAGpTA5dATR6i
+U2GrpUcQgpG+JqfAsGmF4yAOhgFxc1UfidFk3nTup3fLgjipkYY170WLRNbyKkVO
+Sodx93GAs58rizO1acDAWiLq3cyEPBFXbyFThbcNPcLl+/77Uk/mgkYrPQFAQWdK
+1kSRm4SizDBK37K8ChAAAADHhwRhXZSZEgMrZW8Bx0DMhzvhQo+OsXeqQ6QVw4sF
+CaexHh6rLohh7TzL3hQSjoJ27fV6JBkIWdn0LfrMlJIDbSv2SLdlgQMBCgkAAcdA
+MO7Dc1myF6Co1fAH+EuP+OxhxP/7V6ljuSCZENDfA49tQkzTta+PniG+pOVB2LHb
+huyaKBkqiaogo8LAOQQYFgoAeAWCYV2UmQWJBaSPvQkQppmYlfq6zlJHFAAAAAAA
+HgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnEjBMQAmc/2u45u5FQGmB
+QAytjSG2LM3JQN+PPVl5vEkCmwwWIQTB22XVgNe5InJUSx6mmZiV+rrOUgAASdYD
+l0DXEHQ9ykNP2rZP35ET1dmiFagFtTj/hLQcWlg16LqvJNGqOgYXuqTerbiOOt02
+XLCBln+wdewpU4ChEffMUDRBfqfQco/YsMqWV7bHJHAO0eC/DMKCjyU90xdH7R/d
+QgqsfguR1PqPuJxpXV4bSr6CGAAAAA==
+=MSvh
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const keyWithNotation = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+xVgEY9gIshYJKwYBBAHaRw8BAQdAF25fSM8OpFlXZhop4Qpqo5ywGZ4jgWlR
+ppjhIKDthREAAQC+LFpzFcMJYcjxGKzBGHN0Px2jU4d04YSRnFAik+lVVQ6u
+zRdUZXN0IDx0ZXN0QGV4YW1wbGUuY29tPsLACgQQFgoAfAUCY9gIsgQLCQcI
+CRD/utJOCym8pR0UgAAAAAAQAAR0ZXh0QGV4YW1wbGUuY29tdGVzdB8UAAAA
+AAASAARiaW5hcnlAZXhhbXBsZS5jb20AAQIDAxUICgQWAAIBAhkBAhsDAh4B
+FiEEEMCQTUVGKgCX5rDQ/7rSTgspvKUAAPl5AP9Npz90LxzrB97Qr2DrGwfG
+wuYn4FSYwtuPfZHHeoIabwD/QEbvpQJ/NBb9EAZuow4Rirlt1yv19mmnF+j5
+8yUzhQjHXQRj2AiyEgorBgEEAZdVAQUBAQdARXAo30DmKcyUg6co7OUm0RNT
+z9iqFbDBzA8A47JEt1MDAQgHAAD/XKK3lBm0SqMR558HLWdBrNG6NqKuqb5X
+joCML987ZNgRD8J4BBgWCAAqBQJj2AiyCRD/utJOCym8pQIbDBYhBBDAkE1F
+RioAl+aw0P+60k4LKbylAADRxgEAg7UfBDiDPp5LHcW9D+SgFHk6+GyEU4ev
+VppQxdtxPvAA/34snHBX7Twnip1nMt7P4e2hDiw/hwQ7oqioOvc6jMkP
+=Z8YJ
+-----END PGP PRIVATE KEY BLOCK-----
+`
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go
new file mode 100644
index 00000000..fec41a0e
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go
@@ -0,0 +1,67 @@
+// Copyright (C) 2019 ProtonTech AG
+
+package packet
+
+import "math/bits"
+
+// CipherSuite contains a combination of Cipher and Mode
+type CipherSuite struct {
+ // The cipher function
+ Cipher CipherFunction
+ // The AEAD mode of operation.
+ Mode AEADMode
+}
+
+// AEADConfig collects a number of AEAD parameters along with sensible defaults.
+// A nil AEADConfig is valid and results in all default values.
+type AEADConfig struct {
+ // The AEAD mode of operation.
+ DefaultMode AEADMode
+ // Amount of octets in each chunk of data
+ ChunkSize uint64
+}
+
+// Mode returns the AEAD mode of operation.
+func (conf *AEADConfig) Mode() AEADMode {
+ // If no preference is specified, OCB is used (which is mandatory to implement).
+ if conf == nil || conf.DefaultMode == 0 {
+ return AEADModeOCB
+ }
+
+ mode := conf.DefaultMode
+ if mode != AEADModeEAX && mode != AEADModeOCB && mode != AEADModeGCM {
+ panic("AEAD mode unsupported")
+ }
+ return mode
+}
+
+// ChunkSizeByte returns the byte indicating the chunk size. The effective
+// chunk size is computed with the formula uint64(1) << (chunkSizeByte + 6)
+// limit to 16 = 4 MiB
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
+func (conf *AEADConfig) ChunkSizeByte() byte {
+ if conf == nil || conf.ChunkSize == 0 {
+ return 12 // 1 << (12 + 6) == 262144 bytes
+ }
+
+ chunkSize := conf.ChunkSize
+ exponent := bits.Len64(chunkSize) - 1
+ switch {
+ case exponent < 6:
+ exponent = 6
+ case exponent > 16:
+ exponent = 16
+ }
+
+ return byte(exponent - 6)
+}
+
+// decodeAEADChunkSize returns the effective chunk size. In 32-bit systems, the
+// maximum returned value is 1 << 30.
+func decodeAEADChunkSize(c byte) int {
+ size := uint64(1 << (c + 6))
+ if size != uint64(int(size)) {
+ return 1 << 30
+ }
+ return int(size)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go
new file mode 100644
index 00000000..cee83bdc
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go
@@ -0,0 +1,264 @@
+// Copyright (C) 2019 ProtonTech AG
+
+package packet
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "encoding/binary"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// aeadCrypter is an AEAD opener/sealer, its configuration, and data for en/decryption.
+type aeadCrypter struct {
+ aead cipher.AEAD
+ chunkSize int
+ initialNonce []byte
+ associatedData []byte // Chunk-independent associated data
+ chunkIndex []byte // Chunk counter
+ packetTag packetType // SEIP packet (v2) or AEAD Encrypted Data packet
+ bytesProcessed int // Amount of plaintext bytes encrypted/decrypted
+ buffer bytes.Buffer // Buffered bytes across chunks
+}
+
+// computeNonce takes the incremental index and computes an eXclusive OR with
+// the least significant 8 bytes of the receivers' initial nonce (see sec.
+// 5.16.1 and 5.16.2). It returns the resulting nonce.
+func (wo *aeadCrypter) computeNextNonce() (nonce []byte) {
+ if wo.packetTag == packetTypeSymmetricallyEncryptedIntegrityProtected {
+ return append(wo.initialNonce, wo.chunkIndex...)
+ }
+
+ nonce = make([]byte, len(wo.initialNonce))
+ copy(nonce, wo.initialNonce)
+ offset := len(wo.initialNonce) - 8
+ for i := 0; i < 8; i++ {
+ nonce[i+offset] ^= wo.chunkIndex[i]
+ }
+ return
+}
+
+// incrementIndex performs an integer increment by 1 of the integer represented by the
+// slice, modifying it accordingly.
+func (wo *aeadCrypter) incrementIndex() error {
+ index := wo.chunkIndex
+ if len(index) == 0 {
+ return errors.AEADError("Index has length 0")
+ }
+ for i := len(index) - 1; i >= 0; i-- {
+ if index[i] < 255 {
+ index[i]++
+ return nil
+ }
+ index[i] = 0
+ }
+ return errors.AEADError("cannot further increment index")
+}
+
+// aeadDecrypter reads and decrypts bytes. It buffers extra decrypted bytes when
+// necessary, similar to aeadEncrypter.
+type aeadDecrypter struct {
+ aeadCrypter // Embedded ciphertext opener
+ reader io.Reader // 'reader' is a partialLengthReader
+ peekedBytes []byte // Used to detect last chunk
+ eof bool
+}
+
+// Read decrypts bytes and reads them into dst. It decrypts when necessary and
+// buffers extra decrypted bytes. It returns the number of bytes copied into dst
+// and an error.
+func (ar *aeadDecrypter) Read(dst []byte) (n int, err error) {
+ // Return buffered plaintext bytes from previous calls
+ if ar.buffer.Len() > 0 {
+ return ar.buffer.Read(dst)
+ }
+
+ // Return EOF if we've previously validated the final tag
+ if ar.eof {
+ return 0, io.EOF
+ }
+
+ // Read a chunk
+ tagLen := ar.aead.Overhead()
+ cipherChunkBuf := new(bytes.Buffer)
+ _, errRead := io.CopyN(cipherChunkBuf, ar.reader, int64(ar.chunkSize+tagLen))
+ cipherChunk := cipherChunkBuf.Bytes()
+ if errRead != nil && errRead != io.EOF {
+ return 0, errRead
+ }
+ decrypted, errChunk := ar.openChunk(cipherChunk)
+ if errChunk != nil {
+ return 0, errChunk
+ }
+
+ // Return decrypted bytes, buffering if necessary
+ if len(dst) < len(decrypted) {
+ n = copy(dst, decrypted[:len(dst)])
+ ar.buffer.Write(decrypted[len(dst):])
+ } else {
+ n = copy(dst, decrypted)
+ }
+
+ // Check final authentication tag
+ if errRead == io.EOF {
+ errChunk := ar.validateFinalTag(ar.peekedBytes)
+ if errChunk != nil {
+ return n, errChunk
+ }
+ ar.eof = true // Mark EOF for when we've returned all buffered data
+ }
+ return
+}
+
+// Close is noOp. The final authentication tag of the stream was already
+// checked in the last Read call. In the future, this function could be used to
+// wipe the reader and peeked, decrypted bytes, if necessary.
+func (ar *aeadDecrypter) Close() (err error) {
+ return nil
+}
+
+// openChunk decrypts and checks integrity of an encrypted chunk, returning
+// the underlying plaintext and an error. It accesses peeked bytes from next
+// chunk, to identify the last chunk and decrypt/validate accordingly.
+func (ar *aeadDecrypter) openChunk(data []byte) ([]byte, error) {
+ tagLen := ar.aead.Overhead()
+ // Restore carried bytes from last call
+ chunkExtra := append(ar.peekedBytes, data...)
+ // 'chunk' contains encrypted bytes, followed by an authentication tag.
+ chunk := chunkExtra[:len(chunkExtra)-tagLen]
+ ar.peekedBytes = chunkExtra[len(chunkExtra)-tagLen:]
+
+ adata := ar.associatedData
+ if ar.aeadCrypter.packetTag == packetTypeAEADEncrypted {
+ adata = append(ar.associatedData, ar.chunkIndex...)
+ }
+
+ nonce := ar.computeNextNonce()
+ plainChunk, err := ar.aead.Open(nil, nonce, chunk, adata)
+ if err != nil {
+ return nil, err
+ }
+ ar.bytesProcessed += len(plainChunk)
+ if err = ar.aeadCrypter.incrementIndex(); err != nil {
+ return nil, err
+ }
+ return plainChunk, nil
+}
+
+// Checks the summary tag. It takes into account the total decrypted bytes into
+// the associated data. It returns an error, or nil if the tag is valid.
+func (ar *aeadDecrypter) validateFinalTag(tag []byte) error {
+ // Associated: tag, version, cipher, aead, chunk size, ...
+ amountBytes := make([]byte, 8)
+ binary.BigEndian.PutUint64(amountBytes, uint64(ar.bytesProcessed))
+
+ adata := ar.associatedData
+ if ar.aeadCrypter.packetTag == packetTypeAEADEncrypted {
+ // ... index ...
+ adata = append(ar.associatedData, ar.chunkIndex...)
+ }
+
+ // ... and total number of encrypted octets
+ adata = append(adata, amountBytes...)
+ nonce := ar.computeNextNonce()
+ _, err := ar.aead.Open(nil, nonce, tag, adata)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// aeadEncrypter encrypts and writes bytes. It encrypts when necessary according
+// to the AEAD block size, and buffers the extra encrypted bytes for next write.
+type aeadEncrypter struct {
+ aeadCrypter // Embedded plaintext sealer
+ writer io.WriteCloser // 'writer' is a partialLengthWriter
+}
+
+// Write encrypts and writes bytes. It encrypts when necessary and buffers extra
+// plaintext bytes for next call. When the stream is finished, Close() MUST be
+// called to append the final tag.
+func (aw *aeadEncrypter) Write(plaintextBytes []byte) (n int, err error) {
+ // Append plaintextBytes to existing buffered bytes
+ n, err = aw.buffer.Write(plaintextBytes)
+ if err != nil {
+ return n, err
+ }
+ // Encrypt and write chunks
+ for aw.buffer.Len() >= aw.chunkSize {
+ plainChunk := aw.buffer.Next(aw.chunkSize)
+ encryptedChunk, err := aw.sealChunk(plainChunk)
+ if err != nil {
+ return n, err
+ }
+ _, err = aw.writer.Write(encryptedChunk)
+ if err != nil {
+ return n, err
+ }
+ }
+ return
+}
+
+// Close encrypts and writes the remaining buffered plaintext if any, appends
+// the final authentication tag, and closes the embedded writer. This function
+// MUST be called at the end of a stream.
+func (aw *aeadEncrypter) Close() (err error) {
+ // Encrypt and write a chunk if there's buffered data left, or if we haven't
+ // written any chunks yet.
+ if aw.buffer.Len() > 0 || aw.bytesProcessed == 0 {
+ plainChunk := aw.buffer.Bytes()
+ lastEncryptedChunk, err := aw.sealChunk(plainChunk)
+ if err != nil {
+ return err
+ }
+ _, err = aw.writer.Write(lastEncryptedChunk)
+ if err != nil {
+ return err
+ }
+ }
+ // Compute final tag (associated data: packet tag, version, cipher, aead,
+ // chunk size...
+ adata := aw.associatedData
+
+ if aw.aeadCrypter.packetTag == packetTypeAEADEncrypted {
+ // ... index ...
+ adata = append(aw.associatedData, aw.chunkIndex...)
+ }
+
+ // ... and total number of encrypted octets
+ amountBytes := make([]byte, 8)
+ binary.BigEndian.PutUint64(amountBytes, uint64(aw.bytesProcessed))
+ adata = append(adata, amountBytes...)
+
+ nonce := aw.computeNextNonce()
+ finalTag := aw.aead.Seal(nil, nonce, nil, adata)
+ _, err = aw.writer.Write(finalTag)
+ if err != nil {
+ return err
+ }
+ return aw.writer.Close()
+}
+
+// sealChunk Encrypts and authenticates the given chunk.
+func (aw *aeadEncrypter) sealChunk(data []byte) ([]byte, error) {
+ if len(data) > aw.chunkSize {
+ return nil, errors.AEADError("chunk exceeds maximum length")
+ }
+ if aw.associatedData == nil {
+ return nil, errors.AEADError("can't seal without headers")
+ }
+ adata := aw.associatedData
+ if aw.aeadCrypter.packetTag == packetTypeAEADEncrypted {
+ adata = append(aw.associatedData, aw.chunkIndex...)
+ }
+
+ nonce := aw.computeNextNonce()
+ encrypted := aw.aead.Seal(nil, nonce, data, adata)
+ aw.bytesProcessed += len(data)
+ if err := aw.aeadCrypter.incrementIndex(); err != nil {
+ return nil, err
+ }
+ return encrypted, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_encrypted.go
new file mode 100644
index 00000000..98bd876b
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_encrypted.go
@@ -0,0 +1,96 @@
+// Copyright (C) 2019 ProtonTech AG
+
+package packet
+
+import (
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+)
+
+// AEADEncrypted represents an AEAD Encrypted Packet.
+// See https://www.ietf.org/archive/id/draft-koch-openpgp-2015-rfc4880bis-00.html#name-aead-encrypted-data-packet-t
+type AEADEncrypted struct {
+ cipher CipherFunction
+ mode AEADMode
+ chunkSizeByte byte
+ Contents io.Reader // Encrypted chunks and tags
+ initialNonce []byte // Referred to as IV in RFC4880-bis
+}
+
+// Only currently defined version
+const aeadEncryptedVersion = 1
+
+func (ae *AEADEncrypted) parse(buf io.Reader) error {
+ headerData := make([]byte, 4)
+ if n, err := io.ReadFull(buf, headerData); n < 4 {
+ return errors.AEADError("could not read aead header:" + err.Error())
+ }
+ // Read initial nonce
+ mode := AEADMode(headerData[2])
+ nonceLen := mode.IvLength()
+
+ // This packet supports only EAX and OCB
+ // https://www.ietf.org/archive/id/draft-koch-openpgp-2015-rfc4880bis-00.html#name-aead-encrypted-data-packet-t
+ if nonceLen == 0 || mode > AEADModeOCB {
+ return errors.AEADError("unknown mode")
+ }
+
+ initialNonce := make([]byte, nonceLen)
+ if n, err := io.ReadFull(buf, initialNonce); n < nonceLen {
+ return errors.AEADError("could not read aead nonce:" + err.Error())
+ }
+ ae.Contents = buf
+ ae.initialNonce = initialNonce
+ c := headerData[1]
+ if _, ok := algorithm.CipherById[c]; !ok {
+ return errors.UnsupportedError("unknown cipher: " + string(c))
+ }
+ ae.cipher = CipherFunction(c)
+ ae.mode = mode
+ ae.chunkSizeByte = headerData[3]
+ return nil
+}
+
+// Decrypt returns a io.ReadCloser from which decrypted bytes can be read, or
+// an error.
+func (ae *AEADEncrypted) Decrypt(ciph CipherFunction, key []byte) (io.ReadCloser, error) {
+ return ae.decrypt(key)
+}
+
+// decrypt prepares an aeadCrypter and returns a ReadCloser from which
+// decrypted bytes can be read (see aeadDecrypter.Read()).
+func (ae *AEADEncrypted) decrypt(key []byte) (io.ReadCloser, error) {
+ blockCipher := ae.cipher.new(key)
+ aead := ae.mode.new(blockCipher)
+ // Carry the first tagLen bytes
+ tagLen := ae.mode.TagLength()
+ peekedBytes := make([]byte, tagLen)
+ n, err := io.ReadFull(ae.Contents, peekedBytes)
+ if n < tagLen || (err != nil && err != io.EOF) {
+ return nil, errors.AEADError("Not enough data to decrypt:" + err.Error())
+ }
+ chunkSize := decodeAEADChunkSize(ae.chunkSizeByte)
+ return &aeadDecrypter{
+ aeadCrypter: aeadCrypter{
+ aead: aead,
+ chunkSize: chunkSize,
+ initialNonce: ae.initialNonce,
+ associatedData: ae.associatedData(),
+ chunkIndex: make([]byte, 8),
+ packetTag: packetTypeAEADEncrypted,
+ },
+ reader: ae.Contents,
+ peekedBytes: peekedBytes}, nil
+}
+
+// associatedData for chunks: tag, version, cipher, mode, chunk size byte
+func (ae *AEADEncrypted) associatedData() []byte {
+ return []byte{
+ 0xD4,
+ aeadEncryptedVersion,
+ byte(ae.cipher),
+ byte(ae.mode),
+ ae.chunkSizeByte}
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go
new file mode 100644
index 00000000..2f5cad71
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go
@@ -0,0 +1,125 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "compress/bzip2"
+ "compress/flate"
+ "compress/zlib"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "io"
+ "strconv"
+)
+
+// Compressed represents a compressed OpenPGP packet. The decompressed contents
+// will contain more OpenPGP packets. See RFC 4880, section 5.6.
+type Compressed struct {
+ Body io.Reader
+}
+
+const (
+ NoCompression = flate.NoCompression
+ BestSpeed = flate.BestSpeed
+ BestCompression = flate.BestCompression
+ DefaultCompression = flate.DefaultCompression
+)
+
+// CompressionConfig contains compressor configuration settings.
+type CompressionConfig struct {
+ // Level is the compression level to use. It must be set to
+ // between -1 and 9, with -1 causing the compressor to use the
+ // default compression level, 0 causing the compressor to use
+ // no compression and 1 to 9 representing increasing (better,
+ // slower) compression levels. If Level is less than -1 or
+ // more then 9, a non-nil error will be returned during
+ // encryption. See the constants above for convenient common
+ // settings for Level.
+ Level int
+}
+
+func (c *Compressed) parse(r io.Reader) error {
+ var buf [1]byte
+ _, err := readFull(r, buf[:])
+ if err != nil {
+ return err
+ }
+
+ switch buf[0] {
+ case 0:
+ c.Body = r
+ case 1:
+ c.Body = flate.NewReader(r)
+ case 2:
+ c.Body, err = zlib.NewReader(r)
+ case 3:
+ c.Body = bzip2.NewReader(r)
+ default:
+ err = errors.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0])))
+ }
+
+ return err
+}
+
+// compressedWriterCloser represents the serialized compression stream
+// header and the compressor. Its Close() method ensures that both the
+// compressor and serialized stream header are closed. Its Write()
+// method writes to the compressor.
+type compressedWriteCloser struct {
+ sh io.Closer // Stream Header
+ c io.WriteCloser // Compressor
+}
+
+func (cwc compressedWriteCloser) Write(p []byte) (int, error) {
+ return cwc.c.Write(p)
+}
+
+func (cwc compressedWriteCloser) Close() (err error) {
+ err = cwc.c.Close()
+ if err != nil {
+ return err
+ }
+
+ return cwc.sh.Close()
+}
+
+// SerializeCompressed serializes a compressed data packet to w and
+// returns a WriteCloser to which the literal data packets themselves
+// can be written and which MUST be closed on completion. If cc is
+// nil, sensible defaults will be used to configure the compression
+// algorithm.
+func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *CompressionConfig) (literaldata io.WriteCloser, err error) {
+ compressed, err := serializeStreamHeader(w, packetTypeCompressed)
+ if err != nil {
+ return
+ }
+
+ _, err = compressed.Write([]byte{uint8(algo)})
+ if err != nil {
+ return
+ }
+
+ level := DefaultCompression
+ if cc != nil {
+ level = cc.Level
+ }
+
+ var compressor io.WriteCloser
+ switch algo {
+ case CompressionZIP:
+ compressor, err = flate.NewWriter(compressed, level)
+ case CompressionZLIB:
+ compressor, err = zlib.NewWriterLevel(compressed, level)
+ default:
+ s := strconv.Itoa(int(algo))
+ err = errors.UnsupportedError("Unsupported compression algorithm: " + s)
+ }
+ if err != nil {
+ return
+ }
+
+ literaldata = compressedWriteCloser{compressed, compressor}
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go
new file mode 100644
index 00000000..04994bec
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go
@@ -0,0 +1,248 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto"
+ "crypto/rand"
+ "io"
+ "math/big"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/s2k"
+)
+
+// Config collects a number of parameters along with sensible defaults.
+// A nil *Config is valid and results in all default values.
+type Config struct {
+ // Rand provides the source of entropy.
+ // If nil, the crypto/rand Reader is used.
+ Rand io.Reader
+ // DefaultHash is the default hash function to be used.
+ // If zero, SHA-256 is used.
+ DefaultHash crypto.Hash
+ // DefaultCipher is the cipher to be used.
+ // If zero, AES-128 is used.
+ DefaultCipher CipherFunction
+ // Time returns the current time as the number of seconds since the
+ // epoch. If Time is nil, time.Now is used.
+ Time func() time.Time
+ // DefaultCompressionAlgo is the compression algorithm to be
+ // applied to the plaintext before encryption. If zero, no
+ // compression is done.
+ DefaultCompressionAlgo CompressionAlgo
+ // CompressionConfig configures the compression settings.
+ CompressionConfig *CompressionConfig
+ // S2K (String to Key) config, used for key derivation in the context of secret key encryption
+ // and password-encrypted data.
+ // If nil, the default configuration is used
+ S2KConfig *s2k.Config
+ // Iteration count for Iterated S2K (String to Key).
+ // Only used if sk2.Mode is nil.
+ // This value is duplicated here from s2k.Config for backwards compatibility.
+ // It determines the strength of the passphrase stretching when
+ // the said passphrase is hashed to produce a key. S2KCount
+ // should be between 65536 and 65011712, inclusive. If Config
+ // is nil or S2KCount is 0, the value 16777216 used. Not all
+ // values in the above range can be represented. S2KCount will
+ // be rounded up to the next representable value if it cannot
+ // be encoded exactly. When set, it is strongly encrouraged to
+ // use a value that is at least 65536. See RFC 4880 Section
+ // 3.7.1.3.
+ //
+ // Deprecated: SK2Count should be configured in S2KConfig instead.
+ S2KCount int
+ // RSABits is the number of bits in new RSA keys made with NewEntity.
+ // If zero, then 2048 bit keys are created.
+ RSABits int
+ // The public key algorithm to use - will always create a signing primary
+ // key and encryption subkey.
+ Algorithm PublicKeyAlgorithm
+ // Some known primes that are optionally prepopulated by the caller
+ RSAPrimes []*big.Int
+ // Curve configures the desired packet.Curve if the Algorithm is PubKeyAlgoECDSA,
+ // PubKeyAlgoEdDSA, or PubKeyAlgoECDH. If empty Curve25519 is used.
+ Curve Curve
+ // AEADConfig configures the use of the new AEAD Encrypted Data Packet,
+ // defined in the draft of the next version of the OpenPGP specification.
+ // If a non-nil AEADConfig is passed, usage of this packet is enabled. By
+ // default, it is disabled. See the documentation of AEADConfig for more
+ // configuration options related to AEAD.
+ // **Note: using this option may break compatibility with other OpenPGP
+ // implementations, as well as future versions of this library.**
+ AEADConfig *AEADConfig
+ // V5Keys configures version 5 key generation. If false, this package still
+ // supports version 5 keys, but produces version 4 keys.
+ V5Keys bool
+ // "The validity period of the key. This is the number of seconds after
+ // the key creation time that the key expires. If this is not present
+ // or has a value of zero, the key never expires. This is found only on
+ // a self-signature.""
+ // https://tools.ietf.org/html/rfc4880#section-5.2.3.6
+ KeyLifetimeSecs uint32
+ // "The validity period of the signature. This is the number of seconds
+ // after the signature creation time that the signature expires. If
+ // this is not present or has a value of zero, it never expires."
+ // https://tools.ietf.org/html/rfc4880#section-5.2.3.10
+ SigLifetimeSecs uint32
+ // SigningKeyId is used to specify the signing key to use (by Key ID).
+ // By default, the signing key is selected automatically, preferring
+ // signing subkeys if available.
+ SigningKeyId uint64
+ // SigningIdentity is used to specify a user ID (packet Signer's User ID, type 28)
+ // when producing a generic certification signature onto an existing user ID.
+ // The identity must be present in the signer Entity.
+ SigningIdentity string
+ // InsecureAllowUnauthenticatedMessages controls, whether it is tolerated to read
+ // encrypted messages without Modification Detection Code (MDC).
+ // MDC is mandated by the IETF OpenPGP Crypto Refresh draft and has long been implemented
+ // in most OpenPGP implementations. Messages without MDC are considered unnecessarily
+ // insecure and should be prevented whenever possible.
+ // In case one needs to deal with messages from very old OpenPGP implementations, there
+ // might be no other way than to tolerate the missing MDC. Setting this flag, allows this
+ // mode of operation. It should be considered a measure of last resort.
+ InsecureAllowUnauthenticatedMessages bool
+ // KnownNotations is a map of Notation Data names to bools, which controls
+ // the notation names that are allowed to be present in critical Notation Data
+ // signature subpackets.
+ KnownNotations map[string]bool
+ // SignatureNotations is a list of Notations to be added to any signatures.
+ SignatureNotations []*Notation
+}
+
+func (c *Config) Random() io.Reader {
+ if c == nil || c.Rand == nil {
+ return rand.Reader
+ }
+ return c.Rand
+}
+
+func (c *Config) Hash() crypto.Hash {
+ if c == nil || uint(c.DefaultHash) == 0 {
+ return crypto.SHA256
+ }
+ return c.DefaultHash
+}
+
+func (c *Config) Cipher() CipherFunction {
+ if c == nil || uint8(c.DefaultCipher) == 0 {
+ return CipherAES128
+ }
+ return c.DefaultCipher
+}
+
+func (c *Config) Now() time.Time {
+ if c == nil || c.Time == nil {
+ return time.Now().Truncate(time.Second)
+ }
+ return c.Time().Truncate(time.Second)
+}
+
+// KeyLifetime returns the validity period of the key.
+func (c *Config) KeyLifetime() uint32 {
+ if c == nil {
+ return 0
+ }
+ return c.KeyLifetimeSecs
+}
+
+// SigLifetime returns the validity period of the signature.
+func (c *Config) SigLifetime() uint32 {
+ if c == nil {
+ return 0
+ }
+ return c.SigLifetimeSecs
+}
+
+func (c *Config) Compression() CompressionAlgo {
+ if c == nil {
+ return CompressionNone
+ }
+ return c.DefaultCompressionAlgo
+}
+
+func (c *Config) RSAModulusBits() int {
+ if c == nil || c.RSABits == 0 {
+ return 2048
+ }
+ return c.RSABits
+}
+
+func (c *Config) PublicKeyAlgorithm() PublicKeyAlgorithm {
+ if c == nil || c.Algorithm == 0 {
+ return PubKeyAlgoRSA
+ }
+ return c.Algorithm
+}
+
+func (c *Config) CurveName() Curve {
+ if c == nil || c.Curve == "" {
+ return Curve25519
+ }
+ return c.Curve
+}
+
+// Deprecated: The hash iterations should now be queried via the S2K() method.
+func (c *Config) PasswordHashIterations() int {
+ if c == nil || c.S2KCount == 0 {
+ return 0
+ }
+ return c.S2KCount
+}
+
+func (c *Config) S2K() *s2k.Config {
+ if c == nil {
+ return nil
+ }
+ // for backwards compatibility
+ if c != nil && c.S2KCount > 0 && c.S2KConfig == nil {
+ return &s2k.Config{
+ S2KCount: c.S2KCount,
+ }
+ }
+ return c.S2KConfig
+}
+
+func (c *Config) AEAD() *AEADConfig {
+ if c == nil {
+ return nil
+ }
+ return c.AEADConfig
+}
+
+func (c *Config) SigningKey() uint64 {
+ if c == nil {
+ return 0
+ }
+ return c.SigningKeyId
+}
+
+func (c *Config) SigningUserId() string {
+ if c == nil {
+ return ""
+ }
+ return c.SigningIdentity
+}
+
+func (c *Config) AllowUnauthenticatedMessages() bool {
+ if c == nil {
+ return false
+ }
+ return c.InsecureAllowUnauthenticatedMessages
+}
+
+func (c *Config) KnownNotation(notationName string) bool {
+ if c == nil {
+ return false
+ }
+ return c.KnownNotations[notationName]
+}
+
+func (c *Config) Notations() []*Notation {
+ if c == nil {
+ return nil
+ }
+ return c.SignatureNotations
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go
new file mode 100644
index 00000000..eeff2902
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go
@@ -0,0 +1,286 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto"
+ "crypto/rsa"
+ "encoding/binary"
+ "io"
+ "math/big"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdh"
+ "github.com/ProtonMail/go-crypto/openpgp/elgamal"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+)
+
+const encryptedKeyVersion = 3
+
+// EncryptedKey represents a public-key encrypted session key. See RFC 4880,
+// section 5.1.
+type EncryptedKey struct {
+ KeyId uint64
+ Algo PublicKeyAlgorithm
+ CipherFunc CipherFunction // only valid after a successful Decrypt for a v3 packet
+ Key []byte // only valid after a successful Decrypt
+
+ encryptedMPI1, encryptedMPI2 encoding.Field
+}
+
+func (e *EncryptedKey) parse(r io.Reader) (err error) {
+ var buf [10]byte
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ if buf[0] != encryptedKeyVersion {
+ return errors.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0])))
+ }
+ e.KeyId = binary.BigEndian.Uint64(buf[1:9])
+ e.Algo = PublicKeyAlgorithm(buf[9])
+ switch e.Algo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ e.encryptedMPI1 = new(encoding.MPI)
+ if _, err = e.encryptedMPI1.ReadFrom(r); err != nil {
+ return
+ }
+ case PubKeyAlgoElGamal:
+ e.encryptedMPI1 = new(encoding.MPI)
+ if _, err = e.encryptedMPI1.ReadFrom(r); err != nil {
+ return
+ }
+
+ e.encryptedMPI2 = new(encoding.MPI)
+ if _, err = e.encryptedMPI2.ReadFrom(r); err != nil {
+ return
+ }
+ case PubKeyAlgoECDH:
+ e.encryptedMPI1 = new(encoding.MPI)
+ if _, err = e.encryptedMPI1.ReadFrom(r); err != nil {
+ return
+ }
+
+ e.encryptedMPI2 = new(encoding.OID)
+ if _, err = e.encryptedMPI2.ReadFrom(r); err != nil {
+ return
+ }
+ }
+ _, err = consumeAll(r)
+ return
+}
+
+func checksumKeyMaterial(key []byte) uint16 {
+ var checksum uint16
+ for _, v := range key {
+ checksum += uint16(v)
+ }
+ return checksum
+}
+
+// Decrypt decrypts an encrypted session key with the given private key. The
+// private key must have been decrypted first.
+// If config is nil, sensible defaults will be used.
+func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error {
+ if e.KeyId != 0 && e.KeyId != priv.KeyId {
+ return errors.InvalidArgumentError("cannot decrypt encrypted session key for key id " + strconv.FormatUint(e.KeyId, 16) + " with private key id " + strconv.FormatUint(priv.KeyId, 16))
+ }
+ if e.Algo != priv.PubKeyAlgo {
+ return errors.InvalidArgumentError("cannot decrypt encrypted session key of type " + strconv.Itoa(int(e.Algo)) + " with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
+ }
+ if priv.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+
+ var err error
+ var b []byte
+
+ // TODO(agl): use session key decryption routines here to avoid
+ // padding oracle attacks.
+ switch priv.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ // Supports both *rsa.PrivateKey and crypto.Decrypter
+ k := priv.PrivateKey.(crypto.Decrypter)
+ b, err = k.Decrypt(config.Random(), padToKeySize(k.Public().(*rsa.PublicKey), e.encryptedMPI1.Bytes()), nil)
+ case PubKeyAlgoElGamal:
+ c1 := new(big.Int).SetBytes(e.encryptedMPI1.Bytes())
+ c2 := new(big.Int).SetBytes(e.encryptedMPI2.Bytes())
+ b, err = elgamal.Decrypt(priv.PrivateKey.(*elgamal.PrivateKey), c1, c2)
+ case PubKeyAlgoECDH:
+ vsG := e.encryptedMPI1.Bytes()
+ m := e.encryptedMPI2.Bytes()
+ oid := priv.PublicKey.oid.EncodedBytes()
+ b, err = ecdh.Decrypt(priv.PrivateKey.(*ecdh.PrivateKey), vsG, m, oid, priv.PublicKey.Fingerprint[:])
+ default:
+ err = errors.InvalidArgumentError("cannot decrypt encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
+ }
+
+ if err != nil {
+ return err
+ }
+
+ e.CipherFunc = CipherFunction(b[0])
+ if !e.CipherFunc.IsSupported() {
+ return errors.UnsupportedError("unsupported encryption function")
+ }
+
+ e.Key = b[1 : len(b)-2]
+ expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
+ checksum := checksumKeyMaterial(e.Key)
+ if checksum != expectedChecksum {
+ return errors.StructuralError("EncryptedKey checksum incorrect")
+ }
+
+ return nil
+}
+
+// Serialize writes the encrypted key packet, e, to w.
+func (e *EncryptedKey) Serialize(w io.Writer) error {
+ var mpiLen int
+ switch e.Algo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ mpiLen = int(e.encryptedMPI1.EncodedLength())
+ case PubKeyAlgoElGamal:
+ mpiLen = int(e.encryptedMPI1.EncodedLength()) + int(e.encryptedMPI2.EncodedLength())
+ case PubKeyAlgoECDH:
+ mpiLen = int(e.encryptedMPI1.EncodedLength()) + int(e.encryptedMPI2.EncodedLength())
+ default:
+ return errors.InvalidArgumentError("don't know how to serialize encrypted key type " + strconv.Itoa(int(e.Algo)))
+ }
+
+ err := serializeHeader(w, packetTypeEncryptedKey, 1 /* version */ +8 /* key id */ +1 /* algo */ +mpiLen)
+ if err != nil {
+ return err
+ }
+
+ w.Write([]byte{encryptedKeyVersion})
+ binary.Write(w, binary.BigEndian, e.KeyId)
+ w.Write([]byte{byte(e.Algo)})
+
+ switch e.Algo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ _, err := w.Write(e.encryptedMPI1.EncodedBytes())
+ return err
+ case PubKeyAlgoElGamal:
+ if _, err := w.Write(e.encryptedMPI1.EncodedBytes()); err != nil {
+ return err
+ }
+ _, err := w.Write(e.encryptedMPI2.EncodedBytes())
+ return err
+ case PubKeyAlgoECDH:
+ if _, err := w.Write(e.encryptedMPI1.EncodedBytes()); err != nil {
+ return err
+ }
+ _, err := w.Write(e.encryptedMPI2.EncodedBytes())
+ return err
+ default:
+ panic("internal error")
+ }
+}
+
+// SerializeEncryptedKey serializes an encrypted key packet to w that contains
+// key, encrypted to pub.
+// If config is nil, sensible defaults will be used.
+func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, config *Config) error {
+ var buf [10]byte
+ buf[0] = encryptedKeyVersion
+ binary.BigEndian.PutUint64(buf[1:9], pub.KeyId)
+ buf[9] = byte(pub.PubKeyAlgo)
+
+ keyBlock := make([]byte, 1 /* cipher type */ +len(key)+2 /* checksum */)
+ keyBlock[0] = byte(cipherFunc)
+ copy(keyBlock[1:], key)
+ checksum := checksumKeyMaterial(key)
+ keyBlock[1+len(key)] = byte(checksum >> 8)
+ keyBlock[1+len(key)+1] = byte(checksum)
+
+ switch pub.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ return serializeEncryptedKeyRSA(w, config.Random(), buf, pub.PublicKey.(*rsa.PublicKey), keyBlock)
+ case PubKeyAlgoElGamal:
+ return serializeEncryptedKeyElGamal(w, config.Random(), buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock)
+ case PubKeyAlgoECDH:
+ return serializeEncryptedKeyECDH(w, config.Random(), buf, pub.PublicKey.(*ecdh.PublicKey), keyBlock, pub.oid, pub.Fingerprint)
+ case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly:
+ return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
+ }
+
+ return errors.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
+}
+
+func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub *rsa.PublicKey, keyBlock []byte) error {
+ cipherText, err := rsa.EncryptPKCS1v15(rand, pub, keyBlock)
+ if err != nil {
+ return errors.InvalidArgumentError("RSA encryption failed: " + err.Error())
+ }
+
+ cipherMPI := encoding.NewMPI(cipherText)
+ packetLen := 10 /* header length */ + int(cipherMPI.EncodedLength())
+
+ err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(header[:])
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(cipherMPI.EncodedBytes())
+ return err
+}
+
+func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header [10]byte, pub *elgamal.PublicKey, keyBlock []byte) error {
+ c1, c2, err := elgamal.Encrypt(rand, pub, keyBlock)
+ if err != nil {
+ return errors.InvalidArgumentError("ElGamal encryption failed: " + err.Error())
+ }
+
+ packetLen := 10 /* header length */
+ packetLen += 2 /* mpi size */ + (c1.BitLen()+7)/8
+ packetLen += 2 /* mpi size */ + (c2.BitLen()+7)/8
+
+ err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(header[:])
+ if err != nil {
+ return err
+ }
+ if _, err = w.Write(new(encoding.MPI).SetBig(c1).EncodedBytes()); err != nil {
+ return err
+ }
+ _, err = w.Write(new(encoding.MPI).SetBig(c2).EncodedBytes())
+ return err
+}
+
+func serializeEncryptedKeyECDH(w io.Writer, rand io.Reader, header [10]byte, pub *ecdh.PublicKey, keyBlock []byte, oid encoding.Field, fingerprint []byte) error {
+ vsG, c, err := ecdh.Encrypt(rand, pub, keyBlock, oid.EncodedBytes(), fingerprint)
+ if err != nil {
+ return errors.InvalidArgumentError("ECDH encryption failed: " + err.Error())
+ }
+
+ g := encoding.NewMPI(vsG)
+ m := encoding.NewOID(c)
+
+ packetLen := 10 /* header length */
+ packetLen += int(g.EncodedLength()) + int(m.EncodedLength())
+
+ err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
+ if err != nil {
+ return err
+ }
+
+ _, err = w.Write(header[:])
+ if err != nil {
+ return err
+ }
+ if _, err = w.Write(g.EncodedBytes()); err != nil {
+ return err
+ }
+ _, err = w.Write(m.EncodedBytes())
+ return err
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go
new file mode 100644
index 00000000..4be98760
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go
@@ -0,0 +1,91 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "encoding/binary"
+ "io"
+)
+
+// LiteralData represents an encrypted file. See RFC 4880, section 5.9.
+type LiteralData struct {
+ Format uint8
+ IsBinary bool
+ FileName string
+ Time uint32 // Unix epoch time. Either creation time or modification time. 0 means undefined.
+ Body io.Reader
+}
+
+// ForEyesOnly returns whether the contents of the LiteralData have been marked
+// as especially sensitive.
+func (l *LiteralData) ForEyesOnly() bool {
+ return l.FileName == "_CONSOLE"
+}
+
+func (l *LiteralData) parse(r io.Reader) (err error) {
+ var buf [256]byte
+
+ _, err = readFull(r, buf[:2])
+ if err != nil {
+ return
+ }
+
+ l.Format = buf[0]
+ l.IsBinary = l.Format == 'b'
+ fileNameLen := int(buf[1])
+
+ _, err = readFull(r, buf[:fileNameLen])
+ if err != nil {
+ return
+ }
+
+ l.FileName = string(buf[:fileNameLen])
+
+ _, err = readFull(r, buf[:4])
+ if err != nil {
+ return
+ }
+
+ l.Time = binary.BigEndian.Uint32(buf[:4])
+ l.Body = r
+ return
+}
+
+// SerializeLiteral serializes a literal data packet to w and returns a
+// WriteCloser to which the data itself can be written and which MUST be closed
+// on completion. The fileName is truncated to 255 bytes.
+func SerializeLiteral(w io.WriteCloser, isBinary bool, fileName string, time uint32) (plaintext io.WriteCloser, err error) {
+ var buf [4]byte
+ buf[0] = 't'
+ if isBinary {
+ buf[0] = 'b'
+ }
+ if len(fileName) > 255 {
+ fileName = fileName[:255]
+ }
+ buf[1] = byte(len(fileName))
+
+ inner, err := serializeStreamHeader(w, packetTypeLiteralData)
+ if err != nil {
+ return
+ }
+
+ _, err = inner.Write(buf[:2])
+ if err != nil {
+ return
+ }
+ _, err = inner.Write([]byte(fileName))
+ if err != nil {
+ return
+ }
+ binary.BigEndian.PutUint32(buf[:], time)
+ _, err = inner.Write(buf[:])
+ if err != nil {
+ return
+ }
+
+ plaintext = inner
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/notation.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/notation.go
new file mode 100644
index 00000000..2c3e3f50
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/notation.go
@@ -0,0 +1,29 @@
+package packet
+
+// Notation type represents a Notation Data subpacket
+// see https://tools.ietf.org/html/rfc4880#section-5.2.3.16
+type Notation struct {
+ Name string
+ Value []byte
+ IsCritical bool
+ IsHumanReadable bool
+}
+
+func (notation *Notation) getData() []byte {
+ nameData := []byte(notation.Name)
+ nameLen := len(nameData)
+ valueLen := len(notation.Value)
+
+ data := make([]byte, 8+nameLen+valueLen)
+ if notation.IsHumanReadable {
+ data[0] = 0x80
+ }
+
+ data[4] = byte(nameLen >> 8)
+ data[5] = byte(nameLen)
+ data[6] = byte(valueLen >> 8)
+ data[7] = byte(valueLen)
+ copy(data[8:8+nameLen], nameData)
+ copy(data[8+nameLen:], notation.Value)
+ return data
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/ocfb.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/ocfb.go
new file mode 100644
index 00000000..4f26d0a0
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/ocfb.go
@@ -0,0 +1,137 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// OpenPGP CFB Mode. http://tools.ietf.org/html/rfc4880#section-13.9
+
+package packet
+
+import (
+ "crypto/cipher"
+)
+
+type ocfbEncrypter struct {
+ b cipher.Block
+ fre []byte
+ outUsed int
+}
+
+// An OCFBResyncOption determines if the "resynchronization step" of OCFB is
+// performed.
+type OCFBResyncOption bool
+
+const (
+ OCFBResync OCFBResyncOption = true
+ OCFBNoResync OCFBResyncOption = false
+)
+
+// NewOCFBEncrypter returns a cipher.Stream which encrypts data with OpenPGP's
+// cipher feedback mode using the given cipher.Block, and an initial amount of
+// ciphertext. randData must be random bytes and be the same length as the
+// cipher.Block's block size. Resync determines if the "resynchronization step"
+// from RFC 4880, 13.9 step 7 is performed. Different parts of OpenPGP vary on
+// this point.
+func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte) {
+ blockSize := block.BlockSize()
+ if len(randData) != blockSize {
+ return nil, nil
+ }
+
+ x := &ocfbEncrypter{
+ b: block,
+ fre: make([]byte, blockSize),
+ outUsed: 0,
+ }
+ prefix := make([]byte, blockSize+2)
+
+ block.Encrypt(x.fre, x.fre)
+ for i := 0; i < blockSize; i++ {
+ prefix[i] = randData[i] ^ x.fre[i]
+ }
+
+ block.Encrypt(x.fre, prefix[:blockSize])
+ prefix[blockSize] = x.fre[0] ^ randData[blockSize-2]
+ prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1]
+
+ if resync {
+ block.Encrypt(x.fre, prefix[2:])
+ } else {
+ x.fre[0] = prefix[blockSize]
+ x.fre[1] = prefix[blockSize+1]
+ x.outUsed = 2
+ }
+ return x, prefix
+}
+
+func (x *ocfbEncrypter) XORKeyStream(dst, src []byte) {
+ for i := 0; i < len(src); i++ {
+ if x.outUsed == len(x.fre) {
+ x.b.Encrypt(x.fre, x.fre)
+ x.outUsed = 0
+ }
+
+ x.fre[x.outUsed] ^= src[i]
+ dst[i] = x.fre[x.outUsed]
+ x.outUsed++
+ }
+}
+
+type ocfbDecrypter struct {
+ b cipher.Block
+ fre []byte
+ outUsed int
+}
+
+// NewOCFBDecrypter returns a cipher.Stream which decrypts data with OpenPGP's
+// cipher feedback mode using the given cipher.Block. Prefix must be the first
+// blockSize + 2 bytes of the ciphertext, where blockSize is the cipher.Block's
+// block size. On successful exit, blockSize+2 bytes of decrypted data are written into
+// prefix. Resync determines if the "resynchronization step" from RFC 4880,
+// 13.9 step 7 is performed. Different parts of OpenPGP vary on this point.
+func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream {
+ blockSize := block.BlockSize()
+ if len(prefix) != blockSize+2 {
+ return nil
+ }
+
+ x := &ocfbDecrypter{
+ b: block,
+ fre: make([]byte, blockSize),
+ outUsed: 0,
+ }
+ prefixCopy := make([]byte, len(prefix))
+ copy(prefixCopy, prefix)
+
+ block.Encrypt(x.fre, x.fre)
+ for i := 0; i < blockSize; i++ {
+ prefixCopy[i] ^= x.fre[i]
+ }
+
+ block.Encrypt(x.fre, prefix[:blockSize])
+ prefixCopy[blockSize] ^= x.fre[0]
+ prefixCopy[blockSize+1] ^= x.fre[1]
+
+ if resync {
+ block.Encrypt(x.fre, prefix[2:])
+ } else {
+ x.fre[0] = prefix[blockSize]
+ x.fre[1] = prefix[blockSize+1]
+ x.outUsed = 2
+ }
+ copy(prefix, prefixCopy)
+ return x
+}
+
+func (x *ocfbDecrypter) XORKeyStream(dst, src []byte) {
+ for i := 0; i < len(src); i++ {
+ if x.outUsed == len(x.fre) {
+ x.b.Encrypt(x.fre, x.fre)
+ x.outUsed = 0
+ }
+
+ c := src[i]
+ dst[i] = x.fre[x.outUsed] ^ src[i]
+ x.fre[x.outUsed] = c
+ x.outUsed++
+ }
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go
new file mode 100644
index 00000000..033fb2d7
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go
@@ -0,0 +1,73 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto"
+ "encoding/binary"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "io"
+ "strconv"
+)
+
+// OnePassSignature represents a one-pass signature packet. See RFC 4880,
+// section 5.4.
+type OnePassSignature struct {
+ SigType SignatureType
+ Hash crypto.Hash
+ PubKeyAlgo PublicKeyAlgorithm
+ KeyId uint64
+ IsLast bool
+}
+
+const onePassSignatureVersion = 3
+
+func (ops *OnePassSignature) parse(r io.Reader) (err error) {
+ var buf [13]byte
+
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ if buf[0] != onePassSignatureVersion {
+ err = errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0])))
+ }
+
+ var ok bool
+ ops.Hash, ok = algorithm.HashIdToHashWithSha1(buf[2])
+ if !ok {
+ return errors.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2])))
+ }
+
+ ops.SigType = SignatureType(buf[1])
+ ops.PubKeyAlgo = PublicKeyAlgorithm(buf[3])
+ ops.KeyId = binary.BigEndian.Uint64(buf[4:12])
+ ops.IsLast = buf[12] != 0
+ return
+}
+
+// Serialize marshals the given OnePassSignature to w.
+func (ops *OnePassSignature) Serialize(w io.Writer) error {
+ var buf [13]byte
+ buf[0] = onePassSignatureVersion
+ buf[1] = uint8(ops.SigType)
+ var ok bool
+ buf[2], ok = algorithm.HashToHashIdWithSha1(ops.Hash)
+ if !ok {
+ return errors.UnsupportedError("hash type: " + strconv.Itoa(int(ops.Hash)))
+ }
+ buf[3] = uint8(ops.PubKeyAlgo)
+ binary.BigEndian.PutUint64(buf[4:12], ops.KeyId)
+ if ops.IsLast {
+ buf[12] = 1
+ }
+
+ if err := serializeHeader(w, packetTypeOnePassSignature, len(buf)); err != nil {
+ return err
+ }
+ _, err := w.Write(buf[:])
+ return err
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go
new file mode 100644
index 00000000..4f820407
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go
@@ -0,0 +1,171 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "io"
+ "io/ioutil"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// OpaquePacket represents an OpenPGP packet as raw, unparsed data. This is
+// useful for splitting and storing the original packet contents separately,
+// handling unsupported packet types or accessing parts of the packet not yet
+// implemented by this package.
+type OpaquePacket struct {
+ // Packet type
+ Tag uint8
+ // Reason why the packet was parsed opaquely
+ Reason error
+ // Binary contents of the packet data
+ Contents []byte
+}
+
+func (op *OpaquePacket) parse(r io.Reader) (err error) {
+ op.Contents, err = ioutil.ReadAll(r)
+ return
+}
+
+// Serialize marshals the packet to a writer in its original form, including
+// the packet header.
+func (op *OpaquePacket) Serialize(w io.Writer) (err error) {
+ err = serializeHeader(w, packetType(op.Tag), len(op.Contents))
+ if err == nil {
+ _, err = w.Write(op.Contents)
+ }
+ return
+}
+
+// Parse attempts to parse the opaque contents into a structure supported by
+// this package. If the packet is not known then the result will be another
+// OpaquePacket.
+func (op *OpaquePacket) Parse() (p Packet, err error) {
+ hdr := bytes.NewBuffer(nil)
+ err = serializeHeader(hdr, packetType(op.Tag), len(op.Contents))
+ if err != nil {
+ op.Reason = err
+ return op, err
+ }
+ p, err = Read(io.MultiReader(hdr, bytes.NewBuffer(op.Contents)))
+ if err != nil {
+ op.Reason = err
+ p = op
+ }
+ return
+}
+
+// OpaqueReader reads OpaquePackets from an io.Reader.
+type OpaqueReader struct {
+ r io.Reader
+}
+
+func NewOpaqueReader(r io.Reader) *OpaqueReader {
+ return &OpaqueReader{r: r}
+}
+
+// Read the next OpaquePacket.
+func (or *OpaqueReader) Next() (op *OpaquePacket, err error) {
+ tag, _, contents, err := readHeader(or.r)
+ if err != nil {
+ return
+ }
+ op = &OpaquePacket{Tag: uint8(tag), Reason: err}
+ err = op.parse(contents)
+ if err != nil {
+ consumeAll(contents)
+ }
+ return
+}
+
+// OpaqueSubpacket represents an unparsed OpenPGP subpacket,
+// as found in signature and user attribute packets.
+type OpaqueSubpacket struct {
+ SubType uint8
+ EncodedLength []byte // Store the original encoded length for signature verifications.
+ Contents []byte
+}
+
+// OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from
+// their byte representation.
+func OpaqueSubpackets(contents []byte) (result []*OpaqueSubpacket, err error) {
+ var (
+ subHeaderLen int
+ subPacket *OpaqueSubpacket
+ )
+ for len(contents) > 0 {
+ subHeaderLen, subPacket, err = nextSubpacket(contents)
+ if err != nil {
+ break
+ }
+ result = append(result, subPacket)
+ contents = contents[subHeaderLen+len(subPacket.Contents):]
+ }
+ return
+}
+
+func nextSubpacket(contents []byte) (subHeaderLen int, subPacket *OpaqueSubpacket, err error) {
+ // RFC 4880, section 5.2.3.1
+ var subLen uint32
+ var encodedLength []byte
+ if len(contents) < 1 {
+ goto Truncated
+ }
+ subPacket = &OpaqueSubpacket{}
+ switch {
+ case contents[0] < 192:
+ subHeaderLen = 2 // 1 length byte, 1 subtype byte
+ if len(contents) < subHeaderLen {
+ goto Truncated
+ }
+ encodedLength = contents[0:1]
+ subLen = uint32(contents[0])
+ contents = contents[1:]
+ case contents[0] < 255:
+ subHeaderLen = 3 // 2 length bytes, 1 subtype
+ if len(contents) < subHeaderLen {
+ goto Truncated
+ }
+ encodedLength = contents[0:2]
+ subLen = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192
+ contents = contents[2:]
+ default:
+ subHeaderLen = 6 // 5 length bytes, 1 subtype
+ if len(contents) < subHeaderLen {
+ goto Truncated
+ }
+ encodedLength = contents[0:5]
+ subLen = uint32(contents[1])<<24 |
+ uint32(contents[2])<<16 |
+ uint32(contents[3])<<8 |
+ uint32(contents[4])
+ contents = contents[5:]
+
+ }
+ if subLen > uint32(len(contents)) || subLen == 0 {
+ goto Truncated
+ }
+ subPacket.SubType = contents[0]
+ subPacket.EncodedLength = encodedLength
+ subPacket.Contents = contents[1:subLen]
+ return
+Truncated:
+ err = errors.StructuralError("subpacket truncated")
+ return
+}
+
+func (osp *OpaqueSubpacket) Serialize(w io.Writer) (err error) {
+ buf := make([]byte, 6)
+ copy(buf, osp.EncodedLength)
+ n := len(osp.EncodedLength)
+
+ buf[n] = osp.SubType
+ if _, err = w.Write(buf[:n+1]); err != nil {
+ return
+ }
+ _, err = w.Write(osp.Contents)
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go
new file mode 100644
index 00000000..4d86a7da
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go
@@ -0,0 +1,551 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package packet implements parsing and serialization of OpenPGP packets, as
+// specified in RFC 4880.
+package packet // import "github.com/ProtonMail/go-crypto/openpgp/packet"
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "crypto/rsa"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+)
+
+// readFull is the same as io.ReadFull except that reading zero bytes returns
+// ErrUnexpectedEOF rather than EOF.
+func readFull(r io.Reader, buf []byte) (n int, err error) {
+ n, err = io.ReadFull(r, buf)
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return
+}
+
+// readLength reads an OpenPGP length from r. See RFC 4880, section 4.2.2.
+func readLength(r io.Reader) (length int64, isPartial bool, err error) {
+ var buf [4]byte
+ _, err = readFull(r, buf[:1])
+ if err != nil {
+ return
+ }
+ switch {
+ case buf[0] < 192:
+ length = int64(buf[0])
+ case buf[0] < 224:
+ length = int64(buf[0]-192) << 8
+ _, err = readFull(r, buf[0:1])
+ if err != nil {
+ return
+ }
+ length += int64(buf[0]) + 192
+ case buf[0] < 255:
+ length = int64(1) << (buf[0] & 0x1f)
+ isPartial = true
+ default:
+ _, err = readFull(r, buf[0:4])
+ if err != nil {
+ return
+ }
+ length = int64(buf[0])<<24 |
+ int64(buf[1])<<16 |
+ int64(buf[2])<<8 |
+ int64(buf[3])
+ }
+ return
+}
+
+// partialLengthReader wraps an io.Reader and handles OpenPGP partial lengths.
+// The continuation lengths are parsed and removed from the stream and EOF is
+// returned at the end of the packet. See RFC 4880, section 4.2.2.4.
+type partialLengthReader struct {
+ r io.Reader
+ remaining int64
+ isPartial bool
+}
+
+func (r *partialLengthReader) Read(p []byte) (n int, err error) {
+ for r.remaining == 0 {
+ if !r.isPartial {
+ return 0, io.EOF
+ }
+ r.remaining, r.isPartial, err = readLength(r.r)
+ if err != nil {
+ return 0, err
+ }
+ }
+
+ toRead := int64(len(p))
+ if toRead > r.remaining {
+ toRead = r.remaining
+ }
+
+ n, err = r.r.Read(p[:int(toRead)])
+ r.remaining -= int64(n)
+ if n < int(toRead) && err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return
+}
+
+// partialLengthWriter writes a stream of data using OpenPGP partial lengths.
+// See RFC 4880, section 4.2.2.4.
+type partialLengthWriter struct {
+ w io.WriteCloser
+ buf bytes.Buffer
+ lengthByte [1]byte
+}
+
+func (w *partialLengthWriter) Write(p []byte) (n int, err error) {
+ bufLen := w.buf.Len()
+ if bufLen > 512 {
+ for power := uint(30); ; power-- {
+ l := 1 << power
+ if bufLen >= l {
+ w.lengthByte[0] = 224 + uint8(power)
+ _, err = w.w.Write(w.lengthByte[:])
+ if err != nil {
+ return
+ }
+ var m int
+ m, err = w.w.Write(w.buf.Next(l))
+ if err != nil {
+ return
+ }
+ if m != l {
+ return 0, io.ErrShortWrite
+ }
+ break
+ }
+ }
+ }
+ return w.buf.Write(p)
+}
+
+func (w *partialLengthWriter) Close() (err error) {
+ len := w.buf.Len()
+ err = serializeLength(w.w, len)
+ if err != nil {
+ return err
+ }
+ _, err = w.buf.WriteTo(w.w)
+ if err != nil {
+ return err
+ }
+ return w.w.Close()
+}
+
+// A spanReader is an io.LimitReader, but it returns ErrUnexpectedEOF if the
+// underlying Reader returns EOF before the limit has been reached.
+type spanReader struct {
+ r io.Reader
+ n int64
+}
+
+func (l *spanReader) Read(p []byte) (n int, err error) {
+ if l.n <= 0 {
+ return 0, io.EOF
+ }
+ if int64(len(p)) > l.n {
+ p = p[0:l.n]
+ }
+ n, err = l.r.Read(p)
+ l.n -= int64(n)
+ if l.n > 0 && err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return
+}
+
+// readHeader parses a packet header and returns an io.Reader which will return
+// the contents of the packet. See RFC 4880, section 4.2.
+func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader, err error) {
+ var buf [4]byte
+ _, err = io.ReadFull(r, buf[:1])
+ if err != nil {
+ return
+ }
+ if buf[0]&0x80 == 0 {
+ err = errors.StructuralError("tag byte does not have MSB set")
+ return
+ }
+ if buf[0]&0x40 == 0 {
+ // Old format packet
+ tag = packetType((buf[0] & 0x3f) >> 2)
+ lengthType := buf[0] & 3
+ if lengthType == 3 {
+ length = -1
+ contents = r
+ return
+ }
+ lengthBytes := 1 << lengthType
+ _, err = readFull(r, buf[0:lengthBytes])
+ if err != nil {
+ return
+ }
+ for i := 0; i < lengthBytes; i++ {
+ length <<= 8
+ length |= int64(buf[i])
+ }
+ contents = &spanReader{r, length}
+ return
+ }
+
+ // New format packet
+ tag = packetType(buf[0] & 0x3f)
+ length, isPartial, err := readLength(r)
+ if err != nil {
+ return
+ }
+ if isPartial {
+ contents = &partialLengthReader{
+ remaining: length,
+ isPartial: true,
+ r: r,
+ }
+ length = -1
+ } else {
+ contents = &spanReader{r, length}
+ }
+ return
+}
+
+// serializeHeader writes an OpenPGP packet header to w. See RFC 4880, section
+// 4.2.
+func serializeHeader(w io.Writer, ptype packetType, length int) (err error) {
+ err = serializeType(w, ptype)
+ if err != nil {
+ return
+ }
+ return serializeLength(w, length)
+}
+
+// serializeType writes an OpenPGP packet type to w. See RFC 4880, section
+// 4.2.
+func serializeType(w io.Writer, ptype packetType) (err error) {
+ var buf [1]byte
+ buf[0] = 0x80 | 0x40 | byte(ptype)
+ _, err = w.Write(buf[:])
+ return
+}
+
+// serializeLength writes an OpenPGP packet length to w. See RFC 4880, section
+// 4.2.2.
+func serializeLength(w io.Writer, length int) (err error) {
+ var buf [5]byte
+ var n int
+
+ if length < 192 {
+ buf[0] = byte(length)
+ n = 1
+ } else if length < 8384 {
+ length -= 192
+ buf[0] = 192 + byte(length>>8)
+ buf[1] = byte(length)
+ n = 2
+ } else {
+ buf[0] = 255
+ buf[1] = byte(length >> 24)
+ buf[2] = byte(length >> 16)
+ buf[3] = byte(length >> 8)
+ buf[4] = byte(length)
+ n = 5
+ }
+
+ _, err = w.Write(buf[:n])
+ return
+}
+
+// serializeStreamHeader writes an OpenPGP packet header to w where the
+// length of the packet is unknown. It returns a io.WriteCloser which can be
+// used to write the contents of the packet. See RFC 4880, section 4.2.
+func serializeStreamHeader(w io.WriteCloser, ptype packetType) (out io.WriteCloser, err error) {
+ err = serializeType(w, ptype)
+ if err != nil {
+ return
+ }
+ out = &partialLengthWriter{w: w}
+ return
+}
+
+// Packet represents an OpenPGP packet. Users are expected to try casting
+// instances of this interface to specific packet types.
+type Packet interface {
+ parse(io.Reader) error
+}
+
+// consumeAll reads from the given Reader until error, returning the number of
+// bytes read.
+func consumeAll(r io.Reader) (n int64, err error) {
+ var m int
+ var buf [1024]byte
+
+ for {
+ m, err = r.Read(buf[:])
+ n += int64(m)
+ if err == io.EOF {
+ err = nil
+ return
+ }
+ if err != nil {
+ return
+ }
+ }
+}
+
+// packetType represents the numeric ids of the different OpenPGP packet types. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-2
+type packetType uint8
+
+const (
+ packetTypeEncryptedKey packetType = 1
+ packetTypeSignature packetType = 2
+ packetTypeSymmetricKeyEncrypted packetType = 3
+ packetTypeOnePassSignature packetType = 4
+ packetTypePrivateKey packetType = 5
+ packetTypePublicKey packetType = 6
+ packetTypePrivateSubkey packetType = 7
+ packetTypeCompressed packetType = 8
+ packetTypeSymmetricallyEncrypted packetType = 9
+ packetTypeLiteralData packetType = 11
+ packetTypeUserId packetType = 13
+ packetTypePublicSubkey packetType = 14
+ packetTypeUserAttribute packetType = 17
+ packetTypeSymmetricallyEncryptedIntegrityProtected packetType = 18
+ packetTypeAEADEncrypted packetType = 20
+)
+
+// EncryptedDataPacket holds encrypted data. It is currently implemented by
+// SymmetricallyEncrypted and AEADEncrypted.
+type EncryptedDataPacket interface {
+ Decrypt(CipherFunction, []byte) (io.ReadCloser, error)
+}
+
+// Read reads a single OpenPGP packet from the given io.Reader. If there is an
+// error parsing a packet, the whole packet is consumed from the input.
+func Read(r io.Reader) (p Packet, err error) {
+ tag, _, contents, err := readHeader(r)
+ if err != nil {
+ return
+ }
+
+ switch tag {
+ case packetTypeEncryptedKey:
+ p = new(EncryptedKey)
+ case packetTypeSignature:
+ p = new(Signature)
+ case packetTypeSymmetricKeyEncrypted:
+ p = new(SymmetricKeyEncrypted)
+ case packetTypeOnePassSignature:
+ p = new(OnePassSignature)
+ case packetTypePrivateKey, packetTypePrivateSubkey:
+ pk := new(PrivateKey)
+ if tag == packetTypePrivateSubkey {
+ pk.IsSubkey = true
+ }
+ p = pk
+ case packetTypePublicKey, packetTypePublicSubkey:
+ isSubkey := tag == packetTypePublicSubkey
+ p = &PublicKey{IsSubkey: isSubkey}
+ case packetTypeCompressed:
+ p = new(Compressed)
+ case packetTypeSymmetricallyEncrypted:
+ p = new(SymmetricallyEncrypted)
+ case packetTypeLiteralData:
+ p = new(LiteralData)
+ case packetTypeUserId:
+ p = new(UserId)
+ case packetTypeUserAttribute:
+ p = new(UserAttribute)
+ case packetTypeSymmetricallyEncryptedIntegrityProtected:
+ se := new(SymmetricallyEncrypted)
+ se.IntegrityProtected = true
+ p = se
+ case packetTypeAEADEncrypted:
+ p = new(AEADEncrypted)
+ default:
+ err = errors.UnknownPacketTypeError(tag)
+ }
+ if p != nil {
+ err = p.parse(contents)
+ }
+ if err != nil {
+ consumeAll(contents)
+ }
+ return
+}
+
+// SignatureType represents the different semantic meanings of an OpenPGP
+// signature. See RFC 4880, section 5.2.1.
+type SignatureType uint8
+
+const (
+ SigTypeBinary SignatureType = 0x00
+ SigTypeText = 0x01
+ SigTypeGenericCert = 0x10
+ SigTypePersonaCert = 0x11
+ SigTypeCasualCert = 0x12
+ SigTypePositiveCert = 0x13
+ SigTypeSubkeyBinding = 0x18
+ SigTypePrimaryKeyBinding = 0x19
+ SigTypeDirectSignature = 0x1F
+ SigTypeKeyRevocation = 0x20
+ SigTypeSubkeyRevocation = 0x28
+ SigTypeCertificationRevocation = 0x30
+)
+
+// PublicKeyAlgorithm represents the different public key system specified for
+// OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12
+type PublicKeyAlgorithm uint8
+
+const (
+ PubKeyAlgoRSA PublicKeyAlgorithm = 1
+ PubKeyAlgoElGamal PublicKeyAlgorithm = 16
+ PubKeyAlgoDSA PublicKeyAlgorithm = 17
+ // RFC 6637, Section 5.
+ PubKeyAlgoECDH PublicKeyAlgorithm = 18
+ PubKeyAlgoECDSA PublicKeyAlgorithm = 19
+ // https://www.ietf.org/archive/id/draft-koch-eddsa-for-openpgp-04.txt
+ PubKeyAlgoEdDSA PublicKeyAlgorithm = 22
+
+ // Deprecated in RFC 4880, Section 13.5. Use key flags instead.
+ PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
+ PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3
+)
+
+// CanEncrypt returns true if it's possible to encrypt a message to a public
+// key of the given type.
+func (pka PublicKeyAlgorithm) CanEncrypt() bool {
+ switch pka {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal, PubKeyAlgoECDH:
+ return true
+ }
+ return false
+}
+
+// CanSign returns true if it's possible for a public key of the given type to
+// sign a message.
+func (pka PublicKeyAlgorithm) CanSign() bool {
+ switch pka {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA:
+ return true
+ }
+ return false
+}
+
+// CipherFunction represents the different block ciphers specified for OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
+type CipherFunction algorithm.CipherFunction
+
+const (
+ Cipher3DES CipherFunction = 2
+ CipherCAST5 CipherFunction = 3
+ CipherAES128 CipherFunction = 7
+ CipherAES192 CipherFunction = 8
+ CipherAES256 CipherFunction = 9
+)
+
+// KeySize returns the key size, in bytes, of cipher.
+func (cipher CipherFunction) KeySize() int {
+ return algorithm.CipherFunction(cipher).KeySize()
+}
+
+// IsSupported returns true if the cipher is supported from the library
+func (cipher CipherFunction) IsSupported() bool {
+ return algorithm.CipherFunction(cipher).KeySize() > 0
+}
+
+// blockSize returns the block size, in bytes, of cipher.
+func (cipher CipherFunction) blockSize() int {
+ return algorithm.CipherFunction(cipher).BlockSize()
+}
+
+// new returns a fresh instance of the given cipher.
+func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
+ return algorithm.CipherFunction(cipher).New(key)
+}
+
+// padToKeySize left-pads a MPI with zeroes to match the length of the
+// specified RSA public.
+func padToKeySize(pub *rsa.PublicKey, b []byte) []byte {
+ k := (pub.N.BitLen() + 7) / 8
+ if len(b) >= k {
+ return b
+ }
+ bb := make([]byte, k)
+ copy(bb[len(bb)-len(b):], b)
+ return bb
+}
+
+// CompressionAlgo Represents the different compression algorithms
+// supported by OpenPGP (except for BZIP2, which is not currently
+// supported). See Section 9.3 of RFC 4880.
+type CompressionAlgo uint8
+
+const (
+ CompressionNone CompressionAlgo = 0
+ CompressionZIP CompressionAlgo = 1
+ CompressionZLIB CompressionAlgo = 2
+)
+
+// AEADMode represents the different Authenticated Encryption with Associated
+// Data specified for OpenPGP.
+// See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.6
+type AEADMode algorithm.AEADMode
+
+const (
+ AEADModeEAX AEADMode = 1
+ AEADModeOCB AEADMode = 2
+ AEADModeGCM AEADMode = 3
+)
+
+func (mode AEADMode) IvLength() int {
+ return algorithm.AEADMode(mode).NonceLength()
+}
+
+func (mode AEADMode) TagLength() int {
+ return algorithm.AEADMode(mode).TagLength()
+}
+
+// new returns a fresh instance of the given mode.
+func (mode AEADMode) new(block cipher.Block) cipher.AEAD {
+ return algorithm.AEADMode(mode).New(block)
+}
+
+// ReasonForRevocation represents a revocation reason code as per RFC4880
+// section 5.2.3.23.
+type ReasonForRevocation uint8
+
+const (
+ NoReason ReasonForRevocation = 0
+ KeySuperseded ReasonForRevocation = 1
+ KeyCompromised ReasonForRevocation = 2
+ KeyRetired ReasonForRevocation = 3
+)
+
+// Curve is a mapping to supported ECC curves for key generation.
+// See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-06.html#name-curve-specific-wire-formats
+type Curve string
+
+const (
+ Curve25519 Curve = "Curve25519"
+ Curve448 Curve = "Curve448"
+ CurveNistP256 Curve = "P256"
+ CurveNistP384 Curve = "P384"
+ CurveNistP521 Curve = "P521"
+ CurveSecP256k1 Curve = "SecP256k1"
+ CurveBrainpoolP256 Curve = "BrainpoolP256"
+ CurveBrainpoolP384 Curve = "BrainpoolP384"
+ CurveBrainpoolP512 Curve = "BrainpoolP512"
+)
+
+// TrustLevel represents a trust level per RFC4880 5.2.3.13
+type TrustLevel uint8
+
+// TrustAmount represents a trust amount per RFC4880 5.2.3.13
+type TrustAmount uint8
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go
new file mode 100644
index 00000000..2fc43864
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go
@@ -0,0 +1,837 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/cipher"
+ "crypto/dsa"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha1"
+ "io"
+ "io/ioutil"
+ "math/big"
+ "strconv"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdh"
+ "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
+ "github.com/ProtonMail/go-crypto/openpgp/eddsa"
+ "github.com/ProtonMail/go-crypto/openpgp/elgamal"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+ "github.com/ProtonMail/go-crypto/openpgp/s2k"
+)
+
+// PrivateKey represents a possibly encrypted private key. See RFC 4880,
+// section 5.5.3.
+type PrivateKey struct {
+ PublicKey
+ Encrypted bool // if true then the private key is unavailable until Decrypt has been called.
+ encryptedData []byte
+ cipher CipherFunction
+ s2k func(out, in []byte)
+ // An *{rsa|dsa|elgamal|ecdh|ecdsa|ed25519}.PrivateKey or
+ // crypto.Signer/crypto.Decrypter (Decryptor RSA only).
+ PrivateKey interface{}
+ sha1Checksum bool
+ iv []byte
+
+ // Type of encryption of the S2K packet
+ // Allowed values are 0 (Not encrypted), 254 (SHA1), or
+ // 255 (2-byte checksum)
+ s2kType S2KType
+ // Full parameters of the S2K packet
+ s2kParams *s2k.Params
+}
+
+// S2KType s2k packet type
+type S2KType uint8
+
+const (
+ // S2KNON unencrypt
+ S2KNON S2KType = 0
+ // S2KSHA1 sha1 sum check
+ S2KSHA1 S2KType = 254
+ // S2KCHECKSUM sum check
+ S2KCHECKSUM S2KType = 255
+)
+
+func NewRSAPrivateKey(creationTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewRSAPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewDSAPrivateKey(creationTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewDSAPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewElGamalPrivateKey(creationTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewECDSAPrivateKey(creationTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewECDSAPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewEdDSAPrivateKey(creationTime time.Time, priv *eddsa.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewEdDSAPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewECDHPrivateKey(creationTime time.Time, priv *ecdh.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewECDHPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+// NewSignerPrivateKey creates a PrivateKey from a crypto.Signer that
+// implements RSA, ECDSA or EdDSA.
+func NewSignerPrivateKey(creationTime time.Time, signer interface{}) *PrivateKey {
+ pk := new(PrivateKey)
+ // In general, the public Keys should be used as pointers. We still
+ // type-switch on the values, for backwards-compatibility.
+ switch pubkey := signer.(type) {
+ case *rsa.PrivateKey:
+ pk.PublicKey = *NewRSAPublicKey(creationTime, &pubkey.PublicKey)
+ case rsa.PrivateKey:
+ pk.PublicKey = *NewRSAPublicKey(creationTime, &pubkey.PublicKey)
+ case *ecdsa.PrivateKey:
+ pk.PublicKey = *NewECDSAPublicKey(creationTime, &pubkey.PublicKey)
+ case ecdsa.PrivateKey:
+ pk.PublicKey = *NewECDSAPublicKey(creationTime, &pubkey.PublicKey)
+ case *eddsa.PrivateKey:
+ pk.PublicKey = *NewEdDSAPublicKey(creationTime, &pubkey.PublicKey)
+ case eddsa.PrivateKey:
+ pk.PublicKey = *NewEdDSAPublicKey(creationTime, &pubkey.PublicKey)
+ default:
+ panic("openpgp: unknown signer type in NewSignerPrivateKey")
+ }
+ pk.PrivateKey = signer
+ return pk
+}
+
+// NewDecrypterPrivateKey creates a PrivateKey from a *{rsa|elgamal|ecdh}.PrivateKey.
+func NewDecrypterPrivateKey(creationTime time.Time, decrypter interface{}) *PrivateKey {
+ pk := new(PrivateKey)
+ switch priv := decrypter.(type) {
+ case *rsa.PrivateKey:
+ pk.PublicKey = *NewRSAPublicKey(creationTime, &priv.PublicKey)
+ case *elgamal.PrivateKey:
+ pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey)
+ case *ecdh.PrivateKey:
+ pk.PublicKey = *NewECDHPublicKey(creationTime, &priv.PublicKey)
+ default:
+ panic("openpgp: unknown decrypter type in NewDecrypterPrivateKey")
+ }
+ pk.PrivateKey = decrypter
+ return pk
+}
+
+func (pk *PrivateKey) parse(r io.Reader) (err error) {
+ err = (&pk.PublicKey).parse(r)
+ if err != nil {
+ return
+ }
+ v5 := pk.PublicKey.Version == 5
+
+ var buf [1]byte
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ pk.s2kType = S2KType(buf[0])
+ var optCount [1]byte
+ if v5 {
+ if _, err = readFull(r, optCount[:]); err != nil {
+ return
+ }
+ }
+
+ switch pk.s2kType {
+ case S2KNON:
+ pk.s2k = nil
+ pk.Encrypted = false
+ case S2KSHA1, S2KCHECKSUM:
+ if v5 && pk.s2kType == S2KCHECKSUM {
+ return errors.StructuralError("wrong s2k identifier for version 5")
+ }
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ pk.cipher = CipherFunction(buf[0])
+ if pk.cipher != 0 && !pk.cipher.IsSupported() {
+ return errors.UnsupportedError("unsupported cipher function in private key")
+ }
+ pk.s2kParams, err = s2k.ParseIntoParams(r)
+ if err != nil {
+ return
+ }
+ if pk.s2kParams.Dummy() {
+ return
+ }
+ pk.s2k, err = pk.s2kParams.Function()
+ if err != nil {
+ return
+ }
+ pk.Encrypted = true
+ if pk.s2kType == S2KSHA1 {
+ pk.sha1Checksum = true
+ }
+ default:
+ return errors.UnsupportedError("deprecated s2k function in private key")
+ }
+
+ if pk.Encrypted {
+ blockSize := pk.cipher.blockSize()
+ if blockSize == 0 {
+ return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
+ }
+ pk.iv = make([]byte, blockSize)
+ _, err = readFull(r, pk.iv)
+ if err != nil {
+ return
+ }
+ }
+
+ var privateKeyData []byte
+ if v5 {
+ var n [4]byte /* secret material four octet count */
+ _, err = readFull(r, n[:])
+ if err != nil {
+ return
+ }
+ count := uint32(uint32(n[0])<<24 | uint32(n[1])<<16 | uint32(n[2])<<8 | uint32(n[3]))
+ if !pk.Encrypted {
+ count = count + 2 /* two octet checksum */
+ }
+ privateKeyData = make([]byte, count)
+ _, err = readFull(r, privateKeyData)
+ if err != nil {
+ return
+ }
+ } else {
+ privateKeyData, err = ioutil.ReadAll(r)
+ if err != nil {
+ return
+ }
+ }
+ if !pk.Encrypted {
+ if len(privateKeyData) < 2 {
+ return errors.StructuralError("truncated private key data")
+ }
+ var sum uint16
+ for i := 0; i < len(privateKeyData)-2; i++ {
+ sum += uint16(privateKeyData[i])
+ }
+ if privateKeyData[len(privateKeyData)-2] != uint8(sum>>8) ||
+ privateKeyData[len(privateKeyData)-1] != uint8(sum) {
+ return errors.StructuralError("private key checksum failure")
+ }
+ privateKeyData = privateKeyData[:len(privateKeyData)-2]
+ return pk.parsePrivateKey(privateKeyData)
+ }
+
+ pk.encryptedData = privateKeyData
+ return
+}
+
+// Dummy returns true if the private key is a dummy key. This is a GNU extension.
+func (pk *PrivateKey) Dummy() bool {
+ return pk.s2kParams.Dummy()
+}
+
+func mod64kHash(d []byte) uint16 {
+ var h uint16
+ for _, b := range d {
+ h += uint16(b)
+ }
+ return h
+}
+
+func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
+ contents := bytes.NewBuffer(nil)
+ err = pk.PublicKey.serializeWithoutHeaders(contents)
+ if err != nil {
+ return
+ }
+ if _, err = contents.Write([]byte{uint8(pk.s2kType)}); err != nil {
+ return
+ }
+
+ optional := bytes.NewBuffer(nil)
+ if pk.Encrypted || pk.Dummy() {
+ optional.Write([]byte{uint8(pk.cipher)})
+ if err := pk.s2kParams.Serialize(optional); err != nil {
+ return err
+ }
+ if pk.Encrypted {
+ optional.Write(pk.iv)
+ }
+ }
+ if pk.Version == 5 {
+ contents.Write([]byte{uint8(optional.Len())})
+ }
+ io.Copy(contents, optional)
+
+ if !pk.Dummy() {
+ l := 0
+ var priv []byte
+ if !pk.Encrypted {
+ buf := bytes.NewBuffer(nil)
+ err = pk.serializePrivateKey(buf)
+ if err != nil {
+ return err
+ }
+ l = buf.Len()
+ checksum := mod64kHash(buf.Bytes())
+ buf.Write([]byte{byte(checksum >> 8), byte(checksum)})
+ priv = buf.Bytes()
+ } else {
+ priv, l = pk.encryptedData, len(pk.encryptedData)
+ }
+
+ if pk.Version == 5 {
+ contents.Write([]byte{byte(l >> 24), byte(l >> 16), byte(l >> 8), byte(l)})
+ }
+ contents.Write(priv)
+ }
+
+ ptype := packetTypePrivateKey
+ if pk.IsSubkey {
+ ptype = packetTypePrivateSubkey
+ }
+ err = serializeHeader(w, ptype, contents.Len())
+ if err != nil {
+ return
+ }
+ _, err = io.Copy(w, contents)
+ if err != nil {
+ return
+ }
+ return
+}
+
+func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
+ if _, err := w.Write(new(encoding.MPI).SetBig(priv.D).EncodedBytes()); err != nil {
+ return err
+ }
+ if _, err := w.Write(new(encoding.MPI).SetBig(priv.Primes[1]).EncodedBytes()); err != nil {
+ return err
+ }
+ if _, err := w.Write(new(encoding.MPI).SetBig(priv.Primes[0]).EncodedBytes()); err != nil {
+ return err
+ }
+ _, err := w.Write(new(encoding.MPI).SetBig(priv.Precomputed.Qinv).EncodedBytes())
+ return err
+}
+
+func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
+ _, err := w.Write(new(encoding.MPI).SetBig(priv.X).EncodedBytes())
+ return err
+}
+
+func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error {
+ _, err := w.Write(new(encoding.MPI).SetBig(priv.X).EncodedBytes())
+ return err
+}
+
+func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error {
+ _, err := w.Write(encoding.NewMPI(priv.MarshalIntegerSecret()).EncodedBytes())
+ return err
+}
+
+func serializeEdDSAPrivateKey(w io.Writer, priv *eddsa.PrivateKey) error {
+ _, err := w.Write(encoding.NewMPI(priv.MarshalByteSecret()).EncodedBytes())
+ return err
+}
+
+func serializeECDHPrivateKey(w io.Writer, priv *ecdh.PrivateKey) error {
+ _, err := w.Write(encoding.NewMPI(priv.MarshalByteSecret()).EncodedBytes())
+ return err
+}
+
+// decrypt decrypts an encrypted private key using a decryption key.
+func (pk *PrivateKey) decrypt(decryptionKey []byte) error {
+ if pk.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ if !pk.Encrypted {
+ return nil
+ }
+
+ block := pk.cipher.new(decryptionKey)
+ cfb := cipher.NewCFBDecrypter(block, pk.iv)
+
+ data := make([]byte, len(pk.encryptedData))
+ cfb.XORKeyStream(data, pk.encryptedData)
+
+ if pk.sha1Checksum {
+ if len(data) < sha1.Size {
+ return errors.StructuralError("truncated private key data")
+ }
+ h := sha1.New()
+ h.Write(data[:len(data)-sha1.Size])
+ sum := h.Sum(nil)
+ if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
+ return errors.StructuralError("private key checksum failure")
+ }
+ data = data[:len(data)-sha1.Size]
+ } else {
+ if len(data) < 2 {
+ return errors.StructuralError("truncated private key data")
+ }
+ var sum uint16
+ for i := 0; i < len(data)-2; i++ {
+ sum += uint16(data[i])
+ }
+ if data[len(data)-2] != uint8(sum>>8) ||
+ data[len(data)-1] != uint8(sum) {
+ return errors.StructuralError("private key checksum failure")
+ }
+ data = data[:len(data)-2]
+ }
+
+ err := pk.parsePrivateKey(data)
+ if _, ok := err.(errors.KeyInvalidError); ok {
+ return errors.KeyInvalidError("invalid key parameters")
+ }
+ if err != nil {
+ return err
+ }
+
+ // Mark key as unencrypted
+ pk.s2kType = S2KNON
+ pk.s2k = nil
+ pk.Encrypted = false
+ pk.encryptedData = nil
+
+ return nil
+}
+
+func (pk *PrivateKey) decryptWithCache(passphrase []byte, keyCache *s2k.Cache) error {
+ if pk.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ if !pk.Encrypted {
+ return nil
+ }
+
+ key, err := keyCache.GetOrComputeDerivedKey(passphrase, pk.s2kParams, pk.cipher.KeySize())
+ if err != nil {
+ return err
+ }
+ return pk.decrypt(key)
+}
+
+// Decrypt decrypts an encrypted private key using a passphrase.
+func (pk *PrivateKey) Decrypt(passphrase []byte) error {
+ if pk.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ if !pk.Encrypted {
+ return nil
+ }
+
+ key := make([]byte, pk.cipher.KeySize())
+ pk.s2k(key, passphrase)
+ return pk.decrypt(key)
+}
+
+// DecryptPrivateKeys decrypts all encrypted keys with the given config and passphrase.
+// Avoids recomputation of similar s2k key derivations.
+func DecryptPrivateKeys(keys []*PrivateKey, passphrase []byte) error {
+ // Create a cache to avoid recomputation of key derviations for the same passphrase.
+ s2kCache := &s2k.Cache{}
+ for _, key := range keys {
+ if key != nil && !key.Dummy() && key.Encrypted {
+ err := key.decryptWithCache(passphrase, s2kCache)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// encrypt encrypts an unencrypted private key.
+func (pk *PrivateKey) encrypt(key []byte, params *s2k.Params, cipherFunction CipherFunction) error {
+ if pk.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ if pk.Encrypted {
+ return nil
+ }
+ // check if encryptionKey has the correct size
+ if len(key) != cipherFunction.KeySize() {
+ return errors.InvalidArgumentError("supplied encryption key has the wrong size")
+ }
+
+ priv := bytes.NewBuffer(nil)
+ err := pk.serializePrivateKey(priv)
+ if err != nil {
+ return err
+ }
+
+ pk.cipher = cipherFunction
+ pk.s2kParams = params
+ pk.s2k, err = pk.s2kParams.Function()
+ if err != nil {
+ return err
+ }
+
+ privateKeyBytes := priv.Bytes()
+ pk.sha1Checksum = true
+ block := pk.cipher.new(key)
+ pk.iv = make([]byte, pk.cipher.blockSize())
+ _, err = rand.Read(pk.iv)
+ if err != nil {
+ return err
+ }
+ cfb := cipher.NewCFBEncrypter(block, pk.iv)
+
+ if pk.sha1Checksum {
+ pk.s2kType = S2KSHA1
+ h := sha1.New()
+ h.Write(privateKeyBytes)
+ sum := h.Sum(nil)
+ privateKeyBytes = append(privateKeyBytes, sum...)
+ } else {
+ pk.s2kType = S2KCHECKSUM
+ var sum uint16
+ for _, b := range privateKeyBytes {
+ sum += uint16(b)
+ }
+ priv.Write([]byte{uint8(sum >> 8), uint8(sum)})
+ }
+
+ pk.encryptedData = make([]byte, len(privateKeyBytes))
+ cfb.XORKeyStream(pk.encryptedData, privateKeyBytes)
+ pk.Encrypted = true
+ pk.PrivateKey = nil
+ return err
+}
+
+// EncryptWithConfig encrypts an unencrypted private key using the passphrase and the config.
+func (pk *PrivateKey) EncryptWithConfig(passphrase []byte, config *Config) error {
+ params, err := s2k.Generate(config.Random(), config.S2K())
+ if err != nil {
+ return err
+ }
+ // Derive an encryption key with the configured s2k function.
+ key := make([]byte, config.Cipher().KeySize())
+ s2k, err := params.Function()
+ if err != nil {
+ return err
+ }
+ s2k(key, passphrase)
+ // Encrypt the private key with the derived encryption key.
+ return pk.encrypt(key, params, config.Cipher())
+}
+
+// EncryptPrivateKeys encrypts all unencrypted keys with the given config and passphrase.
+// Only derives one key from the passphrase, which is then used to encrypt each key.
+func EncryptPrivateKeys(keys []*PrivateKey, passphrase []byte, config *Config) error {
+ params, err := s2k.Generate(config.Random(), config.S2K())
+ if err != nil {
+ return err
+ }
+ // Derive an encryption key with the configured s2k function.
+ encryptionKey := make([]byte, config.Cipher().KeySize())
+ s2k, err := params.Function()
+ if err != nil {
+ return err
+ }
+ s2k(encryptionKey, passphrase)
+ for _, key := range keys {
+ if key != nil && !key.Dummy() && !key.Encrypted {
+ err = key.encrypt(encryptionKey, params, config.Cipher())
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// Encrypt encrypts an unencrypted private key using a passphrase.
+func (pk *PrivateKey) Encrypt(passphrase []byte) error {
+ // Default config of private key encryption
+ config := &Config{
+ S2KConfig: &s2k.Config{
+ S2KMode: s2k.IteratedSaltedS2K,
+ S2KCount: 65536,
+ Hash: crypto.SHA256,
+ } ,
+ DefaultCipher: CipherAES256,
+ }
+ return pk.EncryptWithConfig(passphrase, config)
+}
+
+func (pk *PrivateKey) serializePrivateKey(w io.Writer) (err error) {
+ switch priv := pk.PrivateKey.(type) {
+ case *rsa.PrivateKey:
+ err = serializeRSAPrivateKey(w, priv)
+ case *dsa.PrivateKey:
+ err = serializeDSAPrivateKey(w, priv)
+ case *elgamal.PrivateKey:
+ err = serializeElGamalPrivateKey(w, priv)
+ case *ecdsa.PrivateKey:
+ err = serializeECDSAPrivateKey(w, priv)
+ case *eddsa.PrivateKey:
+ err = serializeEdDSAPrivateKey(w, priv)
+ case *ecdh.PrivateKey:
+ err = serializeECDHPrivateKey(w, priv)
+ default:
+ err = errors.InvalidArgumentError("unknown private key type")
+ }
+ return
+}
+
+func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
+ switch pk.PublicKey.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
+ return pk.parseRSAPrivateKey(data)
+ case PubKeyAlgoDSA:
+ return pk.parseDSAPrivateKey(data)
+ case PubKeyAlgoElGamal:
+ return pk.parseElGamalPrivateKey(data)
+ case PubKeyAlgoECDSA:
+ return pk.parseECDSAPrivateKey(data)
+ case PubKeyAlgoECDH:
+ return pk.parseECDHPrivateKey(data)
+ case PubKeyAlgoEdDSA:
+ return pk.parseEdDSAPrivateKey(data)
+ }
+ panic("impossible")
+}
+
+func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
+ rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
+ rsaPriv := new(rsa.PrivateKey)
+ rsaPriv.PublicKey = *rsaPub
+
+ buf := bytes.NewBuffer(data)
+ d := new(encoding.MPI)
+ if _, err := d.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ p := new(encoding.MPI)
+ if _, err := p.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ q := new(encoding.MPI)
+ if _, err := q.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ rsaPriv.D = new(big.Int).SetBytes(d.Bytes())
+ rsaPriv.Primes = make([]*big.Int, 2)
+ rsaPriv.Primes[0] = new(big.Int).SetBytes(p.Bytes())
+ rsaPriv.Primes[1] = new(big.Int).SetBytes(q.Bytes())
+ if err := rsaPriv.Validate(); err != nil {
+ return errors.KeyInvalidError(err.Error())
+ }
+ rsaPriv.Precompute()
+ pk.PrivateKey = rsaPriv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
+ dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
+ dsaPriv := new(dsa.PrivateKey)
+ dsaPriv.PublicKey = *dsaPub
+
+ buf := bytes.NewBuffer(data)
+ x := new(encoding.MPI)
+ if _, err := x.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ dsaPriv.X = new(big.Int).SetBytes(x.Bytes())
+ if err := validateDSAParameters(dsaPriv); err != nil {
+ return err
+ }
+ pk.PrivateKey = dsaPriv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
+ pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
+ priv := new(elgamal.PrivateKey)
+ priv.PublicKey = *pub
+
+ buf := bytes.NewBuffer(data)
+ x := new(encoding.MPI)
+ if _, err := x.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ priv.X = new(big.Int).SetBytes(x.Bytes())
+ if err := validateElGamalParameters(priv); err != nil {
+ return err
+ }
+ pk.PrivateKey = priv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseECDSAPrivateKey(data []byte) (err error) {
+ ecdsaPub := pk.PublicKey.PublicKey.(*ecdsa.PublicKey)
+ ecdsaPriv := ecdsa.NewPrivateKey(*ecdsaPub)
+
+ buf := bytes.NewBuffer(data)
+ d := new(encoding.MPI)
+ if _, err := d.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ if err := ecdsaPriv.UnmarshalIntegerSecret(d.Bytes()); err != nil {
+ return err
+ }
+ if err := ecdsa.Validate(ecdsaPriv); err != nil {
+ return err
+ }
+ pk.PrivateKey = ecdsaPriv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseECDHPrivateKey(data []byte) (err error) {
+ ecdhPub := pk.PublicKey.PublicKey.(*ecdh.PublicKey)
+ ecdhPriv := ecdh.NewPrivateKey(*ecdhPub)
+
+ buf := bytes.NewBuffer(data)
+ d := new(encoding.MPI)
+ if _, err := d.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ if err := ecdhPriv.UnmarshalByteSecret(d.Bytes()); err != nil {
+ return err
+ }
+
+ if err := ecdh.Validate(ecdhPriv); err != nil {
+ return err
+ }
+
+ pk.PrivateKey = ecdhPriv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseEdDSAPrivateKey(data []byte) (err error) {
+ eddsaPub := pk.PublicKey.PublicKey.(*eddsa.PublicKey)
+ eddsaPriv := eddsa.NewPrivateKey(*eddsaPub)
+ eddsaPriv.PublicKey = *eddsaPub
+
+ buf := bytes.NewBuffer(data)
+ d := new(encoding.MPI)
+ if _, err := d.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ if err = eddsaPriv.UnmarshalByteSecret(d.Bytes()); err != nil {
+ return err
+ }
+
+ if err := eddsa.Validate(eddsaPriv); err != nil {
+ return err
+ }
+
+ pk.PrivateKey = eddsaPriv
+
+ return nil
+}
+
+func validateDSAParameters(priv *dsa.PrivateKey) error {
+ p := priv.P // group prime
+ q := priv.Q // subgroup order
+ g := priv.G // g has order q mod p
+ x := priv.X // secret
+ y := priv.Y // y == g**x mod p
+ one := big.NewInt(1)
+ // expect g, y >= 2 and g < p
+ if g.Cmp(one) <= 0 || y.Cmp(one) <= 0 || g.Cmp(p) > 0 {
+ return errors.KeyInvalidError("dsa: invalid group")
+ }
+ // expect p > q
+ if p.Cmp(q) <= 0 {
+ return errors.KeyInvalidError("dsa: invalid group prime")
+ }
+ // q should be large enough and divide p-1
+ pSub1 := new(big.Int).Sub(p, one)
+ if q.BitLen() < 150 || new(big.Int).Mod(pSub1, q).Cmp(big.NewInt(0)) != 0 {
+ return errors.KeyInvalidError("dsa: invalid order")
+ }
+ // confirm that g has order q mod p
+ if !q.ProbablyPrime(32) || new(big.Int).Exp(g, q, p).Cmp(one) != 0 {
+ return errors.KeyInvalidError("dsa: invalid order")
+ }
+ // check y
+ if new(big.Int).Exp(g, x, p).Cmp(y) != 0 {
+ return errors.KeyInvalidError("dsa: mismatching values")
+ }
+
+ return nil
+}
+
+func validateElGamalParameters(priv *elgamal.PrivateKey) error {
+ p := priv.P // group prime
+ g := priv.G // g has order p-1 mod p
+ x := priv.X // secret
+ y := priv.Y // y == g**x mod p
+ one := big.NewInt(1)
+ // Expect g, y >= 2 and g < p
+ if g.Cmp(one) <= 0 || y.Cmp(one) <= 0 || g.Cmp(p) > 0 {
+ return errors.KeyInvalidError("elgamal: invalid group")
+ }
+ if p.BitLen() < 1024 {
+ return errors.KeyInvalidError("elgamal: group order too small")
+ }
+ pSub1 := new(big.Int).Sub(p, one)
+ if new(big.Int).Exp(g, pSub1, p).Cmp(one) != 0 {
+ return errors.KeyInvalidError("elgamal: invalid group")
+ }
+ // Since p-1 is not prime, g might have a smaller order that divides p-1.
+ // We cannot confirm the exact order of g, but we make sure it is not too small.
+ gExpI := new(big.Int).Set(g)
+ i := 1
+ threshold := 2 << 17 // we want order > threshold
+ for i < threshold {
+ i++ // we check every order to make sure key validation is not easily bypassed by guessing y'
+ gExpI.Mod(new(big.Int).Mul(gExpI, g), p)
+ if gExpI.Cmp(one) == 0 {
+ return errors.KeyInvalidError("elgamal: order too small")
+ }
+ }
+ // Check y
+ if new(big.Int).Exp(g, x, p).Cmp(y) != 0 {
+ return errors.KeyInvalidError("elgamal: mismatching values")
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key_test_data.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key_test_data.go
new file mode 100644
index 00000000..029b8f1a
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key_test_data.go
@@ -0,0 +1,12 @@
+package packet
+
+// Generated with `gpg --export-secret-keys "Test Key 2"`
+const privKeyRSAHex = "9501fe044cc349a8010400b70ca0010e98c090008d45d1ee8f9113bd5861fd57b88bacb7c68658747663f1e1a3b5a98f32fda6472373c024b97359cd2efc88ff60f77751adfbf6af5e615e6a1408cfad8bf0cea30b0d5f53aa27ad59089ba9b15b7ebc2777a25d7b436144027e3bcd203909f147d0e332b240cf63d3395f5dfe0df0a6c04e8655af7eacdf0011010001fe0303024a252e7d475fd445607de39a265472aa74a9320ba2dac395faa687e9e0336aeb7e9a7397e511b5afd9dc84557c80ac0f3d4d7bfec5ae16f20d41c8c84a04552a33870b930420e230e179564f6d19bb153145e76c33ae993886c388832b0fa042ddda7f133924f3854481533e0ede31d51278c0519b29abc3bf53da673e13e3e1214b52413d179d7f66deee35cac8eacb060f78379d70ef4af8607e68131ff529439668fc39c9ce6dfef8a5ac234d234802cbfb749a26107db26406213ae5c06d4673253a3cbee1fcbae58d6ab77e38d6e2c0e7c6317c48e054edadb5a40d0d48acb44643d998139a8a66bb820be1f3f80185bc777d14b5954b60effe2448a036d565c6bc0b915fcea518acdd20ab07bc1529f561c58cd044f723109b93f6fd99f876ff891d64306b5d08f48bab59f38695e9109c4dec34013ba3153488ce070268381ba923ee1eb77125b36afcb4347ec3478c8f2735b06ef17351d872e577fa95d0c397c88c71b59629a36aec"
+
+// Generated by `gpg --export-secret-keys` followed by a manual extraction of
+// the ElGamal subkey from the packets.
+const privKeyElGamalHex = "9d0157044df9ee1a100400eb8e136a58ec39b582629cdadf830bc64e0a94ed8103ca8bb247b27b11b46d1d25297ef4bcc3071785ba0c0bedfe89eabc5287fcc0edf81ab5896c1c8e4b20d27d79813c7aede75320b33eaeeaa586edc00fd1036c10133e6ba0ff277245d0d59d04b2b3421b7244aca5f4a8d870c6f1c1fbff9e1c26699a860b9504f35ca1d700030503fd1ededd3b840795be6d9ccbe3c51ee42e2f39233c432b831ddd9c4e72b7025a819317e47bf94f9ee316d7273b05d5fcf2999c3a681f519b1234bbfa6d359b4752bd9c3f77d6b6456cde152464763414ca130f4e91d91041432f90620fec0e6d6b5116076c2985d5aeaae13be492b9b329efcaf7ee25120159a0a30cd976b42d7afe030302dae7eb80db744d4960c4df930d57e87fe81412eaace9f900e6c839817a614ddb75ba6603b9417c33ea7b6c93967dfa2bcff3fa3c74a5ce2c962db65b03aece14c96cbd0038fc"
+
+// pkcs1PrivKeyHex is a PKCS#1, RSA private key.
+// Generated by `openssl genrsa 1024 | openssl rsa -outform DER | xxd -p`
+const pkcs1PrivKeyHex = "3082025d02010002818100e98edfa1c3b35884a54d0b36a6a603b0290fa85e49e30fa23fc94fef9c6790bc4849928607aa48d809da326fb42a969d06ad756b98b9c1a90f5d4a2b6d0ac05953c97f4da3120164a21a679793ce181c906dc01d235cc085ddcdf6ea06c389b6ab8885dfd685959e693138856a68a7e5db263337ff82a088d583a897cf2d59e9020301000102818100b6d5c9eb70b02d5369b3ee5b520a14490b5bde8a317d36f7e4c74b7460141311d1e5067735f8f01d6f5908b2b96fbd881f7a1ab9a84d82753e39e19e2d36856be960d05ac9ef8e8782ea1b6d65aee28fdfe1d61451e8cff0adfe84322f12cf455028b581cf60eb9e0e140ba5d21aeba6c2634d7c65318b9a665fc01c3191ca21024100fa5e818da3705b0fa33278bb28d4b6f6050388af2d4b75ec9375dd91ccf2e7d7068086a8b82a8f6282e4fbbdb8a7f2622eb97295249d87acea7f5f816f54d347024100eecf9406d7dc49cdfb95ab1eff4064de84c7a30f64b2798936a0d2018ba9eb52e4b636f82e96c49cc63b80b675e91e40d1b2e4017d4b9adaf33ab3d9cf1c214f024100c173704ace742c082323066226a4655226819a85304c542b9dacbeacbf5d1881ee863485fcf6f59f3a604f9b42289282067447f2b13dfeed3eab7851fc81e0550240741fc41f3fc002b382eed8730e33c5d8de40256e4accee846667f536832f711ab1d4590e7db91a8a116ac5bff3be13d3f9243ff2e976662aa9b395d907f8e9c9024046a5696c9ef882363e06c9fa4e2f5b580906452befba03f4a99d0f873697ef1f851d2226ca7934b30b7c3e80cb634a67172bbbf4781735fe3e09263e2dd723e7"
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go
new file mode 100644
index 00000000..3402b8c1
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go
@@ -0,0 +1,806 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto"
+ "crypto/dsa"
+ "crypto/rsa"
+ "crypto/sha1"
+ "crypto/sha256"
+ _ "crypto/sha512"
+ "encoding/binary"
+ "fmt"
+ "hash"
+ "io"
+ "math/big"
+ "strconv"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdh"
+ "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
+ "github.com/ProtonMail/go-crypto/openpgp/eddsa"
+ "github.com/ProtonMail/go-crypto/openpgp/elgamal"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+)
+
+type kdfHashFunction byte
+type kdfAlgorithm byte
+
+// PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
+type PublicKey struct {
+ Version int
+ CreationTime time.Time
+ PubKeyAlgo PublicKeyAlgorithm
+ PublicKey interface{} // *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey or *eddsa.PublicKey
+ Fingerprint []byte
+ KeyId uint64
+ IsSubkey bool
+
+ // RFC 4880 fields
+ n, e, p, q, g, y encoding.Field
+
+ // RFC 6637 fields
+ // oid contains the OID byte sequence identifying the elliptic curve used
+ oid encoding.Field
+
+ // kdf stores key derivation function parameters
+ // used for ECDH encryption. See RFC 6637, Section 9.
+ kdf encoding.Field
+}
+
+// UpgradeToV5 updates the version of the key to v5, and updates all necessary
+// fields.
+func (pk *PublicKey) UpgradeToV5() {
+ pk.Version = 5
+ pk.setFingerprintAndKeyId()
+}
+
+// signingKey provides a convenient abstraction over signature verification
+// for v3 and v4 public keys.
+type signingKey interface {
+ SerializeForHash(io.Writer) error
+ SerializeSignaturePrefix(io.Writer)
+ serializeWithoutHeaders(io.Writer) error
+}
+
+// NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
+func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey {
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoRSA,
+ PublicKey: pub,
+ n: new(encoding.MPI).SetBig(pub.N),
+ e: new(encoding.MPI).SetBig(big.NewInt(int64(pub.E))),
+ }
+
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+// NewDSAPublicKey returns a PublicKey that wraps the given dsa.PublicKey.
+func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey {
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoDSA,
+ PublicKey: pub,
+ p: new(encoding.MPI).SetBig(pub.P),
+ q: new(encoding.MPI).SetBig(pub.Q),
+ g: new(encoding.MPI).SetBig(pub.G),
+ y: new(encoding.MPI).SetBig(pub.Y),
+ }
+
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+// NewElGamalPublicKey returns a PublicKey that wraps the given elgamal.PublicKey.
+func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *PublicKey {
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoElGamal,
+ PublicKey: pub,
+ p: new(encoding.MPI).SetBig(pub.P),
+ g: new(encoding.MPI).SetBig(pub.G),
+ y: new(encoding.MPI).SetBig(pub.Y),
+ }
+
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey {
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoECDSA,
+ PublicKey: pub,
+ p: encoding.NewMPI(pub.MarshalPoint()),
+ }
+
+ curveInfo := ecc.FindByCurve(pub.GetCurve())
+ if curveInfo == nil {
+ panic("unknown elliptic curve")
+ }
+ pk.oid = curveInfo.Oid
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+func NewECDHPublicKey(creationTime time.Time, pub *ecdh.PublicKey) *PublicKey {
+ var pk *PublicKey
+ var kdf = encoding.NewOID([]byte{0x1, pub.Hash.Id(), pub.Cipher.Id()})
+ pk = &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoECDH,
+ PublicKey: pub,
+ p: encoding.NewMPI(pub.MarshalPoint()),
+ kdf: kdf,
+ }
+
+ curveInfo := ecc.FindByCurve(pub.GetCurve())
+
+ if curveInfo == nil {
+ panic("unknown elliptic curve")
+ }
+
+ pk.oid = curveInfo.Oid
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+func NewEdDSAPublicKey(creationTime time.Time, pub *eddsa.PublicKey) *PublicKey {
+ curveInfo := ecc.FindByCurve(pub.GetCurve())
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoEdDSA,
+ PublicKey: pub,
+ oid: curveInfo.Oid,
+ // Native point format, see draft-koch-eddsa-for-openpgp-04, Appendix B
+ p: encoding.NewMPI(pub.MarshalPoint()),
+ }
+
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+func (pk *PublicKey) parse(r io.Reader) (err error) {
+ // RFC 4880, section 5.5.2
+ var buf [6]byte
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ if buf[0] != 4 && buf[0] != 5 {
+ return errors.UnsupportedError("public key version " + strconv.Itoa(int(buf[0])))
+ }
+
+ pk.Version = int(buf[0])
+ if pk.Version == 5 {
+ var n [4]byte
+ _, err = readFull(r, n[:])
+ if err != nil {
+ return
+ }
+ }
+ pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
+ pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+ err = pk.parseRSA(r)
+ case PubKeyAlgoDSA:
+ err = pk.parseDSA(r)
+ case PubKeyAlgoElGamal:
+ err = pk.parseElGamal(r)
+ case PubKeyAlgoECDSA:
+ err = pk.parseECDSA(r)
+ case PubKeyAlgoECDH:
+ err = pk.parseECDH(r)
+ case PubKeyAlgoEdDSA:
+ err = pk.parseEdDSA(r)
+ default:
+ err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
+ }
+ if err != nil {
+ return
+ }
+
+ pk.setFingerprintAndKeyId()
+ return
+}
+
+func (pk *PublicKey) setFingerprintAndKeyId() {
+ // RFC 4880, section 12.2
+ if pk.Version == 5 {
+ fingerprint := sha256.New()
+ pk.SerializeForHash(fingerprint)
+ pk.Fingerprint = make([]byte, 32)
+ copy(pk.Fingerprint, fingerprint.Sum(nil))
+ pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[:8])
+ } else {
+ fingerprint := sha1.New()
+ pk.SerializeForHash(fingerprint)
+ pk.Fingerprint = make([]byte, 20)
+ copy(pk.Fingerprint, fingerprint.Sum(nil))
+ pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
+ }
+}
+
+// parseRSA parses RSA public key material from the given Reader. See RFC 4880,
+// section 5.5.2.
+func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
+ pk.n = new(encoding.MPI)
+ if _, err = pk.n.ReadFrom(r); err != nil {
+ return
+ }
+ pk.e = new(encoding.MPI)
+ if _, err = pk.e.ReadFrom(r); err != nil {
+ return
+ }
+
+ if len(pk.e.Bytes()) > 3 {
+ err = errors.UnsupportedError("large public exponent")
+ return
+ }
+ rsa := &rsa.PublicKey{
+ N: new(big.Int).SetBytes(pk.n.Bytes()),
+ E: 0,
+ }
+ for i := 0; i < len(pk.e.Bytes()); i++ {
+ rsa.E <<= 8
+ rsa.E |= int(pk.e.Bytes()[i])
+ }
+ pk.PublicKey = rsa
+ return
+}
+
+// parseDSA parses DSA public key material from the given Reader. See RFC 4880,
+// section 5.5.2.
+func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+ pk.q = new(encoding.MPI)
+ if _, err = pk.q.ReadFrom(r); err != nil {
+ return
+ }
+ pk.g = new(encoding.MPI)
+ if _, err = pk.g.ReadFrom(r); err != nil {
+ return
+ }
+ pk.y = new(encoding.MPI)
+ if _, err = pk.y.ReadFrom(r); err != nil {
+ return
+ }
+
+ dsa := new(dsa.PublicKey)
+ dsa.P = new(big.Int).SetBytes(pk.p.Bytes())
+ dsa.Q = new(big.Int).SetBytes(pk.q.Bytes())
+ dsa.G = new(big.Int).SetBytes(pk.g.Bytes())
+ dsa.Y = new(big.Int).SetBytes(pk.y.Bytes())
+ pk.PublicKey = dsa
+ return
+}
+
+// parseElGamal parses ElGamal public key material from the given Reader. See
+// RFC 4880, section 5.5.2.
+func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+ pk.g = new(encoding.MPI)
+ if _, err = pk.g.ReadFrom(r); err != nil {
+ return
+ }
+ pk.y = new(encoding.MPI)
+ if _, err = pk.y.ReadFrom(r); err != nil {
+ return
+ }
+
+ elgamal := new(elgamal.PublicKey)
+ elgamal.P = new(big.Int).SetBytes(pk.p.Bytes())
+ elgamal.G = new(big.Int).SetBytes(pk.g.Bytes())
+ elgamal.Y = new(big.Int).SetBytes(pk.y.Bytes())
+ pk.PublicKey = elgamal
+ return
+}
+
+// parseECDSA parses ECDSA public key material from the given Reader. See
+// RFC 6637, Section 9.
+func (pk *PublicKey) parseECDSA(r io.Reader) (err error) {
+ pk.oid = new(encoding.OID)
+ if _, err = pk.oid.ReadFrom(r); err != nil {
+ return
+ }
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+
+ curveInfo := ecc.FindByOid(pk.oid)
+ if curveInfo == nil {
+ return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid))
+ }
+
+ c, ok := curveInfo.Curve.(ecc.ECDSACurve)
+ if !ok {
+ return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid))
+ }
+
+ ecdsaKey := ecdsa.NewPublicKey(c)
+ err = ecdsaKey.UnmarshalPoint(pk.p.Bytes())
+ pk.PublicKey = ecdsaKey
+
+ return
+}
+
+// parseECDH parses ECDH public key material from the given Reader. See
+// RFC 6637, Section 9.
+func (pk *PublicKey) parseECDH(r io.Reader) (err error) {
+ pk.oid = new(encoding.OID)
+ if _, err = pk.oid.ReadFrom(r); err != nil {
+ return
+ }
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+ pk.kdf = new(encoding.OID)
+ if _, err = pk.kdf.ReadFrom(r); err != nil {
+ return
+ }
+
+ curveInfo := ecc.FindByOid(pk.oid)
+
+ if curveInfo == nil {
+ return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid))
+ }
+
+ c, ok := curveInfo.Curve.(ecc.ECDHCurve)
+ if !ok {
+ return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid))
+ }
+
+ if kdfLen := len(pk.kdf.Bytes()); kdfLen < 3 {
+ return errors.UnsupportedError("unsupported ECDH KDF length: " + strconv.Itoa(kdfLen))
+ }
+ if reserved := pk.kdf.Bytes()[0]; reserved != 0x01 {
+ return errors.UnsupportedError("unsupported KDF reserved field: " + strconv.Itoa(int(reserved)))
+ }
+ kdfHash, ok := algorithm.HashById[pk.kdf.Bytes()[1]]
+ if !ok {
+ return errors.UnsupportedError("unsupported ECDH KDF hash: " + strconv.Itoa(int(pk.kdf.Bytes()[1])))
+ }
+ kdfCipher, ok := algorithm.CipherById[pk.kdf.Bytes()[2]]
+ if !ok {
+ return errors.UnsupportedError("unsupported ECDH KDF cipher: " + strconv.Itoa(int(pk.kdf.Bytes()[2])))
+ }
+
+ ecdhKey := ecdh.NewPublicKey(c, kdfHash, kdfCipher)
+ err = ecdhKey.UnmarshalPoint(pk.p.Bytes())
+ pk.PublicKey = ecdhKey
+
+ return
+}
+
+func (pk *PublicKey) parseEdDSA(r io.Reader) (err error) {
+ pk.oid = new(encoding.OID)
+ if _, err = pk.oid.ReadFrom(r); err != nil {
+ return
+ }
+ curveInfo := ecc.FindByOid(pk.oid)
+ if curveInfo == nil {
+ return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid))
+ }
+
+ c, ok := curveInfo.Curve.(ecc.EdDSACurve)
+ if !ok {
+ return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid))
+ }
+
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+
+ if len(pk.p.Bytes()) == 0 {
+ return errors.StructuralError("empty EdDSA public key")
+ }
+
+ pub := eddsa.NewPublicKey(c)
+
+ switch flag := pk.p.Bytes()[0]; flag {
+ case 0x04:
+ // TODO: see _grcy_ecc_eddsa_ensure_compact in grcypt
+ return errors.UnsupportedError("unsupported EdDSA compression: " + strconv.Itoa(int(flag)))
+ case 0x40:
+ err = pub.UnmarshalPoint(pk.p.Bytes())
+ default:
+ return errors.UnsupportedError("unsupported EdDSA compression: " + strconv.Itoa(int(flag)))
+ }
+
+ pk.PublicKey = pub
+ return
+}
+
+// SerializeForHash serializes the PublicKey to w with the special packet
+// header format needed for hashing.
+func (pk *PublicKey) SerializeForHash(w io.Writer) error {
+ pk.SerializeSignaturePrefix(w)
+ return pk.serializeWithoutHeaders(w)
+}
+
+// SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
+// The prefix is used when calculating a signature over this public key. See
+// RFC 4880, section 5.2.4.
+func (pk *PublicKey) SerializeSignaturePrefix(w io.Writer) {
+ var pLength = pk.algorithmSpecificByteCount()
+ if pk.Version == 5 {
+ pLength += 10 // version, timestamp (4), algorithm, key octet count (4).
+ w.Write([]byte{
+ 0x9A,
+ byte(pLength >> 24),
+ byte(pLength >> 16),
+ byte(pLength >> 8),
+ byte(pLength),
+ })
+ return
+ }
+ pLength += 6
+ w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
+}
+
+func (pk *PublicKey) Serialize(w io.Writer) (err error) {
+ length := 6 // 6 byte header
+ length += pk.algorithmSpecificByteCount()
+ if pk.Version == 5 {
+ length += 4 // octet key count
+ }
+ packetType := packetTypePublicKey
+ if pk.IsSubkey {
+ packetType = packetTypePublicSubkey
+ }
+ err = serializeHeader(w, packetType, length)
+ if err != nil {
+ return
+ }
+ return pk.serializeWithoutHeaders(w)
+}
+
+func (pk *PublicKey) algorithmSpecificByteCount() int {
+ length := 0
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+ length += int(pk.n.EncodedLength())
+ length += int(pk.e.EncodedLength())
+ case PubKeyAlgoDSA:
+ length += int(pk.p.EncodedLength())
+ length += int(pk.q.EncodedLength())
+ length += int(pk.g.EncodedLength())
+ length += int(pk.y.EncodedLength())
+ case PubKeyAlgoElGamal:
+ length += int(pk.p.EncodedLength())
+ length += int(pk.g.EncodedLength())
+ length += int(pk.y.EncodedLength())
+ case PubKeyAlgoECDSA:
+ length += int(pk.oid.EncodedLength())
+ length += int(pk.p.EncodedLength())
+ case PubKeyAlgoECDH:
+ length += int(pk.oid.EncodedLength())
+ length += int(pk.p.EncodedLength())
+ length += int(pk.kdf.EncodedLength())
+ case PubKeyAlgoEdDSA:
+ length += int(pk.oid.EncodedLength())
+ length += int(pk.p.EncodedLength())
+ default:
+ panic("unknown public key algorithm")
+ }
+ return length
+}
+
+// serializeWithoutHeaders marshals the PublicKey to w in the form of an
+// OpenPGP public key packet, not including the packet header.
+func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
+ t := uint32(pk.CreationTime.Unix())
+ if _, err = w.Write([]byte{
+ byte(pk.Version),
+ byte(t >> 24), byte(t >> 16), byte(t >> 8), byte(t),
+ byte(pk.PubKeyAlgo),
+ }); err != nil {
+ return
+ }
+
+ if pk.Version == 5 {
+ n := pk.algorithmSpecificByteCount()
+ if _, err = w.Write([]byte{
+ byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n),
+ }); err != nil {
+ return
+ }
+ }
+
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+ if _, err = w.Write(pk.n.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.e.EncodedBytes())
+ return
+ case PubKeyAlgoDSA:
+ if _, err = w.Write(pk.p.EncodedBytes()); err != nil {
+ return
+ }
+ if _, err = w.Write(pk.q.EncodedBytes()); err != nil {
+ return
+ }
+ if _, err = w.Write(pk.g.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.y.EncodedBytes())
+ return
+ case PubKeyAlgoElGamal:
+ if _, err = w.Write(pk.p.EncodedBytes()); err != nil {
+ return
+ }
+ if _, err = w.Write(pk.g.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.y.EncodedBytes())
+ return
+ case PubKeyAlgoECDSA:
+ if _, err = w.Write(pk.oid.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.p.EncodedBytes())
+ return
+ case PubKeyAlgoECDH:
+ if _, err = w.Write(pk.oid.EncodedBytes()); err != nil {
+ return
+ }
+ if _, err = w.Write(pk.p.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.kdf.EncodedBytes())
+ return
+ case PubKeyAlgoEdDSA:
+ if _, err = w.Write(pk.oid.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.p.EncodedBytes())
+ return
+ }
+ return errors.InvalidArgumentError("bad public-key algorithm")
+}
+
+// CanSign returns true iff this public key can generate signatures
+func (pk *PublicKey) CanSign() bool {
+ return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal && pk.PubKeyAlgo != PubKeyAlgoECDH
+}
+
+// VerifySignature returns nil iff sig is a valid signature, made by this
+// public key, of the data hashed into signed. signed is mutated by this call.
+func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
+ if !pk.CanSign() {
+ return errors.InvalidArgumentError("public key cannot generate signatures")
+ }
+ if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
+ sig.AddMetadataToHashSuffix()
+ }
+ signed.Write(sig.HashSuffix)
+ hashBytes := signed.Sum(nil)
+ if sig.Version == 5 && (hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1]) {
+ return errors.SignatureError("hash tag doesn't match")
+ }
+
+ if pk.PubKeyAlgo != sig.PubKeyAlgo {
+ return errors.InvalidArgumentError("public key and signature use different algorithms")
+ }
+
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
+ err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.Bytes()))
+ if err != nil {
+ return errors.SignatureError("RSA verification failure")
+ }
+ return nil
+ case PubKeyAlgoDSA:
+ dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
+ // Need to truncate hashBytes to match FIPS 186-3 section 4.6.
+ subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
+ if len(hashBytes) > subgroupSize {
+ hashBytes = hashBytes[:subgroupSize]
+ }
+ if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.Bytes()), new(big.Int).SetBytes(sig.DSASigS.Bytes())) {
+ return errors.SignatureError("DSA verification failure")
+ }
+ return nil
+ case PubKeyAlgoECDSA:
+ ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
+ if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.Bytes()), new(big.Int).SetBytes(sig.ECDSASigS.Bytes())) {
+ return errors.SignatureError("ECDSA verification failure")
+ }
+ return nil
+ case PubKeyAlgoEdDSA:
+ eddsaPublicKey := pk.PublicKey.(*eddsa.PublicKey)
+ if !eddsa.Verify(eddsaPublicKey, hashBytes, sig.EdDSASigR.Bytes(), sig.EdDSASigS.Bytes()) {
+ return errors.SignatureError("EdDSA verification failure")
+ }
+ return nil
+ default:
+ return errors.SignatureError("Unsupported public key algorithm used in signature")
+ }
+}
+
+// keySignatureHash returns a Hash of the message that needs to be signed for
+// pk to assert a subkey relationship to signed.
+func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
+ if !hashFunc.Available() {
+ return nil, errors.UnsupportedError("hash function")
+ }
+ h = hashFunc.New()
+
+ // RFC 4880, section 5.2.4
+ err = pk.SerializeForHash(h)
+ if err != nil {
+ return nil, err
+ }
+
+ err = signed.SerializeForHash(h)
+ return
+}
+
+// VerifyKeySignature returns nil iff sig is a valid signature, made by this
+// public key, of signed.
+func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error {
+ h, err := keySignatureHash(pk, signed, sig.Hash)
+ if err != nil {
+ return err
+ }
+ if err = pk.VerifySignature(h, sig); err != nil {
+ return err
+ }
+
+ if sig.FlagSign {
+ // Signing subkeys must be cross-signed. See
+ // https://www.gnupg.org/faq/subkey-cross-certify.html.
+ if sig.EmbeddedSignature == nil {
+ return errors.StructuralError("signing subkey is missing cross-signature")
+ }
+ // Verify the cross-signature. This is calculated over the same
+ // data as the main signature, so we cannot just recursively
+ // call signed.VerifyKeySignature(...)
+ if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil {
+ return errors.StructuralError("error while hashing for cross-signature: " + err.Error())
+ }
+ if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil {
+ return errors.StructuralError("error while verifying cross-signature: " + err.Error())
+ }
+ }
+
+ return nil
+}
+
+func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
+ if !hashFunc.Available() {
+ return nil, errors.UnsupportedError("hash function")
+ }
+ h = hashFunc.New()
+
+ // RFC 4880, section 5.2.4
+ err = pk.SerializeForHash(h)
+
+ return
+}
+
+// VerifyRevocationSignature returns nil iff sig is a valid signature, made by this
+// public key.
+func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) {
+ h, err := keyRevocationHash(pk, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return pk.VerifySignature(h, sig)
+}
+
+// VerifySubkeyRevocationSignature returns nil iff sig is a valid subkey revocation signature,
+// made by this public key, of signed.
+func (pk *PublicKey) VerifySubkeyRevocationSignature(sig *Signature, signed *PublicKey) (err error) {
+ h, err := keySignatureHash(pk, signed, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return pk.VerifySignature(h, sig)
+}
+
+// userIdSignatureHash returns a Hash of the message that needs to be signed
+// to assert that pk is a valid key for id.
+func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
+ if !hashFunc.Available() {
+ return nil, errors.UnsupportedError("hash function")
+ }
+ h = hashFunc.New()
+
+ // RFC 4880, section 5.2.4
+ pk.SerializeSignaturePrefix(h)
+ pk.serializeWithoutHeaders(h)
+
+ var buf [5]byte
+ buf[0] = 0xb4
+ buf[1] = byte(len(id) >> 24)
+ buf[2] = byte(len(id) >> 16)
+ buf[3] = byte(len(id) >> 8)
+ buf[4] = byte(len(id))
+ h.Write(buf[:])
+ h.Write([]byte(id))
+
+ return
+}
+
+// VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
+// public key, that id is the identity of pub.
+func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
+ h, err := userIdSignatureHash(id, pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return pk.VerifySignature(h, sig)
+}
+
+// KeyIdString returns the public key's fingerprint in capital hex
+// (e.g. "6C7EE1B8621CC013").
+func (pk *PublicKey) KeyIdString() string {
+ return fmt.Sprintf("%X", pk.Fingerprint[12:20])
+}
+
+// KeyIdShortString returns the short form of public key's fingerprint
+// in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
+func (pk *PublicKey) KeyIdShortString() string {
+ return fmt.Sprintf("%X", pk.Fingerprint[16:20])
+}
+
+// BitLength returns the bit length for the given public key.
+func (pk *PublicKey) BitLength() (bitLength uint16, err error) {
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+ bitLength = pk.n.BitLength()
+ case PubKeyAlgoDSA:
+ bitLength = pk.p.BitLength()
+ case PubKeyAlgoElGamal:
+ bitLength = pk.p.BitLength()
+ case PubKeyAlgoECDSA:
+ bitLength = pk.p.BitLength()
+ case PubKeyAlgoECDH:
+ bitLength = pk.p.BitLength()
+ case PubKeyAlgoEdDSA:
+ bitLength = pk.p.BitLength()
+ default:
+ err = errors.InvalidArgumentError("bad public-key algorithm")
+ }
+ return
+}
+
+// KeyExpired returns whether sig is a self-signature of a key that has
+// expired or is created in the future.
+func (pk *PublicKey) KeyExpired(sig *Signature, currentTime time.Time) bool {
+ if pk.CreationTime.After(currentTime) {
+ return true
+ }
+ if sig.KeyLifetimeSecs == nil || *sig.KeyLifetimeSecs == 0 {
+ return false
+ }
+ expiry := pk.CreationTime.Add(time.Duration(*sig.KeyLifetimeSecs) * time.Second)
+ return currentTime.After(expiry)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key_test_data.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key_test_data.go
new file mode 100644
index 00000000..b255f1f6
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key_test_data.go
@@ -0,0 +1,24 @@
+package packet
+
+const rsaFingerprintHex = "5fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb"
+
+const rsaPkDataHex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001"
+
+const dsaFingerprintHex = "eece4c094db002103714c63c8e8fbe54062f19ed"
+
+const dsaPkDataHex = "9901a2044d432f89110400cd581334f0d7a1e1bdc8b9d6d8c0baf68793632735d2bb0903224cbaa1dfbf35a60ee7a13b92643421e1eb41aa8d79bea19a115a677f6b8ba3c7818ce53a6c2a24a1608bd8b8d6e55c5090cbde09dd26e356267465ae25e69ec8bdd57c7bbb2623e4d73336f73a0a9098f7f16da2e25252130fd694c0e8070c55a812a423ae7f00a0ebf50e70c2f19c3520a551bd4b08d30f23530d3d03ff7d0bf4a53a64a09dc5e6e6e35854b7d70c882b0c60293401958b1bd9e40abec3ea05ba87cf64899299d4bd6aa7f459c201d3fbbd6c82004bdc5e8a9eb8082d12054cc90fa9d4ec251a843236a588bf49552441817436c4f43326966fe85447d4e6d0acf8fa1ef0f014730770603ad7634c3088dc52501c237328417c31c89ed70400b2f1a98b0bf42f11fefc430704bebbaa41d9f355600c3facee1e490f64208e0e094ea55e3a598a219a58500bf78ac677b670a14f4e47e9cf8eab4f368cc1ddcaa18cc59309d4cc62dd4f680e73e6cc3e1ce87a84d0925efbcb26c575c093fc42eecf45135fabf6403a25c2016e1774c0484e440a18319072c617cc97ac0a3bb0"
+
+const ecdsaFingerprintHex = "9892270b38b8980b05c8d56d43fe956c542ca00b"
+
+const ecdsaPkDataHex = "9893045071c29413052b8104002304230401f4867769cedfa52c325018896245443968e52e51d0c2df8d939949cb5b330f2921711fbee1c9b9dddb95d15cb0255e99badeddda7cc23d9ddcaacbc290969b9f24019375d61c2e4e3b36953a28d8b2bc95f78c3f1d592fb24499be348656a7b17e3963187b4361afe497bc5f9f81213f04069f8e1fb9e6a6290ae295ca1a92b894396cb4"
+
+const ecdhFingerprintHex = "722354df2475a42164d1d49faa8b938f9a201946"
+
+const ecdhPkDataHex = "b90073044d53059212052b810400220303042faa84024a20b6735c4897efa5bfb41bf85b7eefeab5ca0cb9ffc8ea04a46acb25534a577694f9e25340a4ab5223a9dd1eda530c8aa2e6718db10d7e672558c7736fe09369ea5739a2a3554bf16d41faa50562f11c6d39bbd5dffb6b9a9ec91803010909"
+
+const eddsaFingerprintHex = "b2d5e5ec0e6deca6bc8eeeb00907e75e1dd99ad8"
+
+const eddsaPkDataHex = "98330456e2132b16092b06010401da470f01010740bbda39266affa511a8c2d02edf690fb784b0499c4406185811a163539ef11dc1b41d74657374696e67203c74657374696e674074657374696e672e636f6d3e8879041316080021050256e2132b021b03050b09080702061508090a0b020416020301021e01021780000a09100907e75e1dd99ad86d0c00fe39d2008359352782bc9b61ac382584cd8eff3f57a18c2287e3afeeb05d1f04ba00fe2d0bc1ddf3ff8adb9afa3e7d9287244b4ec567f3db4d60b74a9b5465ed528203"
+
+// Source: https://sites.google.com/site/brainhub/pgpecckeys#TOC-ECC-NIST-P-384-key
+const ecc384PubHex = `99006f044d53059213052b81040022030304f6b8c5aced5b84ef9f4a209db2e4a9dfb70d28cb8c10ecd57674a9fa5a67389942b62d5e51367df4c7bfd3f8e500feecf07ed265a621a8ebbbe53e947ec78c677eba143bd1533c2b350e1c29f82313e1e1108eba063be1e64b10e6950e799c2db42465635f6473615f64685f333834203c6f70656e70677040627261696e6875622e6f72673e8900cb04101309005305024d530592301480000000002000077072656665727265642d656d61696c2d656e636f64696e67407067702e636f6d7067706d696d65040b090807021901051b03000000021602051e010000000415090a08000a0910098033880f54719fca2b0180aa37350968bd5f115afd8ce7bc7b103822152dbff06d0afcda835329510905b98cb469ba208faab87c7412b799e7b633017f58364ea480e8a1a3f253a0c5f22c446e8be9a9fce6210136ee30811abbd49139de28b5bdf8dc36d06ae748579e9ff503b90073044d53059212052b810400220303042faa84024a20b6735c4897efa5bfb41bf85b7eefeab5ca0cb9ffc8ea04a46acb25534a577694f9e25340a4ab5223a9dd1eda530c8aa2e6718db10d7e672558c7736fe09369ea5739a2a3554bf16d41faa50562f11c6d39bbd5dffb6b9a9ec9180301090989008404181309000c05024d530592051b0c000000000a0910098033880f54719f80970180eee7a6d8fcee41ee4f9289df17f9bcf9d955dca25c583b94336f3a2b2d4986dc5cf417b8d2dc86f741a9e1a6d236c0e3017d1c76575458a0cfb93ae8a2b274fcc65ceecd7a91eec83656ba13219969f06945b48c56bd04152c3a0553c5f2f4bd1267`
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go
new file mode 100644
index 00000000..10215fe5
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go
@@ -0,0 +1,86 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// Reader reads packets from an io.Reader and allows packets to be 'unread' so
+// that they result from the next call to Next.
+type Reader struct {
+ q []Packet
+ readers []io.Reader
+}
+
+// New io.Readers are pushed when a compressed or encrypted packet is processed
+// and recursively treated as a new source of packets. However, a carefully
+// crafted packet can trigger an infinite recursive sequence of packets. See
+// http://mumble.net/~campbell/misc/pgp-quine
+// https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4402
+// This constant limits the number of recursive packets that may be pushed.
+const maxReaders = 32
+
+// Next returns the most recently unread Packet, or reads another packet from
+// the top-most io.Reader. Unknown packet types are skipped.
+func (r *Reader) Next() (p Packet, err error) {
+ if len(r.q) > 0 {
+ p = r.q[len(r.q)-1]
+ r.q = r.q[:len(r.q)-1]
+ return
+ }
+
+ for len(r.readers) > 0 {
+ p, err = Read(r.readers[len(r.readers)-1])
+ if err == nil {
+ return
+ }
+ if err == io.EOF {
+ r.readers = r.readers[:len(r.readers)-1]
+ continue
+ }
+ // TODO: Add strict mode that rejects unknown packets, instead of ignoring them.
+ if _, ok := err.(errors.UnknownPacketTypeError); ok {
+ continue
+ }
+ if _, ok := err.(errors.UnsupportedError); ok {
+ switch p.(type) {
+ case *SymmetricallyEncrypted, *AEADEncrypted, *Compressed, *LiteralData:
+ return nil, err
+ }
+ continue
+ }
+ return nil, err
+ }
+
+ return nil, io.EOF
+}
+
+// Push causes the Reader to start reading from a new io.Reader. When an EOF
+// error is seen from the new io.Reader, it is popped and the Reader continues
+// to read from the next most recent io.Reader. Push returns a StructuralError
+// if pushing the reader would exceed the maximum recursion level, otherwise it
+// returns nil.
+func (r *Reader) Push(reader io.Reader) (err error) {
+ if len(r.readers) >= maxReaders {
+ return errors.StructuralError("too many layers of packets")
+ }
+ r.readers = append(r.readers, reader)
+ return nil
+}
+
+// Unread causes the given Packet to be returned from the next call to Next.
+func (r *Reader) Unread(p Packet) {
+ r.q = append(r.q, p)
+}
+
+func NewReader(r io.Reader) *Reader {
+ return &Reader{
+ q: nil,
+ readers: []io.Reader{r},
+ }
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go
new file mode 100644
index 00000000..80d0bb98
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go
@@ -0,0 +1,1084 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/dsa"
+ "encoding/binary"
+ "hash"
+ "io"
+ "strconv"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
+ "github.com/ProtonMail/go-crypto/openpgp/eddsa"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+)
+
+const (
+ // See RFC 4880, section 5.2.3.21 for details.
+ KeyFlagCertify = 1 << iota
+ KeyFlagSign
+ KeyFlagEncryptCommunications
+ KeyFlagEncryptStorage
+ KeyFlagSplitKey
+ KeyFlagAuthenticate
+ _
+ KeyFlagGroupKey
+)
+
+// Signature represents a signature. See RFC 4880, section 5.2.
+type Signature struct {
+ Version int
+ SigType SignatureType
+ PubKeyAlgo PublicKeyAlgorithm
+ Hash crypto.Hash
+
+ // HashSuffix is extra data that is hashed in after the signed data.
+ HashSuffix []byte
+ // HashTag contains the first two bytes of the hash for fast rejection
+ // of bad signed data.
+ HashTag [2]byte
+
+ // Metadata includes format, filename and time, and is protected by v5
+ // signatures of type 0x00 or 0x01. This metadata is included into the hash
+ // computation; if nil, six 0x00 bytes are used instead. See section 5.2.4.
+ Metadata *LiteralData
+
+ CreationTime time.Time
+
+ RSASignature encoding.Field
+ DSASigR, DSASigS encoding.Field
+ ECDSASigR, ECDSASigS encoding.Field
+ EdDSASigR, EdDSASigS encoding.Field
+
+ // rawSubpackets contains the unparsed subpackets, in order.
+ rawSubpackets []outputSubpacket
+
+ // The following are optional so are nil when not included in the
+ // signature.
+
+ SigLifetimeSecs, KeyLifetimeSecs *uint32
+ PreferredSymmetric, PreferredHash, PreferredCompression []uint8
+ PreferredCipherSuites [][2]uint8
+ IssuerKeyId *uint64
+ IssuerFingerprint []byte
+ SignerUserId *string
+ IsPrimaryId *bool
+ Notations []*Notation
+
+ // TrustLevel and TrustAmount can be set by the signer to assert that
+ // the key is not only valid but also trustworthy at the specified
+ // level.
+ // See RFC 4880, section 5.2.3.13 for details.
+ TrustLevel TrustLevel
+ TrustAmount TrustAmount
+
+ // TrustRegularExpression can be used in conjunction with trust Signature
+ // packets to limit the scope of the trust that is extended.
+ // See RFC 4880, section 5.2.3.14 for details.
+ TrustRegularExpression *string
+
+ // PolicyURI can be set to the URI of a document that describes the
+ // policy under which the signature was issued. See RFC 4880, section
+ // 5.2.3.20 for details.
+ PolicyURI string
+
+ // FlagsValid is set if any flags were given. See RFC 4880, section
+ // 5.2.3.21 for details.
+ FlagsValid bool
+ FlagCertify, FlagSign, FlagEncryptCommunications, FlagEncryptStorage, FlagSplitKey, FlagAuthenticate, FlagGroupKey bool
+
+ // RevocationReason is set if this signature has been revoked.
+ // See RFC 4880, section 5.2.3.23 for details.
+ RevocationReason *ReasonForRevocation
+ RevocationReasonText string
+
+ // In a self-signature, these flags are set there is a features subpacket
+ // indicating that the issuer implementation supports these features
+ // see https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#features-subpacket
+ SEIPDv1, SEIPDv2 bool
+
+ // EmbeddedSignature, if non-nil, is a signature of the parent key, by
+ // this key. This prevents an attacker from claiming another's signing
+ // subkey as their own.
+ EmbeddedSignature *Signature
+
+ outSubpackets []outputSubpacket
+}
+
+func (sig *Signature) parse(r io.Reader) (err error) {
+ // RFC 4880, section 5.2.3
+ var buf [5]byte
+ _, err = readFull(r, buf[:1])
+ if err != nil {
+ return
+ }
+ if buf[0] != 4 && buf[0] != 5 {
+ err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
+ return
+ }
+ sig.Version = int(buf[0])
+ _, err = readFull(r, buf[:5])
+ if err != nil {
+ return
+ }
+ sig.SigType = SignatureType(buf[0])
+ sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1])
+ switch sig.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA:
+ default:
+ err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
+ return
+ }
+
+ var ok bool
+
+ if sig.Version < 5 {
+ sig.Hash, ok = algorithm.HashIdToHashWithSha1(buf[2])
+ } else {
+ sig.Hash, ok = algorithm.HashIdToHash(buf[2])
+ }
+
+ if !ok {
+ return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
+ }
+
+ hashedSubpacketsLength := int(buf[3])<<8 | int(buf[4])
+ hashedSubpackets := make([]byte, hashedSubpacketsLength)
+ _, err = readFull(r, hashedSubpackets)
+ if err != nil {
+ return
+ }
+ err = sig.buildHashSuffix(hashedSubpackets)
+ if err != nil {
+ return
+ }
+
+ err = parseSignatureSubpackets(sig, hashedSubpackets, true)
+ if err != nil {
+ return
+ }
+
+ _, err = readFull(r, buf[:2])
+ if err != nil {
+ return
+ }
+ unhashedSubpacketsLength := int(buf[0])<<8 | int(buf[1])
+ unhashedSubpackets := make([]byte, unhashedSubpacketsLength)
+ _, err = readFull(r, unhashedSubpackets)
+ if err != nil {
+ return
+ }
+ err = parseSignatureSubpackets(sig, unhashedSubpackets, false)
+ if err != nil {
+ return
+ }
+
+ _, err = readFull(r, sig.HashTag[:2])
+ if err != nil {
+ return
+ }
+
+ switch sig.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ sig.RSASignature = new(encoding.MPI)
+ _, err = sig.RSASignature.ReadFrom(r)
+ case PubKeyAlgoDSA:
+ sig.DSASigR = new(encoding.MPI)
+ if _, err = sig.DSASigR.ReadFrom(r); err != nil {
+ return
+ }
+
+ sig.DSASigS = new(encoding.MPI)
+ _, err = sig.DSASigS.ReadFrom(r)
+ case PubKeyAlgoECDSA:
+ sig.ECDSASigR = new(encoding.MPI)
+ if _, err = sig.ECDSASigR.ReadFrom(r); err != nil {
+ return
+ }
+
+ sig.ECDSASigS = new(encoding.MPI)
+ _, err = sig.ECDSASigS.ReadFrom(r)
+ case PubKeyAlgoEdDSA:
+ sig.EdDSASigR = new(encoding.MPI)
+ if _, err = sig.EdDSASigR.ReadFrom(r); err != nil {
+ return
+ }
+
+ sig.EdDSASigS = new(encoding.MPI)
+ if _, err = sig.EdDSASigS.ReadFrom(r); err != nil {
+ return
+ }
+ default:
+ panic("unreachable")
+ }
+ return
+}
+
+// parseSignatureSubpackets parses subpackets of the main signature packet. See
+// RFC 4880, section 5.2.3.1.
+func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool) (err error) {
+ for len(subpackets) > 0 {
+ subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
+ if err != nil {
+ return
+ }
+ }
+
+ if sig.CreationTime.IsZero() {
+ err = errors.StructuralError("no creation time in signature")
+ }
+
+ return
+}
+
+type signatureSubpacketType uint8
+
+const (
+ creationTimeSubpacket signatureSubpacketType = 2
+ signatureExpirationSubpacket signatureSubpacketType = 3
+ trustSubpacket signatureSubpacketType = 5
+ regularExpressionSubpacket signatureSubpacketType = 6
+ keyExpirationSubpacket signatureSubpacketType = 9
+ prefSymmetricAlgosSubpacket signatureSubpacketType = 11
+ issuerSubpacket signatureSubpacketType = 16
+ notationDataSubpacket signatureSubpacketType = 20
+ prefHashAlgosSubpacket signatureSubpacketType = 21
+ prefCompressionSubpacket signatureSubpacketType = 22
+ primaryUserIdSubpacket signatureSubpacketType = 25
+ policyUriSubpacket signatureSubpacketType = 26
+ keyFlagsSubpacket signatureSubpacketType = 27
+ signerUserIdSubpacket signatureSubpacketType = 28
+ reasonForRevocationSubpacket signatureSubpacketType = 29
+ featuresSubpacket signatureSubpacketType = 30
+ embeddedSignatureSubpacket signatureSubpacketType = 32
+ issuerFingerprintSubpacket signatureSubpacketType = 33
+ prefCipherSuitesSubpacket signatureSubpacketType = 39
+)
+
+// parseSignatureSubpacket parses a single subpacket. len(subpacket) is >= 1.
+func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (rest []byte, err error) {
+ // RFC 4880, section 5.2.3.1
+ var (
+ length uint32
+ packetType signatureSubpacketType
+ isCritical bool
+ )
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("zero length signature subpacket")
+ return
+ }
+ switch {
+ case subpacket[0] < 192:
+ length = uint32(subpacket[0])
+ subpacket = subpacket[1:]
+ case subpacket[0] < 255:
+ if len(subpacket) < 2 {
+ goto Truncated
+ }
+ length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192
+ subpacket = subpacket[2:]
+ default:
+ if len(subpacket) < 5 {
+ goto Truncated
+ }
+ length = uint32(subpacket[1])<<24 |
+ uint32(subpacket[2])<<16 |
+ uint32(subpacket[3])<<8 |
+ uint32(subpacket[4])
+ subpacket = subpacket[5:]
+ }
+ if length > uint32(len(subpacket)) {
+ goto Truncated
+ }
+ rest = subpacket[length:]
+ subpacket = subpacket[:length]
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("zero length signature subpacket")
+ return
+ }
+ packetType = signatureSubpacketType(subpacket[0] & 0x7f)
+ isCritical = subpacket[0]&0x80 == 0x80
+ subpacket = subpacket[1:]
+ sig.rawSubpackets = append(sig.rawSubpackets, outputSubpacket{isHashed, packetType, isCritical, subpacket})
+ if !isHashed &&
+ packetType != issuerSubpacket &&
+ packetType != issuerFingerprintSubpacket &&
+ packetType != embeddedSignatureSubpacket {
+ return
+ }
+ switch packetType {
+ case creationTimeSubpacket:
+ if len(subpacket) != 4 {
+ err = errors.StructuralError("signature creation time not four bytes")
+ return
+ }
+ t := binary.BigEndian.Uint32(subpacket)
+ sig.CreationTime = time.Unix(int64(t), 0)
+ case signatureExpirationSubpacket:
+ // Signature expiration time, section 5.2.3.10
+ if len(subpacket) != 4 {
+ err = errors.StructuralError("expiration subpacket with bad length")
+ return
+ }
+ sig.SigLifetimeSecs = new(uint32)
+ *sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
+ case trustSubpacket:
+ if len(subpacket) != 2 {
+ err = errors.StructuralError("trust subpacket with bad length")
+ return
+ }
+ // Trust level and amount, section 5.2.3.13
+ sig.TrustLevel = TrustLevel(subpacket[0])
+ sig.TrustAmount = TrustAmount(subpacket[1])
+ case regularExpressionSubpacket:
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("regexp subpacket with bad length")
+ return
+ }
+ // Trust regular expression, section 5.2.3.14
+ // RFC specifies the string should be null-terminated; remove a null byte from the end
+ if subpacket[len(subpacket)-1] != 0x00 {
+ err = errors.StructuralError("expected regular expression to be null-terminated")
+ return
+ }
+ trustRegularExpression := string(subpacket[:len(subpacket)-1])
+ sig.TrustRegularExpression = &trustRegularExpression
+ case keyExpirationSubpacket:
+ // Key expiration time, section 5.2.3.6
+ if len(subpacket) != 4 {
+ err = errors.StructuralError("key expiration subpacket with bad length")
+ return
+ }
+ sig.KeyLifetimeSecs = new(uint32)
+ *sig.KeyLifetimeSecs = binary.BigEndian.Uint32(subpacket)
+ case prefSymmetricAlgosSubpacket:
+ // Preferred symmetric algorithms, section 5.2.3.7
+ sig.PreferredSymmetric = make([]byte, len(subpacket))
+ copy(sig.PreferredSymmetric, subpacket)
+ case issuerSubpacket:
+ // Issuer, section 5.2.3.5
+ if sig.Version > 4 {
+ err = errors.StructuralError("issuer subpacket found in v5 key")
+ return
+ }
+ if len(subpacket) != 8 {
+ err = errors.StructuralError("issuer subpacket with bad length")
+ return
+ }
+ sig.IssuerKeyId = new(uint64)
+ *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket)
+ case notationDataSubpacket:
+ // Notation data, section 5.2.3.16
+ if len(subpacket) < 8 {
+ err = errors.StructuralError("notation data subpacket with bad length")
+ return
+ }
+
+ nameLength := uint32(subpacket[4])<<8 | uint32(subpacket[5])
+ valueLength := uint32(subpacket[6])<<8 | uint32(subpacket[7])
+ if len(subpacket) != int(nameLength)+int(valueLength)+8 {
+ err = errors.StructuralError("notation data subpacket with bad length")
+ return
+ }
+
+ notation := Notation{
+ IsHumanReadable: (subpacket[0] & 0x80) == 0x80,
+ Name: string(subpacket[8:(nameLength + 8)]),
+ Value: subpacket[(nameLength + 8):(valueLength + nameLength + 8)],
+ IsCritical: isCritical,
+ }
+
+ sig.Notations = append(sig.Notations, ¬ation)
+ case prefHashAlgosSubpacket:
+ // Preferred hash algorithms, section 5.2.3.8
+ sig.PreferredHash = make([]byte, len(subpacket))
+ copy(sig.PreferredHash, subpacket)
+ case prefCompressionSubpacket:
+ // Preferred compression algorithms, section 5.2.3.9
+ sig.PreferredCompression = make([]byte, len(subpacket))
+ copy(sig.PreferredCompression, subpacket)
+ case primaryUserIdSubpacket:
+ // Primary User ID, section 5.2.3.19
+ if len(subpacket) != 1 {
+ err = errors.StructuralError("primary user id subpacket with bad length")
+ return
+ }
+ sig.IsPrimaryId = new(bool)
+ if subpacket[0] > 0 {
+ *sig.IsPrimaryId = true
+ }
+ case keyFlagsSubpacket:
+ // Key flags, section 5.2.3.21
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("empty key flags subpacket")
+ return
+ }
+ sig.FlagsValid = true
+ if subpacket[0]&KeyFlagCertify != 0 {
+ sig.FlagCertify = true
+ }
+ if subpacket[0]&KeyFlagSign != 0 {
+ sig.FlagSign = true
+ }
+ if subpacket[0]&KeyFlagEncryptCommunications != 0 {
+ sig.FlagEncryptCommunications = true
+ }
+ if subpacket[0]&KeyFlagEncryptStorage != 0 {
+ sig.FlagEncryptStorage = true
+ }
+ if subpacket[0]&KeyFlagSplitKey != 0 {
+ sig.FlagSplitKey = true
+ }
+ if subpacket[0]&KeyFlagAuthenticate != 0 {
+ sig.FlagAuthenticate = true
+ }
+ if subpacket[0]&KeyFlagGroupKey != 0 {
+ sig.FlagGroupKey = true
+ }
+ case signerUserIdSubpacket:
+ userId := string(subpacket)
+ sig.SignerUserId = &userId
+ case reasonForRevocationSubpacket:
+ // Reason For Revocation, section 5.2.3.23
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("empty revocation reason subpacket")
+ return
+ }
+ sig.RevocationReason = new(ReasonForRevocation)
+ *sig.RevocationReason = ReasonForRevocation(subpacket[0])
+ sig.RevocationReasonText = string(subpacket[1:])
+ case featuresSubpacket:
+ // Features subpacket, section 5.2.3.24 specifies a very general
+ // mechanism for OpenPGP implementations to signal support for new
+ // features.
+ if len(subpacket) > 0 {
+ if subpacket[0]&0x01 != 0 {
+ sig.SEIPDv1 = true
+ }
+ // 0x02 and 0x04 are reserved
+ if subpacket[0]&0x08 != 0 {
+ sig.SEIPDv2 = true
+ }
+ }
+ case embeddedSignatureSubpacket:
+ // Only usage is in signatures that cross-certify
+ // signing subkeys. section 5.2.3.26 describes the
+ // format, with its usage described in section 11.1
+ if sig.EmbeddedSignature != nil {
+ err = errors.StructuralError("Cannot have multiple embedded signatures")
+ return
+ }
+ sig.EmbeddedSignature = new(Signature)
+ // Embedded signatures are required to be v4 signatures see
+ // section 12.1. However, we only parse v4 signatures in this
+ // file anyway.
+ if err := sig.EmbeddedSignature.parse(bytes.NewBuffer(subpacket)); err != nil {
+ return nil, err
+ }
+ if sigType := sig.EmbeddedSignature.SigType; sigType != SigTypePrimaryKeyBinding {
+ return nil, errors.StructuralError("cross-signature has unexpected type " + strconv.Itoa(int(sigType)))
+ }
+ case policyUriSubpacket:
+ // Policy URI, section 5.2.3.20
+ sig.PolicyURI = string(subpacket)
+ case issuerFingerprintSubpacket:
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("empty issuer fingerprint subpacket")
+ return
+ }
+ v, l := subpacket[0], len(subpacket[1:])
+ if v == 5 && l != 32 || v != 5 && l != 20 {
+ return nil, errors.StructuralError("bad fingerprint length")
+ }
+ sig.IssuerFingerprint = make([]byte, l)
+ copy(sig.IssuerFingerprint, subpacket[1:])
+ sig.IssuerKeyId = new(uint64)
+ if v == 5 {
+ *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[1:9])
+ } else {
+ *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[13:21])
+ }
+ case prefCipherSuitesSubpacket:
+ // Preferred AEAD cipher suites
+ // See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#name-preferred-aead-ciphersuites
+ if len(subpacket)%2 != 0 {
+ err = errors.StructuralError("invalid aead cipher suite length")
+ return
+ }
+
+ sig.PreferredCipherSuites = make([][2]byte, len(subpacket)/2)
+
+ for i := 0; i < len(subpacket)/2; i++ {
+ sig.PreferredCipherSuites[i] = [2]uint8{subpacket[2*i], subpacket[2*i+1]}
+ }
+ default:
+ if isCritical {
+ err = errors.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
+ return
+ }
+ }
+ return
+
+Truncated:
+ err = errors.StructuralError("signature subpacket truncated")
+ return
+}
+
+// subpacketLengthLength returns the length, in bytes, of an encoded length value.
+func subpacketLengthLength(length int) int {
+ if length < 192 {
+ return 1
+ }
+ if length < 16320 {
+ return 2
+ }
+ return 5
+}
+
+func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool {
+ if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 {
+ return bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint)
+ }
+ return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId
+}
+
+// serializeSubpacketLength marshals the given length into to.
+func serializeSubpacketLength(to []byte, length int) int {
+ // RFC 4880, Section 4.2.2.
+ if length < 192 {
+ to[0] = byte(length)
+ return 1
+ }
+ if length < 16320 {
+ length -= 192
+ to[0] = byte((length >> 8) + 192)
+ to[1] = byte(length)
+ return 2
+ }
+ to[0] = 255
+ to[1] = byte(length >> 24)
+ to[2] = byte(length >> 16)
+ to[3] = byte(length >> 8)
+ to[4] = byte(length)
+ return 5
+}
+
+// subpacketsLength returns the serialized length, in bytes, of the given
+// subpackets.
+func subpacketsLength(subpackets []outputSubpacket, hashed bool) (length int) {
+ for _, subpacket := range subpackets {
+ if subpacket.hashed == hashed {
+ length += subpacketLengthLength(len(subpacket.contents) + 1)
+ length += 1 // type byte
+ length += len(subpacket.contents)
+ }
+ }
+ return
+}
+
+// serializeSubpackets marshals the given subpackets into to.
+func serializeSubpackets(to []byte, subpackets []outputSubpacket, hashed bool) {
+ for _, subpacket := range subpackets {
+ if subpacket.hashed == hashed {
+ n := serializeSubpacketLength(to, len(subpacket.contents)+1)
+ to[n] = byte(subpacket.subpacketType)
+ if subpacket.isCritical {
+ to[n] |= 0x80
+ }
+ to = to[1+n:]
+ n = copy(to, subpacket.contents)
+ to = to[n:]
+ }
+ }
+ return
+}
+
+// SigExpired returns whether sig is a signature that has expired or is created
+// in the future.
+func (sig *Signature) SigExpired(currentTime time.Time) bool {
+ if sig.CreationTime.After(currentTime) {
+ return true
+ }
+ if sig.SigLifetimeSecs == nil || *sig.SigLifetimeSecs == 0 {
+ return false
+ }
+ expiry := sig.CreationTime.Add(time.Duration(*sig.SigLifetimeSecs) * time.Second)
+ return currentTime.After(expiry)
+}
+
+// buildHashSuffix constructs the HashSuffix member of sig in preparation for signing.
+func (sig *Signature) buildHashSuffix(hashedSubpackets []byte) (err error) {
+ var hashId byte
+ var ok bool
+
+ if sig.Version < 5 {
+ hashId, ok = algorithm.HashToHashIdWithSha1(sig.Hash)
+ } else {
+ hashId, ok = algorithm.HashToHashId(sig.Hash)
+ }
+
+ if !ok {
+ sig.HashSuffix = nil
+ return errors.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash)))
+ }
+
+ hashedFields := bytes.NewBuffer([]byte{
+ uint8(sig.Version),
+ uint8(sig.SigType),
+ uint8(sig.PubKeyAlgo),
+ uint8(hashId),
+ uint8(len(hashedSubpackets) >> 8),
+ uint8(len(hashedSubpackets)),
+ })
+ hashedFields.Write(hashedSubpackets)
+
+ var l uint64 = uint64(6 + len(hashedSubpackets))
+ if sig.Version == 5 {
+ hashedFields.Write([]byte{0x05, 0xff})
+ hashedFields.Write([]byte{
+ uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
+ uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
+ })
+ } else {
+ hashedFields.Write([]byte{0x04, 0xff})
+ hashedFields.Write([]byte{
+ uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
+ })
+ }
+ sig.HashSuffix = make([]byte, hashedFields.Len())
+ copy(sig.HashSuffix, hashedFields.Bytes())
+ return
+}
+
+func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
+ hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true)
+ hashedSubpackets := make([]byte, hashedSubpacketsLen)
+ serializeSubpackets(hashedSubpackets, sig.outSubpackets, true)
+ err = sig.buildHashSuffix(hashedSubpackets)
+ if err != nil {
+ return
+ }
+ if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
+ sig.AddMetadataToHashSuffix()
+ }
+
+ h.Write(sig.HashSuffix)
+ digest = h.Sum(nil)
+ copy(sig.HashTag[:], digest)
+ return
+}
+
+// Sign signs a message with a private key. The hash, h, must contain
+// the hash of the message to be signed and will be mutated by this function.
+// On success, the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err error) {
+ if priv.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ sig.Version = priv.PublicKey.Version
+ sig.IssuerFingerprint = priv.PublicKey.Fingerprint
+ sig.outSubpackets, err = sig.buildSubpackets(priv.PublicKey)
+ if err != nil {
+ return err
+ }
+ digest, err := sig.signPrepareHash(h)
+ if err != nil {
+ return
+ }
+ switch priv.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ // supports both *rsa.PrivateKey and crypto.Signer
+ sigdata, err := priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
+ if err == nil {
+ sig.RSASignature = encoding.NewMPI(sigdata)
+ }
+ case PubKeyAlgoDSA:
+ dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
+
+ // Need to truncate hashBytes to match FIPS 186-3 section 4.6.
+ subgroupSize := (dsaPriv.Q.BitLen() + 7) / 8
+ if len(digest) > subgroupSize {
+ digest = digest[:subgroupSize]
+ }
+ r, s, err := dsa.Sign(config.Random(), dsaPriv, digest)
+ if err == nil {
+ sig.DSASigR = new(encoding.MPI).SetBig(r)
+ sig.DSASigS = new(encoding.MPI).SetBig(s)
+ }
+ case PubKeyAlgoECDSA:
+ sk := priv.PrivateKey.(*ecdsa.PrivateKey)
+ r, s, err := ecdsa.Sign(config.Random(), sk, digest)
+
+ if err == nil {
+ sig.ECDSASigR = new(encoding.MPI).SetBig(r)
+ sig.ECDSASigS = new(encoding.MPI).SetBig(s)
+ }
+ case PubKeyAlgoEdDSA:
+ sk := priv.PrivateKey.(*eddsa.PrivateKey)
+ r, s, err := eddsa.Sign(sk, digest)
+ if err == nil {
+ sig.EdDSASigR = encoding.NewMPI(r)
+ sig.EdDSASigS = encoding.NewMPI(s)
+ }
+ default:
+ err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
+ }
+
+ return
+}
+
+// SignUserId computes a signature from priv, asserting that pub is a valid
+// key for the identity id. On success, the signature is stored in sig. Call
+// Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error {
+ if priv.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ h, err := userIdSignatureHash(id, pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return sig.Sign(h, priv, config)
+}
+
+// CrossSignKey computes a signature from signingKey on pub hashed using hashKey. On success,
+// the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) CrossSignKey(pub *PublicKey, hashKey *PublicKey, signingKey *PrivateKey,
+ config *Config) error {
+ h, err := keySignatureHash(hashKey, pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return sig.Sign(h, signingKey, config)
+}
+
+// SignKey computes a signature from priv, asserting that pub is a subkey. On
+// success, the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
+ if priv.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ h, err := keySignatureHash(&priv.PublicKey, pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return sig.Sign(h, priv, config)
+}
+
+// RevokeKey computes a revocation signature of pub using priv. On success, the signature is
+// stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) RevokeKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
+ h, err := keyRevocationHash(pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return sig.Sign(h, priv, config)
+}
+
+// RevokeSubkey computes a subkey revocation signature of pub using priv.
+// On success, the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) RevokeSubkey(pub *PublicKey, priv *PrivateKey, config *Config) error {
+ // Identical to a subkey binding signature
+ return sig.SignKey(pub, priv, config)
+}
+
+// Serialize marshals sig to w. Sign, SignUserId or SignKey must have been
+// called first.
+func (sig *Signature) Serialize(w io.Writer) (err error) {
+ if len(sig.outSubpackets) == 0 {
+ sig.outSubpackets = sig.rawSubpackets
+ }
+ if sig.RSASignature == nil && sig.DSASigR == nil && sig.ECDSASigR == nil && sig.EdDSASigR == nil {
+ return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
+ }
+
+ sigLength := 0
+ switch sig.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ sigLength = int(sig.RSASignature.EncodedLength())
+ case PubKeyAlgoDSA:
+ sigLength = int(sig.DSASigR.EncodedLength())
+ sigLength += int(sig.DSASigS.EncodedLength())
+ case PubKeyAlgoECDSA:
+ sigLength = int(sig.ECDSASigR.EncodedLength())
+ sigLength += int(sig.ECDSASigS.EncodedLength())
+ case PubKeyAlgoEdDSA:
+ sigLength = int(sig.EdDSASigR.EncodedLength())
+ sigLength += int(sig.EdDSASigS.EncodedLength())
+ default:
+ panic("impossible")
+ }
+
+ unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
+ length := len(sig.HashSuffix) - 6 /* trailer not included */ +
+ 2 /* length of unhashed subpackets */ + unhashedSubpacketsLen +
+ 2 /* hash tag */ + sigLength
+ if sig.Version == 5 {
+ length -= 4 // eight-octet instead of four-octet big endian
+ }
+ err = serializeHeader(w, packetTypeSignature, length)
+ if err != nil {
+ return
+ }
+ err = sig.serializeBody(w)
+ if err != nil {
+ return err
+ }
+ return
+}
+
+func (sig *Signature) serializeBody(w io.Writer) (err error) {
+ hashedSubpacketsLen := uint16(uint16(sig.HashSuffix[4])<<8) | uint16(sig.HashSuffix[5])
+ fields := sig.HashSuffix[:6+hashedSubpacketsLen]
+ _, err = w.Write(fields)
+ if err != nil {
+ return
+ }
+
+ unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
+ unhashedSubpackets := make([]byte, 2+unhashedSubpacketsLen)
+ unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8)
+ unhashedSubpackets[1] = byte(unhashedSubpacketsLen)
+ serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false)
+
+ _, err = w.Write(unhashedSubpackets)
+ if err != nil {
+ return
+ }
+ _, err = w.Write(sig.HashTag[:])
+ if err != nil {
+ return
+ }
+
+ switch sig.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ _, err = w.Write(sig.RSASignature.EncodedBytes())
+ case PubKeyAlgoDSA:
+ if _, err = w.Write(sig.DSASigR.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(sig.DSASigS.EncodedBytes())
+ case PubKeyAlgoECDSA:
+ if _, err = w.Write(sig.ECDSASigR.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(sig.ECDSASigS.EncodedBytes())
+ case PubKeyAlgoEdDSA:
+ if _, err = w.Write(sig.EdDSASigR.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(sig.EdDSASigS.EncodedBytes())
+ default:
+ panic("impossible")
+ }
+ return
+}
+
+// outputSubpacket represents a subpacket to be marshaled.
+type outputSubpacket struct {
+ hashed bool // true if this subpacket is in the hashed area.
+ subpacketType signatureSubpacketType
+ isCritical bool
+ contents []byte
+}
+
+func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubpacket, err error) {
+ creationTime := make([]byte, 4)
+ binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix()))
+ subpackets = append(subpackets, outputSubpacket{true, creationTimeSubpacket, false, creationTime})
+
+ if sig.IssuerKeyId != nil && sig.Version == 4 {
+ keyId := make([]byte, 8)
+ binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId)
+ subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
+ }
+ if sig.IssuerFingerprint != nil {
+ contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...)
+ subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version == 5, contents})
+ }
+ if sig.SignerUserId != nil {
+ subpackets = append(subpackets, outputSubpacket{true, signerUserIdSubpacket, false, []byte(*sig.SignerUserId)})
+ }
+ if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 {
+ sigLifetime := make([]byte, 4)
+ binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs)
+ subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime})
+ }
+
+ // Key flags may only appear in self-signatures or certification signatures.
+
+ if sig.FlagsValid {
+ var flags byte
+ if sig.FlagCertify {
+ flags |= KeyFlagCertify
+ }
+ if sig.FlagSign {
+ flags |= KeyFlagSign
+ }
+ if sig.FlagEncryptCommunications {
+ flags |= KeyFlagEncryptCommunications
+ }
+ if sig.FlagEncryptStorage {
+ flags |= KeyFlagEncryptStorage
+ }
+ if sig.FlagSplitKey {
+ flags |= KeyFlagSplitKey
+ }
+ if sig.FlagAuthenticate {
+ flags |= KeyFlagAuthenticate
+ }
+ if sig.FlagGroupKey {
+ flags |= KeyFlagGroupKey
+ }
+ subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, false, []byte{flags}})
+ }
+
+ for _, notation := range sig.Notations {
+ subpackets = append(
+ subpackets,
+ outputSubpacket{
+ true,
+ notationDataSubpacket,
+ notation.IsCritical,
+ notation.getData(),
+ })
+ }
+
+ // The following subpackets may only appear in self-signatures.
+
+ var features = byte(0x00)
+ if sig.SEIPDv1 {
+ features |= 0x01
+ }
+ if sig.SEIPDv2 {
+ features |= 0x08
+ }
+
+ if features != 0x00 {
+ subpackets = append(subpackets, outputSubpacket{true, featuresSubpacket, false, []byte{features}})
+ }
+
+ if sig.TrustLevel != 0 {
+ subpackets = append(subpackets, outputSubpacket{true, trustSubpacket, true, []byte{byte(sig.TrustLevel), byte(sig.TrustAmount)}})
+ }
+
+ if sig.TrustRegularExpression != nil {
+ // RFC specifies the string should be null-terminated; add a null byte to the end
+ subpackets = append(subpackets, outputSubpacket{true, regularExpressionSubpacket, true, []byte(*sig.TrustRegularExpression + "\000")})
+ }
+
+ if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 {
+ keyLifetime := make([]byte, 4)
+ binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs)
+ subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime})
+ }
+
+ if sig.IsPrimaryId != nil && *sig.IsPrimaryId {
+ subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}})
+ }
+
+ if len(sig.PreferredSymmetric) > 0 {
+ subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric})
+ }
+
+ if len(sig.PreferredHash) > 0 {
+ subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash})
+ }
+
+ if len(sig.PreferredCompression) > 0 {
+ subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
+ }
+
+ if len(sig.PolicyURI) > 0 {
+ subpackets = append(subpackets, outputSubpacket{true, policyUriSubpacket, false, []uint8(sig.PolicyURI)})
+ }
+
+ if len(sig.PreferredCipherSuites) > 0 {
+ serialized := make([]byte, len(sig.PreferredCipherSuites)*2)
+ for i, cipherSuite := range sig.PreferredCipherSuites {
+ serialized[2*i] = cipherSuite[0]
+ serialized[2*i+1] = cipherSuite[1]
+ }
+ subpackets = append(subpackets, outputSubpacket{true, prefCipherSuitesSubpacket, false, serialized})
+ }
+
+ // Revocation reason appears only in revocation signatures and is serialized as per section 5.2.3.23.
+ if sig.RevocationReason != nil {
+ subpackets = append(subpackets, outputSubpacket{true, reasonForRevocationSubpacket, true,
+ append([]uint8{uint8(*sig.RevocationReason)}, []uint8(sig.RevocationReasonText)...)})
+ }
+
+ // EmbeddedSignature appears only in subkeys capable of signing and is serialized as per section 5.2.3.26.
+ if sig.EmbeddedSignature != nil {
+ var buf bytes.Buffer
+ err = sig.EmbeddedSignature.serializeBody(&buf)
+ if err != nil {
+ return
+ }
+ subpackets = append(subpackets, outputSubpacket{true, embeddedSignatureSubpacket, true, buf.Bytes()})
+ }
+
+ return
+}
+
+// AddMetadataToHashSuffix modifies the current hash suffix to include metadata
+// (format, filename, and time). Version 5 keys protect this data including it
+// in the hash computation. See section 5.2.4.
+func (sig *Signature) AddMetadataToHashSuffix() {
+ if sig == nil || sig.Version != 5 {
+ return
+ }
+ if sig.SigType != 0x00 && sig.SigType != 0x01 {
+ return
+ }
+ lit := sig.Metadata
+ if lit == nil {
+ // This will translate into six 0x00 bytes.
+ lit = &LiteralData{}
+ }
+
+ // Extract the current byte count
+ n := sig.HashSuffix[len(sig.HashSuffix)-8:]
+ l := uint64(
+ uint64(n[0])<<56 | uint64(n[1])<<48 | uint64(n[2])<<40 | uint64(n[3])<<32 |
+ uint64(n[4])<<24 | uint64(n[5])<<16 | uint64(n[6])<<8 | uint64(n[7]))
+
+ suffix := bytes.NewBuffer(nil)
+ suffix.Write(sig.HashSuffix[:l])
+
+ // Add the metadata
+ var buf [4]byte
+ buf[0] = lit.Format
+ fileName := lit.FileName
+ if len(lit.FileName) > 255 {
+ fileName = fileName[:255]
+ }
+ buf[1] = byte(len(fileName))
+ suffix.Write(buf[:2])
+ suffix.Write([]byte(lit.FileName))
+ binary.BigEndian.PutUint32(buf[:], lit.Time)
+ suffix.Write(buf[:])
+
+ // Update the counter and restore trailing bytes
+ l = uint64(suffix.Len())
+ suffix.Write([]byte{0x05, 0xff})
+ suffix.Write([]byte{
+ uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
+ uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
+ })
+ sig.HashSuffix = suffix.Bytes()
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go
new file mode 100644
index 00000000..bac2b132
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go
@@ -0,0 +1,276 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "io"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/s2k"
+)
+
+// This is the largest session key that we'll support. Since at most 256-bit cipher
+// is supported in OpenPGP, this is large enough to contain also the auth tag.
+const maxSessionKeySizeInBytes = 64
+
+// SymmetricKeyEncrypted represents a passphrase protected session key. See RFC
+// 4880, section 5.3.
+type SymmetricKeyEncrypted struct {
+ Version int
+ CipherFunc CipherFunction
+ Mode AEADMode
+ s2k func(out, in []byte)
+ iv []byte
+ encryptedKey []byte // Contains also the authentication tag for AEAD
+}
+
+// parse parses an SymmetricKeyEncrypted packet as specified in
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#name-symmetric-key-encrypted-ses
+func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error {
+ var buf [1]byte
+
+ // Version
+ if _, err := readFull(r, buf[:]); err != nil {
+ return err
+ }
+ ske.Version = int(buf[0])
+ if ske.Version != 4 && ske.Version != 5 {
+ return errors.UnsupportedError("unknown SymmetricKeyEncrypted version")
+ }
+
+ // Cipher function
+ if _, err := readFull(r, buf[:]); err != nil {
+ return err
+ }
+ ske.CipherFunc = CipherFunction(buf[0])
+ if !ske.CipherFunc.IsSupported() {
+ return errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[0])))
+ }
+
+ if ske.Version == 5 {
+ // AEAD mode
+ if _, err := readFull(r, buf[:]); err != nil {
+ return errors.StructuralError("cannot read AEAD octet from packet")
+ }
+ ske.Mode = AEADMode(buf[0])
+ }
+
+ var err error
+ if ske.s2k, err = s2k.Parse(r); err != nil {
+ if _, ok := err.(errors.ErrDummyPrivateKey); ok {
+ return errors.UnsupportedError("missing key GNU extension in session key")
+ }
+ return err
+ }
+
+ if ske.Version == 5 {
+ // AEAD IV
+ iv := make([]byte, ske.Mode.IvLength())
+ _, err := readFull(r, iv)
+ if err != nil {
+ return errors.StructuralError("cannot read AEAD IV")
+ }
+
+ ske.iv = iv
+ }
+
+ encryptedKey := make([]byte, maxSessionKeySizeInBytes)
+ // The session key may follow. We just have to try and read to find
+ // out. If it exists then we limit it to maxSessionKeySizeInBytes.
+ n, err := readFull(r, encryptedKey)
+ if err != nil && err != io.ErrUnexpectedEOF {
+ return err
+ }
+
+ if n != 0 {
+ if n == maxSessionKeySizeInBytes {
+ return errors.UnsupportedError("oversized encrypted session key")
+ }
+ ske.encryptedKey = encryptedKey[:n]
+ }
+ return nil
+}
+
+// Decrypt attempts to decrypt an encrypted session key and returns the key and
+// the cipher to use when decrypting a subsequent Symmetrically Encrypted Data
+// packet.
+func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) ([]byte, CipherFunction, error) {
+ key := make([]byte, ske.CipherFunc.KeySize())
+ ske.s2k(key, passphrase)
+ if len(ske.encryptedKey) == 0 {
+ return key, ske.CipherFunc, nil
+ }
+ switch ske.Version {
+ case 4:
+ plaintextKey, cipherFunc, err := ske.decryptV4(key)
+ return plaintextKey, cipherFunc, err
+ case 5:
+ plaintextKey, err := ske.decryptV5(key)
+ return plaintextKey, CipherFunction(0), err
+ }
+ err := errors.UnsupportedError("unknown SymmetricKeyEncrypted version")
+ return nil, CipherFunction(0), err
+}
+
+func (ske *SymmetricKeyEncrypted) decryptV4(key []byte) ([]byte, CipherFunction, error) {
+ // the IV is all zeros
+ iv := make([]byte, ske.CipherFunc.blockSize())
+ c := cipher.NewCFBDecrypter(ske.CipherFunc.new(key), iv)
+ plaintextKey := make([]byte, len(ske.encryptedKey))
+ c.XORKeyStream(plaintextKey, ske.encryptedKey)
+ cipherFunc := CipherFunction(plaintextKey[0])
+ if cipherFunc.blockSize() == 0 {
+ return nil, ske.CipherFunc, errors.UnsupportedError(
+ "unknown cipher: " + strconv.Itoa(int(cipherFunc)))
+ }
+ plaintextKey = plaintextKey[1:]
+ if len(plaintextKey) != cipherFunc.KeySize() {
+ return nil, cipherFunc, errors.StructuralError(
+ "length of decrypted key not equal to cipher keysize")
+ }
+ return plaintextKey, cipherFunc, nil
+}
+
+func (ske *SymmetricKeyEncrypted) decryptV5(key []byte) ([]byte, error) {
+ adata := []byte{0xc3, byte(5), byte(ske.CipherFunc), byte(ske.Mode)}
+ aead := getEncryptedKeyAeadInstance(ske.CipherFunc, ske.Mode, key, adata)
+
+ plaintextKey, err := aead.Open(nil, ske.iv, ske.encryptedKey, adata)
+ if err != nil {
+ return nil, err
+ }
+ return plaintextKey, nil
+}
+
+// SerializeSymmetricKeyEncrypted serializes a symmetric key packet to w.
+// The packet contains a random session key, encrypted by a key derived from
+// the given passphrase. The session key is returned and must be passed to
+// SerializeSymmetricallyEncrypted.
+// If config is nil, sensible defaults will be used.
+func SerializeSymmetricKeyEncrypted(w io.Writer, passphrase []byte, config *Config) (key []byte, err error) {
+ cipherFunc := config.Cipher()
+
+ sessionKey := make([]byte, cipherFunc.KeySize())
+ _, err = io.ReadFull(config.Random(), sessionKey)
+ if err != nil {
+ return
+ }
+
+ err = SerializeSymmetricKeyEncryptedReuseKey(w, sessionKey, passphrase, config)
+ if err != nil {
+ return
+ }
+
+ key = sessionKey
+ return
+}
+
+// SerializeSymmetricKeyEncryptedReuseKey serializes a symmetric key packet to w.
+// The packet contains the given session key, encrypted by a key derived from
+// the given passphrase. The returned session key must be passed to
+// SerializeSymmetricallyEncrypted.
+// If config is nil, sensible defaults will be used.
+func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, passphrase []byte, config *Config) (err error) {
+ var version int
+ if config.AEAD() != nil {
+ version = 5
+ } else {
+ version = 4
+ }
+ cipherFunc := config.Cipher()
+ // cipherFunc must be AES
+ if !cipherFunc.IsSupported() || cipherFunc < CipherAES128 || cipherFunc > CipherAES256 {
+ return errors.UnsupportedError("unsupported cipher: " + strconv.Itoa(int(cipherFunc)))
+ }
+
+ keySize := cipherFunc.KeySize()
+ s2kBuf := new(bytes.Buffer)
+ keyEncryptingKey := make([]byte, keySize)
+ // s2k.Serialize salts and stretches the passphrase, and writes the
+ // resulting key to keyEncryptingKey and the s2k descriptor to s2kBuf.
+ err = s2k.Serialize(s2kBuf, keyEncryptingKey, config.Random(), passphrase, config.S2K())
+ if err != nil {
+ return
+ }
+ s2kBytes := s2kBuf.Bytes()
+
+ var packetLength int
+ switch version {
+ case 4:
+ packetLength = 2 /* header */ + len(s2kBytes) + 1 /* cipher type */ + keySize
+ case 5:
+ ivLen := config.AEAD().Mode().IvLength()
+ tagLen := config.AEAD().Mode().TagLength()
+ packetLength = 3 + len(s2kBytes) + ivLen + keySize + tagLen
+ }
+ err = serializeHeader(w, packetTypeSymmetricKeyEncrypted, packetLength)
+ if err != nil {
+ return
+ }
+
+ // Symmetric Key Encrypted Version
+ buf := []byte{byte(version)}
+
+ // Cipher function
+ buf = append(buf, byte(cipherFunc))
+
+ if version == 5 {
+ // AEAD mode
+ buf = append(buf, byte(config.AEAD().Mode()))
+ }
+ _, err = w.Write(buf)
+ if err != nil {
+ return
+ }
+ _, err = w.Write(s2kBytes)
+ if err != nil {
+ return
+ }
+
+ switch version {
+ case 4:
+ iv := make([]byte, cipherFunc.blockSize())
+ c := cipher.NewCFBEncrypter(cipherFunc.new(keyEncryptingKey), iv)
+ encryptedCipherAndKey := make([]byte, keySize+1)
+ c.XORKeyStream(encryptedCipherAndKey, buf[1:])
+ c.XORKeyStream(encryptedCipherAndKey[1:], sessionKey)
+ _, err = w.Write(encryptedCipherAndKey)
+ if err != nil {
+ return
+ }
+ case 5:
+ mode := config.AEAD().Mode()
+ adata := []byte{0xc3, byte(5), byte(cipherFunc), byte(mode)}
+ aead := getEncryptedKeyAeadInstance(cipherFunc, mode, keyEncryptingKey, adata)
+
+ // Sample iv using random reader
+ iv := make([]byte, config.AEAD().Mode().IvLength())
+ _, err = io.ReadFull(config.Random(), iv)
+ if err != nil {
+ return
+ }
+ // Seal and write (encryptedData includes auth. tag)
+
+ encryptedData := aead.Seal(nil, iv, sessionKey, adata)
+ _, err = w.Write(iv)
+ if err != nil {
+ return
+ }
+ _, err = w.Write(encryptedData)
+ if err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+func getEncryptedKeyAeadInstance(c CipherFunction, mode AEADMode, inputKey, associatedData []byte) (aead cipher.AEAD) {
+ blockCipher := c.new(inputKey)
+ return mode.new(blockCipher)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go
new file mode 100644
index 00000000..e9bbf032
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go
@@ -0,0 +1,90 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+const aeadSaltSize = 32
+
+// SymmetricallyEncrypted represents a symmetrically encrypted byte string. The
+// encrypted Contents will consist of more OpenPGP packets. See RFC 4880,
+// sections 5.7 and 5.13.
+type SymmetricallyEncrypted struct {
+ Version int
+ Contents io.Reader // contains tag for version 2
+ IntegrityProtected bool // If true it is type 18 (with MDC or AEAD). False is packet type 9
+
+ // Specific to version 1
+ prefix []byte
+
+ // Specific to version 2
+ Cipher CipherFunction
+ Mode AEADMode
+ ChunkSizeByte byte
+ Salt [aeadSaltSize]byte
+}
+
+const (
+ symmetricallyEncryptedVersionMdc = 1
+ symmetricallyEncryptedVersionAead = 2
+)
+
+func (se *SymmetricallyEncrypted) parse(r io.Reader) error {
+ if se.IntegrityProtected {
+ // See RFC 4880, section 5.13.
+ var buf [1]byte
+ _, err := readFull(r, buf[:])
+ if err != nil {
+ return err
+ }
+
+ switch buf[0] {
+ case symmetricallyEncryptedVersionMdc:
+ se.Version = symmetricallyEncryptedVersionMdc
+ case symmetricallyEncryptedVersionAead:
+ se.Version = symmetricallyEncryptedVersionAead
+ if err := se.parseAead(r); err != nil {
+ return err
+ }
+ default:
+ return errors.UnsupportedError("unknown SymmetricallyEncrypted version")
+ }
+ }
+ se.Contents = r
+ return nil
+}
+
+// Decrypt returns a ReadCloser, from which the decrypted Contents of the
+// packet can be read. An incorrect key will only be detected after trying
+// to decrypt the entire data.
+func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, error) {
+ if se.Version == symmetricallyEncryptedVersionAead {
+ return se.decryptAead(key)
+ }
+
+ return se.decryptMdc(c, key)
+}
+
+// SerializeSymmetricallyEncrypted serializes a symmetrically encrypted packet
+// to w and returns a WriteCloser to which the to-be-encrypted packets can be
+// written.
+// If config is nil, sensible defaults will be used.
+func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, aeadSupported bool, cipherSuite CipherSuite, key []byte, config *Config) (Contents io.WriteCloser, err error) {
+ writeCloser := noOpCloser{w}
+ ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedIntegrityProtected)
+ if err != nil {
+ return
+ }
+
+ if aeadSupported {
+ return serializeSymmetricallyEncryptedAead(ciphertext, cipherSuite, config.AEADConfig.ChunkSizeByte(), config.Random(), key)
+ }
+
+ return serializeSymmetricallyEncryptedMdc(ciphertext, c, key, config)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go
new file mode 100644
index 00000000..e96252c1
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go
@@ -0,0 +1,156 @@
+// Copyright 2023 Proton AG. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto/cipher"
+ "crypto/sha256"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "golang.org/x/crypto/hkdf"
+)
+
+// parseAead parses a V2 SEIPD packet (AEAD) as specified in
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
+func (se *SymmetricallyEncrypted) parseAead(r io.Reader) error {
+ headerData := make([]byte, 3)
+ if n, err := io.ReadFull(r, headerData); n < 3 {
+ return errors.StructuralError("could not read aead header: " + err.Error())
+ }
+
+ // Cipher
+ se.Cipher = CipherFunction(headerData[0])
+ // cipherFunc must have block size 16 to use AEAD
+ if se.Cipher.blockSize() != 16 {
+ return errors.UnsupportedError("invalid aead cipher: " + string(se.Cipher))
+ }
+
+ // Mode
+ se.Mode = AEADMode(headerData[1])
+ if se.Mode.TagLength() == 0 {
+ return errors.UnsupportedError("unknown aead mode: " + string(se.Mode))
+ }
+
+ // Chunk size
+ se.ChunkSizeByte = headerData[2]
+ if se.ChunkSizeByte > 16 {
+ return errors.UnsupportedError("invalid aead chunk size byte: " + string(se.ChunkSizeByte))
+ }
+
+ // Salt
+ if n, err := io.ReadFull(r, se.Salt[:]); n < aeadSaltSize {
+ return errors.StructuralError("could not read aead salt: " + err.Error())
+ }
+
+ return nil
+}
+
+// associatedData for chunks: tag, version, cipher, mode, chunk size byte
+func (se *SymmetricallyEncrypted) associatedData() []byte {
+ return []byte{
+ 0xD2,
+ symmetricallyEncryptedVersionAead,
+ byte(se.Cipher),
+ byte(se.Mode),
+ se.ChunkSizeByte,
+ }
+}
+
+// decryptAead decrypts a V2 SEIPD packet (AEAD) as specified in
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
+func (se *SymmetricallyEncrypted) decryptAead(inputKey []byte) (io.ReadCloser, error) {
+ aead, nonce := getSymmetricallyEncryptedAeadInstance(se.Cipher, se.Mode, inputKey, se.Salt[:], se.associatedData())
+
+ // Carry the first tagLen bytes
+ tagLen := se.Mode.TagLength()
+ peekedBytes := make([]byte, tagLen)
+ n, err := io.ReadFull(se.Contents, peekedBytes)
+ if n < tagLen || (err != nil && err != io.EOF) {
+ return nil, errors.StructuralError("not enough data to decrypt:" + err.Error())
+ }
+
+ return &aeadDecrypter{
+ aeadCrypter: aeadCrypter{
+ aead: aead,
+ chunkSize: decodeAEADChunkSize(se.ChunkSizeByte),
+ initialNonce: nonce,
+ associatedData: se.associatedData(),
+ chunkIndex: make([]byte, 8),
+ packetTag: packetTypeSymmetricallyEncryptedIntegrityProtected,
+ },
+ reader: se.Contents,
+ peekedBytes: peekedBytes,
+ }, nil
+}
+
+// serializeSymmetricallyEncryptedAead encrypts to a writer a V2 SEIPD packet (AEAD) as specified in
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
+func serializeSymmetricallyEncryptedAead(ciphertext io.WriteCloser, cipherSuite CipherSuite, chunkSizeByte byte, rand io.Reader, inputKey []byte) (Contents io.WriteCloser, err error) {
+ // cipherFunc must have block size 16 to use AEAD
+ if cipherSuite.Cipher.blockSize() != 16 {
+ return nil, errors.InvalidArgumentError("invalid aead cipher function")
+ }
+
+ if cipherSuite.Cipher.KeySize() != len(inputKey) {
+ return nil, errors.InvalidArgumentError("error in aead serialization: bad key length")
+ }
+
+ // Data for en/decryption: tag, version, cipher, aead mode, chunk size
+ prefix := []byte{
+ 0xD2,
+ symmetricallyEncryptedVersionAead,
+ byte(cipherSuite.Cipher),
+ byte(cipherSuite.Mode),
+ chunkSizeByte,
+ }
+
+ // Write header (that correspond to prefix except first byte)
+ n, err := ciphertext.Write(prefix[1:])
+ if err != nil || n < 4 {
+ return nil, err
+ }
+
+ // Random salt
+ salt := make([]byte, aeadSaltSize)
+ if _, err := rand.Read(salt); err != nil {
+ return nil, err
+ }
+
+ if _, err := ciphertext.Write(salt); err != nil {
+ return nil, err
+ }
+
+ aead, nonce := getSymmetricallyEncryptedAeadInstance(cipherSuite.Cipher, cipherSuite.Mode, inputKey, salt, prefix)
+
+ return &aeadEncrypter{
+ aeadCrypter: aeadCrypter{
+ aead: aead,
+ chunkSize: decodeAEADChunkSize(chunkSizeByte),
+ associatedData: prefix,
+ chunkIndex: make([]byte, 8),
+ initialNonce: nonce,
+ packetTag: packetTypeSymmetricallyEncryptedIntegrityProtected,
+ },
+ writer: ciphertext,
+ }, nil
+}
+
+func getSymmetricallyEncryptedAeadInstance(c CipherFunction, mode AEADMode, inputKey, salt, associatedData []byte) (aead cipher.AEAD, nonce []byte) {
+ hkdfReader := hkdf.New(sha256.New, inputKey, salt, associatedData)
+
+ encryptionKey := make([]byte, c.KeySize())
+ _, _ = readFull(hkdfReader, encryptionKey)
+
+ // Last 64 bits of nonce are the counter
+ nonce = make([]byte, mode.IvLength()-8)
+
+ _, _ = readFull(hkdfReader, nonce)
+
+ blockCipher := c.new(encryptionKey)
+ aead = mode.new(blockCipher)
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go
new file mode 100644
index 00000000..fa26bebe
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go
@@ -0,0 +1,256 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto/cipher"
+ "crypto/sha1"
+ "crypto/subtle"
+ "hash"
+ "io"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// seMdcReader wraps an io.Reader with a no-op Close method.
+type seMdcReader struct {
+ in io.Reader
+}
+
+func (ser seMdcReader) Read(buf []byte) (int, error) {
+ return ser.in.Read(buf)
+}
+
+func (ser seMdcReader) Close() error {
+ return nil
+}
+
+func (se *SymmetricallyEncrypted) decryptMdc(c CipherFunction, key []byte) (io.ReadCloser, error) {
+ if !c.IsSupported() {
+ return nil, errors.UnsupportedError("unsupported cipher: " + strconv.Itoa(int(c)))
+ }
+
+ if len(key) != c.KeySize() {
+ return nil, errors.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length")
+ }
+
+ if se.prefix == nil {
+ se.prefix = make([]byte, c.blockSize()+2)
+ _, err := readFull(se.Contents, se.prefix)
+ if err != nil {
+ return nil, err
+ }
+ } else if len(se.prefix) != c.blockSize()+2 {
+ return nil, errors.InvalidArgumentError("can't try ciphers with different block lengths")
+ }
+
+ ocfbResync := OCFBResync
+ if se.IntegrityProtected {
+ // MDC packets use a different form of OCFB mode.
+ ocfbResync = OCFBNoResync
+ }
+
+ s := NewOCFBDecrypter(c.new(key), se.prefix, ocfbResync)
+
+ plaintext := cipher.StreamReader{S: s, R: se.Contents}
+
+ if se.IntegrityProtected {
+ // IntegrityProtected packets have an embedded hash that we need to check.
+ h := sha1.New()
+ h.Write(se.prefix)
+ return &seMDCReader{in: plaintext, h: h}, nil
+ }
+
+ // Otherwise, we just need to wrap plaintext so that it's a valid ReadCloser.
+ return seMdcReader{plaintext}, nil
+}
+
+const mdcTrailerSize = 1 /* tag byte */ + 1 /* length byte */ + sha1.Size
+
+// An seMDCReader wraps an io.Reader, maintains a running hash and keeps hold
+// of the most recent 22 bytes (mdcTrailerSize). Upon EOF, those bytes form an
+// MDC packet containing a hash of the previous Contents which is checked
+// against the running hash. See RFC 4880, section 5.13.
+type seMDCReader struct {
+ in io.Reader
+ h hash.Hash
+ trailer [mdcTrailerSize]byte
+ scratch [mdcTrailerSize]byte
+ trailerUsed int
+ error bool
+ eof bool
+}
+
+func (ser *seMDCReader) Read(buf []byte) (n int, err error) {
+ if ser.error {
+ err = io.ErrUnexpectedEOF
+ return
+ }
+ if ser.eof {
+ err = io.EOF
+ return
+ }
+
+ // If we haven't yet filled the trailer buffer then we must do that
+ // first.
+ for ser.trailerUsed < mdcTrailerSize {
+ n, err = ser.in.Read(ser.trailer[ser.trailerUsed:])
+ ser.trailerUsed += n
+ if err == io.EOF {
+ if ser.trailerUsed != mdcTrailerSize {
+ n = 0
+ err = io.ErrUnexpectedEOF
+ ser.error = true
+ return
+ }
+ ser.eof = true
+ n = 0
+ return
+ }
+
+ if err != nil {
+ n = 0
+ return
+ }
+ }
+
+ // If it's a short read then we read into a temporary buffer and shift
+ // the data into the caller's buffer.
+ if len(buf) <= mdcTrailerSize {
+ n, err = readFull(ser.in, ser.scratch[:len(buf)])
+ copy(buf, ser.trailer[:n])
+ ser.h.Write(buf[:n])
+ copy(ser.trailer[:], ser.trailer[n:])
+ copy(ser.trailer[mdcTrailerSize-n:], ser.scratch[:])
+ if n < len(buf) {
+ ser.eof = true
+ err = io.EOF
+ }
+ return
+ }
+
+ n, err = ser.in.Read(buf[mdcTrailerSize:])
+ copy(buf, ser.trailer[:])
+ ser.h.Write(buf[:n])
+ copy(ser.trailer[:], buf[n:])
+
+ if err == io.EOF {
+ ser.eof = true
+ }
+ return
+}
+
+// This is a new-format packet tag byte for a type 19 (Integrity Protected) packet.
+const mdcPacketTagByte = byte(0x80) | 0x40 | 19
+
+func (ser *seMDCReader) Close() error {
+ if ser.error {
+ return errors.ErrMDCMissing
+ }
+
+ for !ser.eof {
+ // We haven't seen EOF so we need to read to the end
+ var buf [1024]byte
+ _, err := ser.Read(buf[:])
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return errors.ErrMDCMissing
+ }
+ }
+
+ ser.h.Write(ser.trailer[:2])
+
+ final := ser.h.Sum(nil)
+ if subtle.ConstantTimeCompare(final, ser.trailer[2:]) != 1 {
+ return errors.ErrMDCHashMismatch
+ }
+ // The hash already includes the MDC header, but we still check its value
+ // to confirm encryption correctness
+ if ser.trailer[0] != mdcPacketTagByte || ser.trailer[1] != sha1.Size {
+ return errors.ErrMDCMissing
+ }
+ return nil
+}
+
+// An seMDCWriter writes through to an io.WriteCloser while maintains a running
+// hash of the data written. On close, it emits an MDC packet containing the
+// running hash.
+type seMDCWriter struct {
+ w io.WriteCloser
+ h hash.Hash
+}
+
+func (w *seMDCWriter) Write(buf []byte) (n int, err error) {
+ w.h.Write(buf)
+ return w.w.Write(buf)
+}
+
+func (w *seMDCWriter) Close() (err error) {
+ var buf [mdcTrailerSize]byte
+
+ buf[0] = mdcPacketTagByte
+ buf[1] = sha1.Size
+ w.h.Write(buf[:2])
+ digest := w.h.Sum(nil)
+ copy(buf[2:], digest)
+
+ _, err = w.w.Write(buf[:])
+ if err != nil {
+ return
+ }
+ return w.w.Close()
+}
+
+// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
+type noOpCloser struct {
+ w io.Writer
+}
+
+func (c noOpCloser) Write(data []byte) (n int, err error) {
+ return c.w.Write(data)
+}
+
+func (c noOpCloser) Close() error {
+ return nil
+}
+
+func serializeSymmetricallyEncryptedMdc(ciphertext io.WriteCloser, c CipherFunction, key []byte, config *Config) (Contents io.WriteCloser, err error) {
+ // Disallow old cipher suites
+ if !c.IsSupported() || c < CipherAES128 {
+ return nil, errors.InvalidArgumentError("invalid mdc cipher function")
+ }
+
+ if c.KeySize() != len(key) {
+ return nil, errors.InvalidArgumentError("error in mdc serialization: bad key length")
+ }
+
+ _, err = ciphertext.Write([]byte{symmetricallyEncryptedVersionMdc})
+ if err != nil {
+ return
+ }
+
+ block := c.new(key)
+ blockSize := block.BlockSize()
+ iv := make([]byte, blockSize)
+ _, err = config.Random().Read(iv)
+ if err != nil {
+ return
+ }
+ s, prefix := NewOCFBEncrypter(block, iv, OCFBNoResync)
+ _, err = ciphertext.Write(prefix)
+ if err != nil {
+ return
+ }
+ plaintext := cipher.StreamWriter{S: s, W: ciphertext}
+
+ h := sha1.New()
+ h.Write(iv)
+ h.Write(iv[blockSize-2:])
+ Contents = &seMDCWriter{w: plaintext, h: h}
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go
new file mode 100644
index 00000000..88ec72c6
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go
@@ -0,0 +1,101 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "image"
+ "image/jpeg"
+ "io"
+ "io/ioutil"
+)
+
+const UserAttrImageSubpacket = 1
+
+// UserAttribute is capable of storing other types of data about a user
+// beyond name, email and a text comment. In practice, user attributes are typically used
+// to store a signed thumbnail photo JPEG image of the user.
+// See RFC 4880, section 5.12.
+type UserAttribute struct {
+ Contents []*OpaqueSubpacket
+}
+
+// NewUserAttributePhoto creates a user attribute packet
+// containing the given images.
+func NewUserAttributePhoto(photos ...image.Image) (uat *UserAttribute, err error) {
+ uat = new(UserAttribute)
+ for _, photo := range photos {
+ var buf bytes.Buffer
+ // RFC 4880, Section 5.12.1.
+ data := []byte{
+ 0x10, 0x00, // Little-endian image header length (16 bytes)
+ 0x01, // Image header version 1
+ 0x01, // JPEG
+ 0, 0, 0, 0, // 12 reserved octets, must be all zero.
+ 0, 0, 0, 0,
+ 0, 0, 0, 0}
+ if _, err = buf.Write(data); err != nil {
+ return
+ }
+ if err = jpeg.Encode(&buf, photo, nil); err != nil {
+ return
+ }
+
+ lengthBuf := make([]byte, 5)
+ n := serializeSubpacketLength(lengthBuf, len(buf.Bytes())+1)
+ lengthBuf = lengthBuf[:n]
+
+ uat.Contents = append(uat.Contents, &OpaqueSubpacket{
+ SubType: UserAttrImageSubpacket,
+ EncodedLength: lengthBuf,
+ Contents: buf.Bytes(),
+ })
+ }
+ return
+}
+
+// NewUserAttribute creates a new user attribute packet containing the given subpackets.
+func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute {
+ return &UserAttribute{Contents: contents}
+}
+
+func (uat *UserAttribute) parse(r io.Reader) (err error) {
+ // RFC 4880, section 5.13
+ b, err := ioutil.ReadAll(r)
+ if err != nil {
+ return
+ }
+ uat.Contents, err = OpaqueSubpackets(b)
+ return
+}
+
+// Serialize marshals the user attribute to w in the form of an OpenPGP packet, including
+// header.
+func (uat *UserAttribute) Serialize(w io.Writer) (err error) {
+ var buf bytes.Buffer
+ for _, sp := range uat.Contents {
+ err = sp.Serialize(&buf)
+ if err != nil {
+ return err
+ }
+ }
+ if err = serializeHeader(w, packetTypeUserAttribute, buf.Len()); err != nil {
+ return err
+ }
+ _, err = w.Write(buf.Bytes())
+ return
+}
+
+// ImageData returns zero or more byte slices, each containing
+// JPEG File Interchange Format (JFIF), for each photo in the
+// user attribute packet.
+func (uat *UserAttribute) ImageData() (imageData [][]byte) {
+ for _, sp := range uat.Contents {
+ if sp.SubType == UserAttrImageSubpacket && len(sp.Contents) > 16 {
+ imageData = append(imageData, sp.Contents[16:])
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go
new file mode 100644
index 00000000..614fbafd
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go
@@ -0,0 +1,167 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "io"
+ "io/ioutil"
+ "strings"
+)
+
+// UserId contains text that is intended to represent the name and email
+// address of the key holder. See RFC 4880, section 5.11. By convention, this
+// takes the form "Full Name (Comment) "
+type UserId struct {
+ Id string // By convention, this takes the form "Full Name (Comment) " which is split out in the fields below.
+
+ Name, Comment, Email string
+}
+
+func hasInvalidCharacters(s string) bool {
+ for _, c := range s {
+ switch c {
+ case '(', ')', '<', '>', 0:
+ return true
+ }
+ }
+ return false
+}
+
+// NewUserId returns a UserId or nil if any of the arguments contain invalid
+// characters. The invalid characters are '\x00', '(', ')', '<' and '>'
+func NewUserId(name, comment, email string) *UserId {
+ // RFC 4880 doesn't deal with the structure of userid strings; the
+ // name, comment and email form is just a convention. However, there's
+ // no convention about escaping the metacharacters and GPG just refuses
+ // to create user ids where, say, the name contains a '('. We mirror
+ // this behaviour.
+
+ if hasInvalidCharacters(name) || hasInvalidCharacters(comment) || hasInvalidCharacters(email) {
+ return nil
+ }
+
+ uid := new(UserId)
+ uid.Name, uid.Comment, uid.Email = name, comment, email
+ uid.Id = name
+ if len(comment) > 0 {
+ if len(uid.Id) > 0 {
+ uid.Id += " "
+ }
+ uid.Id += "("
+ uid.Id += comment
+ uid.Id += ")"
+ }
+ if len(email) > 0 {
+ if len(uid.Id) > 0 {
+ uid.Id += " "
+ }
+ uid.Id += "<"
+ uid.Id += email
+ uid.Id += ">"
+ }
+ return uid
+}
+
+func (uid *UserId) parse(r io.Reader) (err error) {
+ // RFC 4880, section 5.11
+ b, err := ioutil.ReadAll(r)
+ if err != nil {
+ return
+ }
+ uid.Id = string(b)
+ uid.Name, uid.Comment, uid.Email = parseUserId(uid.Id)
+ return
+}
+
+// Serialize marshals uid to w in the form of an OpenPGP packet, including
+// header.
+func (uid *UserId) Serialize(w io.Writer) error {
+ err := serializeHeader(w, packetTypeUserId, len(uid.Id))
+ if err != nil {
+ return err
+ }
+ _, err = w.Write([]byte(uid.Id))
+ return err
+}
+
+// parseUserId extracts the name, comment and email from a user id string that
+// is formatted as "Full Name (Comment) ".
+func parseUserId(id string) (name, comment, email string) {
+ var n, c, e struct {
+ start, end int
+ }
+ var state int
+
+ for offset, rune := range id {
+ switch state {
+ case 0:
+ // Entering name
+ n.start = offset
+ state = 1
+ fallthrough
+ case 1:
+ // In name
+ if rune == '(' {
+ state = 2
+ n.end = offset
+ } else if rune == '<' {
+ state = 5
+ n.end = offset
+ }
+ case 2:
+ // Entering comment
+ c.start = offset
+ state = 3
+ fallthrough
+ case 3:
+ // In comment
+ if rune == ')' {
+ state = 4
+ c.end = offset
+ }
+ case 4:
+ // Between comment and email
+ if rune == '<' {
+ state = 5
+ }
+ case 5:
+ // Entering email
+ e.start = offset
+ state = 6
+ fallthrough
+ case 6:
+ // In email
+ if rune == '>' {
+ state = 7
+ e.end = offset
+ }
+ default:
+ // After email
+ }
+ }
+ switch state {
+ case 1:
+ // ended in the name
+ n.end = len(id)
+ case 3:
+ // ended in comment
+ c.end = len(id)
+ case 6:
+ // ended in email
+ e.end = len(id)
+ }
+
+ name = strings.TrimSpace(id[n.start:n.end])
+ comment = strings.TrimSpace(id[c.start:c.end])
+ email = strings.TrimSpace(id[e.start:e.end])
+
+ // RFC 2822 3.4: alternate simple form of a mailbox
+ if email == "" && strings.ContainsRune(name, '@') {
+ email = name
+ name = ""
+ }
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go
new file mode 100644
index 00000000..8499c737
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go
@@ -0,0 +1,592 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package openpgp implements high level operations on OpenPGP messages.
+package openpgp // import "github.com/ProtonMail/go-crypto/openpgp"
+
+import (
+ "crypto"
+ _ "crypto/sha256"
+ _ "crypto/sha512"
+ "hash"
+ "io"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/armor"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+ _ "golang.org/x/crypto/sha3"
+)
+
+// SignatureType is the armor type for a PGP signature.
+var SignatureType = "PGP SIGNATURE"
+
+// readArmored reads an armored block with the given type.
+func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) {
+ block, err := armor.Decode(r)
+ if err != nil {
+ return
+ }
+
+ if block.Type != expectedType {
+ return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type)
+ }
+
+ return block.Body, nil
+}
+
+// MessageDetails contains the result of parsing an OpenPGP encrypted and/or
+// signed message.
+type MessageDetails struct {
+ IsEncrypted bool // true if the message was encrypted.
+ EncryptedToKeyIds []uint64 // the list of recipient key ids.
+ IsSymmetricallyEncrypted bool // true if a passphrase could have decrypted the message.
+ DecryptedWith Key // the private key used to decrypt the message, if any.
+ IsSigned bool // true if the message is signed.
+ SignedByKeyId uint64 // the key id of the signer, if any.
+ SignedBy *Key // the key of the signer, if available.
+ LiteralData *packet.LiteralData // the metadata of the contents
+ UnverifiedBody io.Reader // the contents of the message.
+
+ // If IsSigned is true and SignedBy is non-zero then the signature will
+ // be verified as UnverifiedBody is read. The signature cannot be
+ // checked until the whole of UnverifiedBody is read so UnverifiedBody
+ // must be consumed until EOF before the data can be trusted. Even if a
+ // message isn't signed (or the signer is unknown) the data may contain
+ // an authentication code that is only checked once UnverifiedBody has
+ // been consumed. Once EOF has been seen, the following fields are
+ // valid. (An authentication code failure is reported as a
+ // SignatureError error when reading from UnverifiedBody.)
+ Signature *packet.Signature // the signature packet itself.
+ SignatureError error // nil if the signature is good.
+ UnverifiedSignatures []*packet.Signature // all other unverified signature packets.
+
+ decrypted io.ReadCloser
+}
+
+// A PromptFunction is used as a callback by functions that may need to decrypt
+// a private key, or prompt for a passphrase. It is called with a list of
+// acceptable, encrypted private keys and a boolean that indicates whether a
+// passphrase is usable. It should either decrypt a private key or return a
+// passphrase to try. If the decrypted private key or given passphrase isn't
+// correct, the function will be called again, forever. Any error returned will
+// be passed up.
+type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
+
+// A keyEnvelopePair is used to store a private key with the envelope that
+// contains a symmetric key, encrypted with that key.
+type keyEnvelopePair struct {
+ key Key
+ encryptedKey *packet.EncryptedKey
+}
+
+// ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
+// The given KeyRing should contain both public keys (for signature
+// verification) and, possibly encrypted, private keys for decrypting.
+// If config is nil, sensible defaults will be used.
+func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
+ var p packet.Packet
+
+ var symKeys []*packet.SymmetricKeyEncrypted
+ var pubKeys []keyEnvelopePair
+ // Integrity protected encrypted packet: SymmetricallyEncrypted or AEADEncrypted
+ var edp packet.EncryptedDataPacket
+
+ packets := packet.NewReader(r)
+ md = new(MessageDetails)
+ md.IsEncrypted = true
+
+ // The message, if encrypted, starts with a number of packets
+ // containing an encrypted decryption key. The decryption key is either
+ // encrypted to a public key, or with a passphrase. This loop
+ // collects these packets.
+ParsePackets:
+ for {
+ p, err = packets.Next()
+ if err != nil {
+ return nil, err
+ }
+ switch p := p.(type) {
+ case *packet.SymmetricKeyEncrypted:
+ // This packet contains the decryption key encrypted with a passphrase.
+ md.IsSymmetricallyEncrypted = true
+ symKeys = append(symKeys, p)
+ case *packet.EncryptedKey:
+ // This packet contains the decryption key encrypted to a public key.
+ md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
+ switch p.Algo {
+ case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal, packet.PubKeyAlgoECDH:
+ break
+ default:
+ continue
+ }
+ if keyring != nil {
+ var keys []Key
+ if p.KeyId == 0 {
+ keys = keyring.DecryptionKeys()
+ } else {
+ keys = keyring.KeysById(p.KeyId)
+ }
+ for _, k := range keys {
+ pubKeys = append(pubKeys, keyEnvelopePair{k, p})
+ }
+ }
+ case *packet.SymmetricallyEncrypted:
+ if !p.IntegrityProtected && !config.AllowUnauthenticatedMessages() {
+ return nil, errors.UnsupportedError("message is not integrity protected")
+ }
+ edp = p
+ break ParsePackets
+ case *packet.AEADEncrypted:
+ edp = p
+ break ParsePackets
+ case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
+ // This message isn't encrypted.
+ if len(symKeys) != 0 || len(pubKeys) != 0 {
+ return nil, errors.StructuralError("key material not followed by encrypted message")
+ }
+ packets.Unread(p)
+ return readSignedMessage(packets, nil, keyring, config)
+ }
+ }
+
+ var candidates []Key
+ var decrypted io.ReadCloser
+
+ // Now that we have the list of encrypted keys we need to decrypt at
+ // least one of them or, if we cannot, we need to call the prompt
+ // function so that it can decrypt a key or give us a passphrase.
+FindKey:
+ for {
+ // See if any of the keys already have a private key available
+ candidates = candidates[:0]
+ candidateFingerprints := make(map[string]bool)
+
+ for _, pk := range pubKeys {
+ if pk.key.PrivateKey == nil {
+ continue
+ }
+ if !pk.key.PrivateKey.Encrypted {
+ if len(pk.encryptedKey.Key) == 0 {
+ errDec := pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
+ if errDec != nil {
+ continue
+ }
+ }
+ // Try to decrypt symmetrically encrypted
+ decrypted, err = edp.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
+ if err != nil && err != errors.ErrKeyIncorrect {
+ return nil, err
+ }
+ if decrypted != nil {
+ md.DecryptedWith = pk.key
+ break FindKey
+ }
+ } else {
+ fpr := string(pk.key.PublicKey.Fingerprint[:])
+ if v := candidateFingerprints[fpr]; v {
+ continue
+ }
+ candidates = append(candidates, pk.key)
+ candidateFingerprints[fpr] = true
+ }
+ }
+
+ if len(candidates) == 0 && len(symKeys) == 0 {
+ return nil, errors.ErrKeyIncorrect
+ }
+
+ if prompt == nil {
+ return nil, errors.ErrKeyIncorrect
+ }
+
+ passphrase, err := prompt(candidates, len(symKeys) != 0)
+ if err != nil {
+ return nil, err
+ }
+
+ // Try the symmetric passphrase first
+ if len(symKeys) != 0 && passphrase != nil {
+ for _, s := range symKeys {
+ key, cipherFunc, err := s.Decrypt(passphrase)
+ // In v4, on wrong passphrase, session key decryption is very likely to result in an invalid cipherFunc:
+ // only for < 5% of cases we will proceed to decrypt the data
+ if err == nil {
+ decrypted, err = edp.Decrypt(cipherFunc, key)
+ if err != nil {
+ return nil, err
+ }
+ if decrypted != nil {
+ break FindKey
+ }
+ }
+ }
+ }
+ }
+
+ md.decrypted = decrypted
+ if err := packets.Push(decrypted); err != nil {
+ return nil, err
+ }
+ mdFinal, sensitiveParsingErr := readSignedMessage(packets, md, keyring, config)
+ if sensitiveParsingErr != nil {
+ return nil, errors.StructuralError("parsing error")
+ }
+ return mdFinal, nil
+}
+
+// readSignedMessage reads a possibly signed message if mdin is non-zero then
+// that structure is updated and returned. Otherwise a fresh MessageDetails is
+// used.
+func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing, config *packet.Config) (md *MessageDetails, err error) {
+ if mdin == nil {
+ mdin = new(MessageDetails)
+ }
+ md = mdin
+
+ var p packet.Packet
+ var h hash.Hash
+ var wrappedHash hash.Hash
+ var prevLast bool
+FindLiteralData:
+ for {
+ p, err = packets.Next()
+ if err != nil {
+ return nil, err
+ }
+ switch p := p.(type) {
+ case *packet.Compressed:
+ if err := packets.Push(p.Body); err != nil {
+ return nil, err
+ }
+ case *packet.OnePassSignature:
+ if prevLast {
+ return nil, errors.UnsupportedError("nested signature packets")
+ }
+
+ if p.IsLast {
+ prevLast = true
+ }
+
+ h, wrappedHash, err = hashForSignature(p.Hash, p.SigType)
+ if err != nil {
+ md.SignatureError = err
+ }
+
+ md.IsSigned = true
+ md.SignedByKeyId = p.KeyId
+ if keyring != nil {
+ keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign)
+ if len(keys) > 0 {
+ md.SignedBy = &keys[0]
+ }
+ }
+ case *packet.LiteralData:
+ md.LiteralData = p
+ break FindLiteralData
+ }
+ }
+
+ if md.IsSigned && md.SignatureError == nil {
+ md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md, config}
+ } else if md.decrypted != nil {
+ md.UnverifiedBody = checkReader{md}
+ } else {
+ md.UnverifiedBody = md.LiteralData.Body
+ }
+
+ return md, nil
+}
+
+// hashForSignature returns a pair of hashes that can be used to verify a
+// signature. The signature may specify that the contents of the signed message
+// should be preprocessed (i.e. to normalize line endings). Thus this function
+// returns two hashes. The second should be used to hash the message itself and
+// performs any needed preprocessing.
+func hashForSignature(hashFunc crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
+ if _, ok := algorithm.HashToHashIdWithSha1(hashFunc); !ok {
+ return nil, nil, errors.UnsupportedError("unsupported hash function")
+ }
+ if !hashFunc.Available() {
+ return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashFunc)))
+ }
+ h := hashFunc.New()
+
+ switch sigType {
+ case packet.SigTypeBinary:
+ return h, h, nil
+ case packet.SigTypeText:
+ return h, NewCanonicalTextHash(h), nil
+ }
+
+ return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
+}
+
+// checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
+// it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger
+// MDC checks.
+type checkReader struct {
+ md *MessageDetails
+}
+
+func (cr checkReader) Read(buf []byte) (int, error) {
+ n, sensitiveParsingError := cr.md.LiteralData.Body.Read(buf)
+ if sensitiveParsingError == io.EOF {
+ mdcErr := cr.md.decrypted.Close()
+ if mdcErr != nil {
+ return n, mdcErr
+ }
+ return n, io.EOF
+ }
+
+ if sensitiveParsingError != nil {
+ return n, errors.StructuralError("parsing error")
+ }
+
+ return n, nil
+}
+
+// signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes
+// the data as it is read. When it sees an EOF from the underlying io.Reader
+// it parses and checks a trailing Signature packet and triggers any MDC checks.
+type signatureCheckReader struct {
+ packets *packet.Reader
+ h, wrappedHash hash.Hash
+ md *MessageDetails
+ config *packet.Config
+}
+
+func (scr *signatureCheckReader) Read(buf []byte) (int, error) {
+ n, sensitiveParsingError := scr.md.LiteralData.Body.Read(buf)
+
+ // Hash only if required
+ if scr.md.SignedBy != nil {
+ scr.wrappedHash.Write(buf[:n])
+ }
+
+ if sensitiveParsingError == io.EOF {
+ var p packet.Packet
+ var readError error
+ var sig *packet.Signature
+
+ p, readError = scr.packets.Next()
+ for readError == nil {
+ var ok bool
+ if sig, ok = p.(*packet.Signature); ok {
+ if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
+ sig.Metadata = scr.md.LiteralData
+ }
+
+ // If signature KeyID matches
+ if scr.md.SignedBy != nil && *sig.IssuerKeyId == scr.md.SignedByKeyId {
+ key := scr.md.SignedBy
+ signatureError := key.PublicKey.VerifySignature(scr.h, sig)
+ if signatureError == nil {
+ signatureError = checkSignatureDetails(key, sig, scr.config)
+ }
+ scr.md.Signature = sig
+ scr.md.SignatureError = signatureError
+ } else {
+ scr.md.UnverifiedSignatures = append(scr.md.UnverifiedSignatures, sig)
+ }
+ }
+
+ p, readError = scr.packets.Next()
+ }
+
+ if scr.md.SignedBy != nil && scr.md.Signature == nil {
+ if scr.md.UnverifiedSignatures == nil {
+ scr.md.SignatureError = errors.StructuralError("LiteralData not followed by signature")
+ } else {
+ scr.md.SignatureError = errors.StructuralError("No matching signature found")
+ }
+ }
+
+ // The SymmetricallyEncrypted packet, if any, might have an
+ // unsigned hash of its own. In order to check this we need to
+ // close that Reader.
+ if scr.md.decrypted != nil {
+ mdcErr := scr.md.decrypted.Close()
+ if mdcErr != nil {
+ return n, mdcErr
+ }
+ }
+ return n, io.EOF
+ }
+
+ if sensitiveParsingError != nil {
+ return n, errors.StructuralError("parsing error")
+ }
+
+ return n, nil
+}
+
+// VerifyDetachedSignature takes a signed file and a detached signature and
+// returns the signature packet and the entity the signature was signed by,
+// if any, and a possible signature verification error.
+// If the signer isn't known, ErrUnknownIssuer is returned.
+func VerifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
+ var expectedHashes []crypto.Hash
+ return verifyDetachedSignature(keyring, signed, signature, expectedHashes, config)
+}
+
+// VerifyDetachedSignatureAndHash performs the same actions as
+// VerifyDetachedSignature and checks that the expected hash functions were used.
+func VerifyDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
+ return verifyDetachedSignature(keyring, signed, signature, expectedHashes, config)
+}
+
+// CheckDetachedSignature takes a signed file and a detached signature and
+// returns the entity the signature was signed by, if any, and a possible
+// signature verification error. If the signer isn't known,
+// ErrUnknownIssuer is returned.
+func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) {
+ var expectedHashes []crypto.Hash
+ return CheckDetachedSignatureAndHash(keyring, signed, signature, expectedHashes, config)
+}
+
+// CheckDetachedSignatureAndHash performs the same actions as
+// CheckDetachedSignature and checks that the expected hash functions were used.
+func CheckDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (signer *Entity, err error) {
+ _, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, config)
+ return
+}
+
+func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
+ var issuerKeyId uint64
+ var hashFunc crypto.Hash
+ var sigType packet.SignatureType
+ var keys []Key
+ var p packet.Packet
+
+ expectedHashesLen := len(expectedHashes)
+ packets := packet.NewReader(signature)
+ for {
+ p, err = packets.Next()
+ if err == io.EOF {
+ return nil, nil, errors.ErrUnknownIssuer
+ }
+ if err != nil {
+ return nil, nil, err
+ }
+
+ var ok bool
+ sig, ok = p.(*packet.Signature)
+ if !ok {
+ return nil, nil, errors.StructuralError("non signature packet found")
+ }
+ if sig.IssuerKeyId == nil {
+ return nil, nil, errors.StructuralError("signature doesn't have an issuer")
+ }
+ issuerKeyId = *sig.IssuerKeyId
+ hashFunc = sig.Hash
+ sigType = sig.SigType
+
+ for i, expectedHash := range expectedHashes {
+ if hashFunc == expectedHash {
+ break
+ }
+ if i+1 == expectedHashesLen {
+ return nil, nil, errors.StructuralError("hash algorithm mismatch with cleartext message headers")
+ }
+ }
+
+ keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign)
+ if len(keys) > 0 {
+ break
+ }
+ }
+
+ if len(keys) == 0 {
+ panic("unreachable")
+ }
+
+ h, wrappedHash, err := hashForSignature(hashFunc, sigType)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF {
+ return nil, nil, err
+ }
+
+ for _, key := range keys {
+ err = key.PublicKey.VerifySignature(h, sig)
+ if err == nil {
+ return sig, key.Entity, checkSignatureDetails(&key, sig, config)
+ }
+ }
+
+ return nil, nil, err
+}
+
+// CheckArmoredDetachedSignature performs the same actions as
+// CheckDetachedSignature but expects the signature to be armored.
+func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) {
+ body, err := readArmored(signature, SignatureType)
+ if err != nil {
+ return
+ }
+
+ return CheckDetachedSignature(keyring, signed, body, config)
+}
+
+// checkSignatureDetails returns an error if:
+// - The signature (or one of the binding signatures mentioned below)
+// has a unknown critical notation data subpacket
+// - The primary key of the signing entity is revoked
+// - The primary identity is revoked
+// - The signature is expired
+// - The primary key of the signing entity is expired according to the
+// primary identity binding signature
+//
+// ... or, if the signature was signed by a subkey and:
+// - The signing subkey is revoked
+// - The signing subkey is expired according to the subkey binding signature
+// - The signing subkey binding signature is expired
+// - The signing subkey cross-signature is expired
+//
+// NOTE: The order of these checks is important, as the caller may choose to
+// ignore ErrSignatureExpired or ErrKeyExpired errors, but should never
+// ignore any other errors.
+//
+// TODO: Also return an error if:
+// - The primary key is expired according to a direct-key signature
+// - (For V5 keys only:) The direct-key signature (exists and) is expired
+func checkSignatureDetails(key *Key, signature *packet.Signature, config *packet.Config) error {
+ now := config.Now()
+ primaryIdentity := key.Entity.PrimaryIdentity()
+ signedBySubKey := key.PublicKey != key.Entity.PrimaryKey
+ sigsToCheck := []*packet.Signature{signature, primaryIdentity.SelfSignature}
+ if signedBySubKey {
+ sigsToCheck = append(sigsToCheck, key.SelfSignature, key.SelfSignature.EmbeddedSignature)
+ }
+ for _, sig := range sigsToCheck {
+ for _, notation := range sig.Notations {
+ if notation.IsCritical && !config.KnownNotation(notation.Name) {
+ return errors.SignatureError("unknown critical notation: " + notation.Name)
+ }
+ }
+ }
+ if key.Entity.Revoked(now) || // primary key is revoked
+ (signedBySubKey && key.Revoked(now)) || // subkey is revoked
+ primaryIdentity.Revoked(now) { // primary identity is revoked
+ return errors.ErrKeyRevoked
+ }
+ if key.Entity.PrimaryKey.KeyExpired(primaryIdentity.SelfSignature, now) { // primary key is expired
+ return errors.ErrKeyExpired
+ }
+ if signedBySubKey {
+ if key.PublicKey.KeyExpired(key.SelfSignature, now) { // subkey is expired
+ return errors.ErrKeyExpired
+ }
+ }
+ for _, sig := range sigsToCheck {
+ if sig.SigExpired(now) { // any of the relevant signatures are expired
+ return errors.ErrSignatureExpired
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go
new file mode 100644
index 00000000..db6dad5c
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go
@@ -0,0 +1,274 @@
+package openpgp
+
+const testKey1KeyId uint64 = 0xA34D7E18C20C31BB
+const testKey3KeyId uint64 = 0x338934250CCC0360
+const testKeyP256KeyId uint64 = 0xd44a2c495918513e
+
+const signedInput = "Signed message\nline 2\nline 3\n"
+const signedTextInput = "Signed message\r\nline 2\r\nline 3\r\n"
+
+const recipientUnspecifiedHex = "848c0300000000000000000103ff62d4d578d03cf40c3da998dfe216c074fa6ddec5e31c197c9666ba292830d91d18716a80f699f9d897389a90e6d62d0238f5f07a5248073c0f24920e4bc4a30c2d17ee4e0cae7c3d4aaa4e8dced50e3010a80ee692175fa0385f62ecca4b56ee6e9980aa3ec51b61b077096ac9e800edaf161268593eedb6cc7027ff5cb32745d250010d407a6221ae22ef18469b444f2822478c4d190b24d36371a95cb40087cdd42d9399c3d06a53c0673349bfb607927f20d1e122bde1e2bf3aa6cae6edf489629bcaa0689539ae3b718914d88ededc3b"
+
+const detachedSignatureHex = "889c04000102000605024d449cd1000a0910a34d7e18c20c31bb167603ff57718d09f28a519fdc7b5a68b6a3336da04df85e38c5cd5d5bd2092fa4629848a33d85b1729402a2aab39c3ac19f9d573f773cc62c264dc924c067a79dfd8a863ae06c7c8686120760749f5fd9b1e03a64d20a7df3446ddc8f0aeadeaeba7cbaee5c1e366d65b6a0c6cc749bcb912d2f15013f812795c2e29eb7f7b77f39ce77"
+
+const detachedSignatureTextHex = "889c04010102000605024d449d21000a0910a34d7e18c20c31bbc8c60400a24fbef7342603a41cb1165767bd18985d015fb72fe05db42db36cfb2f1d455967f1e491194fbf6cf88146222b23bf6ffbd50d17598d976a0417d3192ff9cc0034fd00f287b02e90418bbefe609484b09231e4e7a5f3562e199bf39909ab5276c4d37382fe088f6b5c3426fc1052865da8b3ab158672d58b6264b10823dc4b39"
+
+const detachedSignatureDSAHex = "884604001102000605024d6c4eac000a0910338934250ccc0360f18d00a087d743d6405ed7b87755476629600b8b694a39e900a0abff8126f46faf1547c1743c37b21b4ea15b8f83"
+
+const detachedSignatureP256Hex = "885e0400130a0006050256e5bb00000a0910d44a2c495918513edef001009841a4f792beb0befccb35c8838a6a87d9b936beaa86db6745ddc7b045eee0cf00fd1ac1f78306b17e965935dd3f8bae4587a76587e4af231efe19cc4011a8434817"
+
+// The plaintext is https://www.gutenberg.org/cache/epub/1080/pg1080.txt
+const modestProposalSha512 = "lbbrB1+WP3T9AaC9OQqBdOcCjgeEQadlulXsNPgVx0tyqPzDHwUugZ2gE7V0ESKAw6kAVfgkcuvfgxAAGaeHtw=="
+
+const testKeys1And2Hex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001b41054657374204b6579203120285253412988b804130102002205024d3c5c10021b03060b090807030206150802090a0b0416020301021e01021780000a0910a34d7e18c20c31bbb5b304009cc45fe610b641a2c146331be94dade0a396e73ca725e1b25c21708d9cab46ecca5ccebc23055879df8f99eea39b377962a400f2ebdc36a7c99c333d74aeba346315137c3ff9d0a09b0273299090343048afb8107cf94cbd1400e3026f0ccac7ecebbc4d78588eb3e478fe2754d3ca664bcf3eac96ca4a6b0c8d7df5102f60f6b0020003b88d044d3c5c10010400b201df61d67487301f11879d514f4248ade90c8f68c7af1284c161098de4c28c2850f1ec7b8e30f959793e571542ffc6532189409cb51c3d30dad78c4ad5165eda18b20d9826d8707d0f742e2ab492103a85bbd9ddf4f5720f6de7064feb0d39ee002219765bb07bcfb8b877f47abe270ddeda4f676108cecb6b9bb2ad484a4f0011010001889f04180102000905024d3c5c10021b0c000a0910a34d7e18c20c31bb1a03040085c8d62e16d05dc4e9dad64953c8a2eed8b6c12f92b1575eeaa6dcf7be9473dd5b24b37b6dffbb4e7c99ed1bd3cb11634be19b3e6e207bed7505c7ca111ccf47cb323bf1f8851eb6360e8034cbff8dd149993c959de89f8f77f38e7e98b8e3076323aa719328e2b408db5ec0d03936efd57422ba04f925cdc7b4c1af7590e40ab0020003988d044d3c5c33010400b488c3e5f83f4d561f317817538d9d0397981e9aef1321ca68ebfae1cf8b7d388e19f4b5a24a82e2fbbf1c6c26557a6c5845307a03d815756f564ac7325b02bc83e87d5480a8fae848f07cb891f2d51ce7df83dcafdc12324517c86d472cc0ee10d47a68fd1d9ae49a6c19bbd36d82af597a0d88cc9c49de9df4e696fc1f0b5d0011010001b42754657374204b6579203220285253412c20656e637279707465642070726976617465206b65792988b804130102002205024d3c5c33021b03060b090807030206150802090a0b0416020301021e01021780000a0910d4984f961e35246b98940400908a73b6a6169f700434f076c6c79015a49bee37130eaf23aaa3cfa9ce60bfe4acaa7bc95f1146ada5867e0079babb38804891f4f0b8ebca57a86b249dee786161a755b7a342e68ccf3f78ed6440a93a6626beb9a37aa66afcd4f888790cb4bb46d94a4ae3eb3d7d3e6b00f6bfec940303e89ec5b32a1eaaacce66497d539328b0020003b88d044d3c5c33010400a4e913f9442abcc7f1804ccab27d2f787ffa592077ca935a8bb23165bd8d57576acac647cc596b2c3f814518cc8c82953c7a4478f32e0cf645630a5ba38d9618ef2bc3add69d459ae3dece5cab778938d988239f8c5ae437807075e06c828019959c644ff05ef6a5a1dab72227c98e3a040b0cf219026640698d7a13d8538a570011010001889f04180102000905024d3c5c33021b0c000a0910d4984f961e35246b26c703ff7ee29ef53bc1ae1ead533c408fa136db508434e233d6e62be621e031e5940bbd4c08142aed0f82217e7c3e1ec8de574bc06ccf3c36633be41ad78a9eacd209f861cae7b064100758545cc9dd83db71806dc1cfd5fb9ae5c7474bba0c19c44034ae61bae5eca379383339dece94ff56ff7aa44a582f3e5c38f45763af577c0934b0020003"
+
+const testKeys1And2PrivateHex = "9501d8044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd00110100010003ff4d91393b9a8e3430b14d6209df42f98dc927425b881f1209f319220841273a802a97c7bdb8b3a7740b3ab5866c4d1d308ad0d3a79bd1e883aacf1ac92dfe720285d10d08752a7efe3c609b1d00f17f2805b217be53999a7da7e493bfc3e9618fd17018991b8128aea70a05dbce30e4fbe626aa45775fa255dd9177aabf4df7cf0200c1ded12566e4bc2bb590455e5becfb2e2c9796482270a943343a7835de41080582c2be3caf5981aa838140e97afa40ad652a0b544f83eb1833b0957dce26e47b0200eacd6046741e9ce2ec5beb6fb5e6335457844fb09477f83b050a96be7da043e17f3a9523567ed40e7a521f818813a8b8a72209f1442844843ccc7eb9805442570200bdafe0438d97ac36e773c7162028d65844c4d463e2420aa2228c6e50dc2743c3d6c72d0d782a5173fe7be2169c8a9f4ef8a7cf3e37165e8c61b89c346cdc6c1799d2b41054657374204b6579203120285253412988b804130102002205024d3c5c10021b03060b090807030206150802090a0b0416020301021e01021780000a0910a34d7e18c20c31bbb5b304009cc45fe610b641a2c146331be94dade0a396e73ca725e1b25c21708d9cab46ecca5ccebc23055879df8f99eea39b377962a400f2ebdc36a7c99c333d74aeba346315137c3ff9d0a09b0273299090343048afb8107cf94cbd1400e3026f0ccac7ecebbc4d78588eb3e478fe2754d3ca664bcf3eac96ca4a6b0c8d7df5102f60f6b00200009d01d8044d3c5c10010400b201df61d67487301f11879d514f4248ade90c8f68c7af1284c161098de4c28c2850f1ec7b8e30f959793e571542ffc6532189409cb51c3d30dad78c4ad5165eda18b20d9826d8707d0f742e2ab492103a85bbd9ddf4f5720f6de7064feb0d39ee002219765bb07bcfb8b877f47abe270ddeda4f676108cecb6b9bb2ad484a4f00110100010003fd17a7490c22a79c59281fb7b20f5e6553ec0c1637ae382e8adaea295f50241037f8997cf42c1ce26417e015091451b15424b2c59eb8d4161b0975630408e394d3b00f88d4b4e18e2cc85e8251d4753a27c639c83f5ad4a571c4f19d7cd460b9b73c25ade730c99df09637bd173d8e3e981ac64432078263bb6dc30d3e974150dd0200d0ee05be3d4604d2146fb0457f31ba17c057560785aa804e8ca5530a7cd81d3440d0f4ba6851efcfd3954b7e68908fc0ba47f7ac37bf559c6c168b70d3a7c8cd0200da1c677c4bce06a068070f2b3733b0a714e88d62aa3f9a26c6f5216d48d5c2b5624144f3807c0df30be66b3268eeeca4df1fbded58faf49fc95dc3c35f134f8b01fd1396b6c0fc1b6c4f0eb8f5e44b8eace1e6073e20d0b8bc5385f86f1cf3f050f66af789f3ef1fc107b7f4421e19e0349c730c68f0a226981f4e889054fdb4dc149e8e889f04180102000905024d3c5c10021b0c000a0910a34d7e18c20c31bb1a03040085c8d62e16d05dc4e9dad64953c8a2eed8b6c12f92b1575eeaa6dcf7be9473dd5b24b37b6dffbb4e7c99ed1bd3cb11634be19b3e6e207bed7505c7ca111ccf47cb323bf1f8851eb6360e8034cbff8dd149993c959de89f8f77f38e7e98b8e3076323aa719328e2b408db5ec0d03936efd57422ba04f925cdc7b4c1af7590e40ab00200009501fe044d3c5c33010400b488c3e5f83f4d561f317817538d9d0397981e9aef1321ca68ebfae1cf8b7d388e19f4b5a24a82e2fbbf1c6c26557a6c5845307a03d815756f564ac7325b02bc83e87d5480a8fae848f07cb891f2d51ce7df83dcafdc12324517c86d472cc0ee10d47a68fd1d9ae49a6c19bbd36d82af597a0d88cc9c49de9df4e696fc1f0b5d0011010001fe030302e9030f3c783e14856063f16938530e148bc57a7aa3f3e4f90df9dceccdc779bc0835e1ad3d006e4a8d7b36d08b8e0de5a0d947254ecfbd22037e6572b426bcfdc517796b224b0036ff90bc574b5509bede85512f2eefb520fb4b02aa523ba739bff424a6fe81c5041f253f8d757e69a503d3563a104d0d49e9e890b9d0c26f96b55b743883b472caa7050c4acfd4a21f875bdf1258d88bd61224d303dc9df77f743137d51e6d5246b88c406780528fd9a3e15bab5452e5b93970d9dcc79f48b38651b9f15bfbcf6da452837e9cc70683d1bdca94507870f743e4ad902005812488dd342f836e72869afd00ce1850eea4cfa53ce10e3608e13d3c149394ee3cbd0e23d018fcbcb6e2ec5a1a22972d1d462ca05355d0d290dd2751e550d5efb38c6c89686344df64852bf4ff86638708f644e8ec6bd4af9b50d8541cb91891a431326ab2e332faa7ae86cfb6e0540aa63160c1e5cdd5a4add518b303fff0a20117c6bc77f7cfbaf36b04c865c6c2b42754657374204b6579203220285253412c20656e637279707465642070726976617465206b65792988b804130102002205024d3c5c33021b03060b090807030206150802090a0b0416020301021e01021780000a0910d4984f961e35246b98940400908a73b6a6169f700434f076c6c79015a49bee37130eaf23aaa3cfa9ce60bfe4acaa7bc95f1146ada5867e0079babb38804891f4f0b8ebca57a86b249dee786161a755b7a342e68ccf3f78ed6440a93a6626beb9a37aa66afcd4f888790cb4bb46d94a4ae3eb3d7d3e6b00f6bfec940303e89ec5b32a1eaaacce66497d539328b00200009d01fe044d3c5c33010400a4e913f9442abcc7f1804ccab27d2f787ffa592077ca935a8bb23165bd8d57576acac647cc596b2c3f814518cc8c82953c7a4478f32e0cf645630a5ba38d9618ef2bc3add69d459ae3dece5cab778938d988239f8c5ae437807075e06c828019959c644ff05ef6a5a1dab72227c98e3a040b0cf219026640698d7a13d8538a570011010001fe030302e9030f3c783e148560f936097339ae381d63116efcf802ff8b1c9360767db5219cc987375702a4123fd8657d3e22700f23f95020d1b261eda5257e9a72f9a918e8ef22dd5b3323ae03bbc1923dd224db988cadc16acc04b120a9f8b7e84da9716c53e0334d7b66586ddb9014df604b41be1e960dcfcbc96f4ed150a1a0dd070b9eb14276b9b6be413a769a75b519a53d3ecc0c220e85cd91ca354d57e7344517e64b43b6e29823cbd87eae26e2b2e78e6dedfbb76e3e9f77bcb844f9a8932eb3db2c3f9e44316e6f5d60e9e2a56e46b72abe6b06dc9a31cc63f10023d1f5e12d2a3ee93b675c96f504af0001220991c88db759e231b3320dcedf814dcf723fd9857e3d72d66a0f2af26950b915abdf56c1596f46a325bf17ad4810d3535fb02a259b247ac3dbd4cc3ecf9c51b6c07cebb009c1506fba0a89321ec8683e3fd009a6e551d50243e2d5092fefb3321083a4bad91320dc624bd6b5dddf93553e3d53924c05bfebec1fb4bd47e89a1a889f04180102000905024d3c5c33021b0c000a0910d4984f961e35246b26c703ff7ee29ef53bc1ae1ead533c408fa136db508434e233d6e62be621e031e5940bbd4c08142aed0f82217e7c3e1ec8de574bc06ccf3c36633be41ad78a9eacd209f861cae7b064100758545cc9dd83db71806dc1cfd5fb9ae5c7474bba0c19c44034ae61bae5eca379383339dece94ff56ff7aa44a582f3e5c38f45763af577c0934b0020000"
+
+const dsaElGamalTestKeysHex = "9501e1044dfcb16a110400aa3e5c1a1f43dd28c2ffae8abf5cfce555ee874134d8ba0a0f7b868ce2214beddc74e5e1e21ded354a95d18acdaf69e5e342371a71fbb9093162e0c5f3427de413a7f2c157d83f5cd2f9d791256dc4f6f0e13f13c3302af27f2384075ab3021dff7a050e14854bbde0a1094174855fc02f0bae8e00a340d94a1f22b32e48485700a0cec672ac21258fb95f61de2ce1af74b2c4fa3e6703ff698edc9be22c02ae4d916e4fa223f819d46582c0516235848a77b577ea49018dcd5e9e15cff9dbb4663a1ae6dd7580fa40946d40c05f72814b0f88481207e6c0832c3bded4853ebba0a7e3bd8e8c66df33d5a537cd4acf946d1080e7a3dcea679cb2b11a72a33a2b6a9dc85f466ad2ddf4c3db6283fa645343286971e3dd700703fc0c4e290d45767f370831a90187e74e9972aae5bff488eeff7d620af0362bfb95c1a6c3413ab5d15a2e4139e5d07a54d72583914661ed6a87cce810be28a0aa8879a2dd39e52fb6fe800f4f181ac7e328f740cde3d09a05cecf9483e4cca4253e60d4429ffd679d9996a520012aad119878c941e3cf151459873bdfc2a9563472fe0303027a728f9feb3b864260a1babe83925ce794710cfd642ee4ae0e5b9d74cee49e9c67b6cd0ea5dfbb582132195a121356a1513e1bca73e5b80c58c7ccb4164453412f456c47616d616c2054657374204b65792031886204131102002205024dfcb16a021b03060b090807030206150802090a0b0416020301021e01021780000a091033af447ccd759b09fadd00a0b8fd6f5a790bad7e9f2dbb7632046dc4493588db009c087c6a9ba9f7f49fab221587a74788c00db4889ab00200009d0157044dfcb16a1004008dec3f9291205255ccff8c532318133a6840739dd68b03ba942676f9038612071447bf07d00d559c5c0875724ea16a4c774f80d8338b55fca691a0522e530e604215b467bbc9ccfd483a1da99d7bc2648b4318fdbd27766fc8bfad3fddb37c62b8ae7ccfe9577e9b8d1e77c1d417ed2c2ef02d52f4da11600d85d3229607943700030503ff506c94c87c8cab778e963b76cf63770f0a79bf48fb49d3b4e52234620fc9f7657f9f8d56c96a2b7c7826ae6b57ebb2221a3fe154b03b6637cea7e6d98e3e45d87cf8dc432f723d3d71f89c5192ac8d7290684d2c25ce55846a80c9a7823f6acd9bb29fa6cd71f20bc90eccfca20451d0c976e460e672b000df49466408d527affe0303027a728f9feb3b864260abd761730327bca2aaa4ea0525c175e92bf240682a0e83b226f97ecb2e935b62c9a133858ce31b271fa8eb41f6a1b3cd72a63025ce1a75ee4180dcc284884904181102000905024dfcb16a021b0c000a091033af447ccd759b09dd0b009e3c3e7296092c81bee5a19929462caaf2fff3ae26009e218c437a2340e7ea628149af1ec98ec091a43992b00200009501e1044dfcb1be1104009f61faa61aa43df75d128cbe53de528c4aec49ce9360c992e70c77072ad5623de0a3a6212771b66b39a30dad6781799e92608316900518ec01184a85d872365b7d2ba4bacfb5882ea3c2473d3750dc6178cc1cf82147fb58caa28b28e9f12f6d1efcb0534abed644156c91cca4ab78834268495160b2400bc422beb37d237c2300a0cac94911b6d493bda1e1fbc6feeca7cb7421d34b03fe22cec6ccb39675bb7b94a335c2b7be888fd3906a1125f33301d8aa6ec6ee6878f46f73961c8d57a3e9544d8ef2a2cbfd4d52da665b1266928cfe4cb347a58c412815f3b2d2369dec04b41ac9a71cc9547426d5ab941cccf3b18575637ccfb42df1a802df3cfe0a999f9e7109331170e3a221991bf868543960f8c816c28097e503fe319db10fb98049f3a57d7c80c420da66d56f3644371631fad3f0ff4040a19a4fedc2d07727a1b27576f75a4d28c47d8246f27071e12d7a8de62aad216ddbae6aa02efd6b8a3e2818cda48526549791ab277e447b3a36c57cefe9b592f5eab73959743fcc8e83cbefec03a329b55018b53eec196765ae40ef9e20521a603c551efe0303020950d53a146bf9c66034d00c23130cce95576a2ff78016ca471276e8227fb30b1ffbd92e61804fb0c3eff9e30b1a826ee8f3e4730b4d86273ca977b4164453412f456c47616d616c2054657374204b65792032886204131102002205024dfcb1be021b03060b090807030206150802090a0b0416020301021e01021780000a0910a86bf526325b21b22bd9009e34511620415c974750a20df5cb56b182f3b48e6600a0a9466cb1a1305a84953445f77d461593f1d42bc1b00200009d0157044dfcb1be1004009565a951da1ee87119d600c077198f1c1bceb0f7aa54552489298e41ff788fa8f0d43a69871f0f6f77ebdfb14a4260cf9fbeb65d5844b4272a1904dd95136d06c3da745dc46327dd44a0f16f60135914368c8039a34033862261806bb2c5ce1152e2840254697872c85441ccb7321431d75a747a4bfb1d2c66362b51ce76311700030503fc0ea76601c196768070b7365a200e6ddb09307f262d5f39eec467b5f5784e22abdf1aa49226f59ab37cb49969d8f5230ea65caf56015abda62604544ed526c5c522bf92bed178a078789f6c807b6d34885688024a5bed9e9f8c58d11d4b82487b44c5f470c5606806a0443b79cadb45e0f897a561a53f724e5349b9267c75ca17fe0303020950d53a146bf9c660bc5f4ce8f072465e2d2466434320c1e712272fafc20e342fe7608101580fa1a1a367e60486a7cd1246b7ef5586cf5e10b32762b710a30144f12dd17dd4884904181102000905024dfcb1be021b0c000a0910a86bf526325b21b2904c00a0b2b66b4b39ccffda1d10f3ea8d58f827e30a8b8e009f4255b2d8112a184e40cde43a34e8655ca7809370b0020000"
+
+const signedMessageHex = "a3019bc0cbccc0c4b8d8b74ee2108fe16ec6d3ca490cbe362d3f8333d3f352531472538b8b13d353b97232f352158c20943157c71c16064626063656269052062e4e01987e9b6fccff4b7df3a34c534b23e679cbec3bc0f8f6e64dfb4b55fe3f8efa9ce110ddb5cd79faf1d753c51aecfa669f7e7aa043436596cccc3359cb7dd6bbe9ecaa69e5989d9e57209571edc0b2fa7f57b9b79a64ee6e99ce1371395fee92fec2796f7b15a77c386ff668ee27f6d38f0baa6c438b561657377bf6acff3c5947befd7bf4c196252f1d6e5c524d0300"
+
+const signedTextMessageHex = "a3019bc0cbccc8c4b8d8b74ee2108fe16ec6d36a250cbece0c178233d3f352531472538b8b13d35379b97232f352158ca0b4312f57c71c1646462606365626906a062e4e019811591798ff99bf8afee860b0d8a8c2a85c3387e3bcf0bb3b17987f2bbcfab2aa526d930cbfd3d98757184df3995c9f3e7790e36e3e9779f06089d4c64e9e47dd6202cb6e9bc73c5d11bb59fbaf89d22d8dc7cf199ddf17af96e77c5f65f9bbed56f427bd8db7af37f6c9984bf9385efaf5f184f986fb3e6adb0ecfe35bbf92d16a7aa2a344fb0bc52fb7624f0200"
+
+const signedEncryptedMessageHex = "c18c032a67d68660df41c70103ff5a84c9a72f80e74ef0384c2d6a9ebfe2b09e06a8f298394f6d2abf174e40934ab0ec01fb2d0ddf21211c6fe13eb238563663b017a6b44edca552eb4736c4b7dc6ed907dd9e12a21b51b64b46f902f76fb7aaf805c1db8070574d8d0431a23e324a750f77fb72340a17a42300ee4ca8207301e95a731da229a63ab9c6b44541fbd2c11d016d810b3b3b2b38f15b5b40f0a4910332829c2062f1f7cc61f5b03677d73c54cafa1004ced41f315d46444946faae571d6f426e6dbd45d9780eb466df042005298adabf7ce0ef766dfeb94cd449c7ed0046c880339599c4711af073ce649b1e237c40b50a5536283e03bdbb7afad78bd08707715c67fb43295f905b4c479178809d429a8e167a9a8c6dfd8ab20b4edebdc38d6dec879a3202e1b752690d9bb5b0c07c5a227c79cc200e713a99251a4219d62ad5556900cf69bd384b6c8e726c7be267471d0d23af956da165af4af757246c2ebcc302b39e8ef2fccb4971b234fcda22d759ddb20e27269ee7f7fe67898a9de721bfa02ab0becaa046d00ea16cb1afc4e2eab40d0ac17121c565686e5cbd0cbdfbd9d6db5c70278b9c9db5a83176d04f61fbfbc4471d721340ede2746e5c312ded4f26787985af92b64fae3f253dbdde97f6a5e1996fd4d865599e32ff76325d3e9abe93184c02988ee89a4504356a4ef3b9b7a57cbb9637ca90af34a7676b9ef559325c3cca4e29d69fec1887f5440bb101361d744ad292a8547f22b4f22b419a42aa836169b89190f46d9560824cb2ac6e8771de8223216a5e647e132ab9eebcba89569ab339cb1c3d70fe806b31f4f4c600b4103b8d7583ebff16e43dcda551e6530f975122eb8b29"
+
+const verifiedSignatureEncryptedMessageHex = "c2b304000108000605026048f6d600210910a34d7e18c20c31bb1621045fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb9a3b0400a32ddac1af259c1b0abab0041327ea04970944401978fb647dd1cf9aba4f164e43f0d8a9389501886474bdd4a6e77f6aea945c07dfbf87743835b44cc2c39a1f9aeecfa83135abc92e18e50396f2e6a06c44e0188b0081effbfb4160d28f118d4ff73dd199a102e47cffd8c7ff2bacd83ae72b5820c021a486766dd587b5da61"
+
+const unverifiedSignatureEncryptedMessageHex = "c2b304000108000605026048f6d600210910a34d7e18c20c31bb1621045fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb9a3b0400a32ddac1af259c1b0abab0041327ea04970944401978fb647dd1cf9aba4f164e43f0d8a9389501886474bdd4a6e77f6aea945c07dfbf87743835b44cc2c39a1f9aeecfa83135abc92e18e50396f2e6a06c44e0188b0081effbfb4160d28f118d4ff73dd199a102e47cffd8c7ff2bacd83ae72b5820c021a486766dd587b5da61"
+
+const signedEncryptedMessage2Hex = "85010e03cf6a7abcd43e36731003fb057f5495b79db367e277cdbe4ab90d924ddee0c0381494112ff8c1238fb0184af35d1731573b01bc4c55ecacd2aafbe2003d36310487d1ecc9ac994f3fada7f9f7f5c3a64248ab7782906c82c6ff1303b69a84d9a9529c31ecafbcdb9ba87e05439897d87e8a2a3dec55e14df19bba7f7bd316291c002ae2efd24f83f9e3441203fc081c0c23dc3092a454ca8a082b27f631abf73aca341686982e8fbda7e0e7d863941d68f3de4a755c2964407f4b5e0477b3196b8c93d551dd23c8beef7d0f03fbb1b6066f78907faf4bf1677d8fcec72651124080e0b7feae6b476e72ab207d38d90b958759fdedfc3c6c35717c9dbfc979b3cfbbff0a76d24a5e57056bb88acbd2a901ef64bc6e4db02adc05b6250ff378de81dca18c1910ab257dff1b9771b85bb9bbe0a69f5989e6d1710a35e6dfcceb7d8fb5ccea8db3932b3d9ff3fe0d327597c68b3622aec8e3716c83a6c93f497543b459b58ba504ed6bcaa747d37d2ca746fe49ae0a6ce4a8b694234e941b5159ff8bd34b9023da2814076163b86f40eed7c9472f81b551452d5ab87004a373c0172ec87ea6ce42ccfa7dbdad66b745496c4873d8019e8c28d6b3"
+
+const signatureEncryptedMessage2Hex = "c24604001102000605024dfd0166000a091033af447ccd759b09bae600a096ec5e63ecf0a403085e10f75cc3bab327663282009f51fad9df457ed8d2b70d8a73c76e0443eac0f377"
+
+const symmetricallyEncryptedCompressedHex = "c32e040903085a357c1a7b5614ed00cc0d1d92f428162058b3f558a0fb0980d221ebac6c97d5eda4e0fe32f6e706e94dd263012d6ca1ef8c4bbd324098225e603a10c85ebf09cbf7b5aeeb5ce46381a52edc51038b76a8454483be74e6dcd1e50d5689a8ae7eceaeefed98a0023d49b22eb1f65c2aa1ef1783bb5e1995713b0457102ec3c3075fe871267ffa4b686ad5d52000d857"
+
+const dsaTestKeyHex = "9901a2044d6c49de110400cb5ce438cf9250907ac2ba5bf6547931270b89f7c4b53d9d09f4d0213a5ef2ec1f26806d3d259960f872a4a102ef1581ea3f6d6882d15134f21ef6a84de933cc34c47cc9106efe3bd84c6aec12e78523661e29bc1a61f0aab17fa58a627fd5fd33f5149153fbe8cd70edf3d963bc287ef875270ff14b5bfdd1bca4483793923b00a0fe46d76cb6e4cbdc568435cd5480af3266d610d303fe33ae8273f30a96d4d34f42fa28ce1112d425b2e3bf7ea553d526e2db6b9255e9dc7419045ce817214d1a0056dbc8d5289956a4b1b69f20f1105124096e6a438f41f2e2495923b0f34b70642607d45559595c7fe94d7fa85fc41bf7d68c1fd509ebeaa5f315f6059a446b9369c277597e4f474a9591535354c7e7f4fd98a08aa60400b130c24ff20bdfbf683313f5daebf1c9b34b3bdadfc77f2ddd72ee1fb17e56c473664bc21d66467655dd74b9005e3a2bacce446f1920cd7017231ae447b67036c9b431b8179deacd5120262d894c26bc015bffe3d827ba7087ad9b700d2ca1f6d16cc1786581e5dd065f293c31209300f9b0afcc3f7c08dd26d0a22d87580b4db41054657374204b65792033202844534129886204131102002205024d6c49de021b03060b090807030206150802090a0b0416020301021e01021780000a0910338934250ccc03607e0400a0bdb9193e8a6b96fc2dfc108ae848914b504481f100a09c4dc148cb693293a67af24dd40d2b13a9e36794"
+
+const dsaTestKeyPrivateHex = "9501bb044d6c49de110400cb5ce438cf9250907ac2ba5bf6547931270b89f7c4b53d9d09f4d0213a5ef2ec1f26806d3d259960f872a4a102ef1581ea3f6d6882d15134f21ef6a84de933cc34c47cc9106efe3bd84c6aec12e78523661e29bc1a61f0aab17fa58a627fd5fd33f5149153fbe8cd70edf3d963bc287ef875270ff14b5bfdd1bca4483793923b00a0fe46d76cb6e4cbdc568435cd5480af3266d610d303fe33ae8273f30a96d4d34f42fa28ce1112d425b2e3bf7ea553d526e2db6b9255e9dc7419045ce817214d1a0056dbc8d5289956a4b1b69f20f1105124096e6a438f41f2e2495923b0f34b70642607d45559595c7fe94d7fa85fc41bf7d68c1fd509ebeaa5f315f6059a446b9369c277597e4f474a9591535354c7e7f4fd98a08aa60400b130c24ff20bdfbf683313f5daebf1c9b34b3bdadfc77f2ddd72ee1fb17e56c473664bc21d66467655dd74b9005e3a2bacce446f1920cd7017231ae447b67036c9b431b8179deacd5120262d894c26bc015bffe3d827ba7087ad9b700d2ca1f6d16cc1786581e5dd065f293c31209300f9b0afcc3f7c08dd26d0a22d87580b4d00009f592e0619d823953577d4503061706843317e4fee083db41054657374204b65792033202844534129886204131102002205024d6c49de021b03060b090807030206150802090a0b0416020301021e01021780000a0910338934250ccc03607e0400a0bdb9193e8a6b96fc2dfc108ae848914b504481f100a09c4dc148cb693293a67af24dd40d2b13a9e36794"
+
+const p256TestKeyHex = "98520456e5b83813082a8648ce3d030107020304a2072cd6d21321266c758cc5b83fab0510f751cb8d91897cddb7047d8d6f185546e2107111b0a95cb8ef063c33245502af7a65f004d5919d93ee74eb71a66253b424502d3235362054657374204b6579203c696e76616c6964406578616d706c652e636f6d3e8879041313080021050256e5b838021b03050b09080702061508090a0b020416020301021e01021780000a0910d44a2c495918513e54e50100dfa64f97d9b47766fc1943c6314ba3f2b2a103d71ad286dc5b1efb96a345b0c80100dbc8150b54241f559da6ef4baacea6d31902b4f4b1bdc09b34bf0502334b7754b8560456e5b83812082a8648ce3d030107020304bfe3cea9cee13486f8d518aa487fecab451f25467d2bf08e58f63e5fa525d5482133e6a79299c274b068ef0be448152ad65cf11cf764348588ca4f6a0bcf22b6030108078861041813080009050256e5b838021b0c000a0910d44a2c495918513e4a4800ff49d589fa64024ad30be363a032e3a0e0e6f5db56ba4c73db850518bf0121b8f20100fd78e065f4c70ea5be9df319ea67e493b936fc78da834a71828043d3154af56e"
+
+const p256TestKeyPrivateHex = "94a50456e5b83813082a8648ce3d030107020304a2072cd6d21321266c758cc5b83fab0510f751cb8d91897cddb7047d8d6f185546e2107111b0a95cb8ef063c33245502af7a65f004d5919d93ee74eb71a66253fe070302f0c2bfb0b6c30f87ee1599472b8636477eab23ced13b271886a4b50ed34c9d8436af5af5b8f88921f0efba6ef8c37c459bbb88bc1c6a13bbd25c4ce9b1e97679569ee77645d469bf4b43de637f5561b424502d3235362054657374204b6579203c696e76616c6964406578616d706c652e636f6d3e8879041313080021050256e5b838021b03050b09080702061508090a0b020416020301021e01021780000a0910d44a2c495918513e54e50100dfa64f97d9b47766fc1943c6314ba3f2b2a103d71ad286dc5b1efb96a345b0c80100dbc8150b54241f559da6ef4baacea6d31902b4f4b1bdc09b34bf0502334b77549ca90456e5b83812082a8648ce3d030107020304bfe3cea9cee13486f8d518aa487fecab451f25467d2bf08e58f63e5fa525d5482133e6a79299c274b068ef0be448152ad65cf11cf764348588ca4f6a0bcf22b603010807fe0703027510012471a603cfee2968dce19f732721ddf03e966fd133b4e3c7a685b788705cbc46fb026dc94724b830c9edbaecd2fb2c662f23169516cacd1fe423f0475c364ecc10abcabcfd4bbbda1a36a1bd8861041813080009050256e5b838021b0c000a0910d44a2c495918513e4a4800ff49d589fa64024ad30be363a032e3a0e0e6f5db56ba4c73db850518bf0121b8f20100fd78e065f4c70ea5be9df319ea67e493b936fc78da834a71828043d3154af56e"
+
+const armoredPrivateKeyBlock = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.10 (GNU/Linux)
+
+lQHYBE2rFNoBBADFwqWQIW/DSqcB4yCQqnAFTJ27qS5AnB46ccAdw3u4Greeu3Bp
+idpoHdjULy7zSKlwR1EA873dO/k/e11Ml3dlAFUinWeejWaK2ugFP6JjiieSsrKn
+vWNicdCS4HTWn0X4sjl0ZiAygw6GNhqEQ3cpLeL0g8E9hnYzJKQ0LWJa0QARAQAB
+AAP/TB81EIo2VYNmTq0pK1ZXwUpxCrvAAIG3hwKjEzHcbQznsjNvPUihZ+NZQ6+X
+0HCfPAdPkGDCLCb6NavcSW+iNnLTrdDnSI6+3BbIONqWWdRDYJhqZCkqmG6zqSfL
+IdkJgCw94taUg5BWP/AAeQrhzjChvpMQTVKQL5mnuZbUCeMCAN5qrYMP2S9iKdnk
+VANIFj7656ARKt/nf4CBzxcpHTyB8+d2CtPDKCmlJP6vL8t58Jmih+kHJMvC0dzn
+gr5f5+sCAOOe5gt9e0am7AvQWhdbHVfJU0TQJx+m2OiCJAqGTB1nvtBLHdJnfdC9
+TnXXQ6ZXibqLyBies/xeY2sCKL5qtTMCAKnX9+9d/5yQxRyrQUHt1NYhaXZnJbHx
+q4ytu0eWz+5i68IYUSK69jJ1NWPM0T6SkqpB3KCAIv68VFm9PxqG1KmhSrQIVGVz
+dCBLZXmIuAQTAQIAIgUCTasU2gIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA
+CgkQO9o98PRieSoLhgQAkLEZex02Qt7vGhZzMwuN0R22w3VwyYyjBx+fM3JFETy1
+ut4xcLJoJfIaF5ZS38UplgakHG0FQ+b49i8dMij0aZmDqGxrew1m4kBfjXw9B/v+
+eIqpODryb6cOSwyQFH0lQkXC040pjq9YqDsO5w0WYNXYKDnzRV0p4H1pweo2VDid
+AdgETasU2gEEAN46UPeWRqKHvA99arOxee38fBt2CI08iiWyI8T3J6ivtFGixSqV
+bRcPxYO/qLpVe5l84Nb3X71GfVXlc9hyv7CD6tcowL59hg1E/DC5ydI8K8iEpUmK
+/UnHdIY5h8/kqgGxkY/T/hgp5fRQgW1ZoZxLajVlMRZ8W4tFtT0DeA+JABEBAAEA
+A/0bE1jaaZKj6ndqcw86jd+QtD1SF+Cf21CWRNeLKnUds4FRRvclzTyUMuWPkUeX
+TaNNsUOFqBsf6QQ2oHUBBK4VCHffHCW4ZEX2cd6umz7mpHW6XzN4DECEzOVksXtc
+lUC1j4UB91DC/RNQqwX1IV2QLSwssVotPMPqhOi0ZLNY7wIA3n7DWKInxYZZ4K+6
+rQ+POsz6brEoRHwr8x6XlHenq1Oki855pSa1yXIARoTrSJkBtn5oI+f8AzrnN0BN
+oyeQAwIA/7E++3HDi5aweWrViiul9cd3rcsS0dEnksPhvS0ozCJiHsq/6GFmy7J8
+QSHZPteedBnZyNp5jR+H7cIfVN3KgwH/Skq4PsuPhDq5TKK6i8Pc1WW8MA6DXTdU
+nLkX7RGmMwjC0DBf7KWAlPjFaONAX3a8ndnz//fy1q7u2l9AZwrj1qa1iJ8EGAEC
+AAkFAk2rFNoCGwwACgkQO9o98PRieSo2/QP/WTzr4ioINVsvN1akKuekmEMI3LAp
+BfHwatufxxP1U+3Si/6YIk7kuPB9Hs+pRqCXzbvPRrI8NHZBmc8qIGthishdCYad
+AHcVnXjtxrULkQFGbGvhKURLvS9WnzD/m1K2zzwxzkPTzT9/Yf06O6Mal5AdugPL
+VrM0m72/jnpKo04=
+=zNCn
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const e2ePublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Charset: UTF-8
+
+xv8AAABSBAAAAAATCCqGSM49AwEHAgME1LRoXSpOxtHXDUdmuvzchyg6005qIBJ4
+sfaSxX7QgH9RV2ONUhC+WiayCNADq+UMzuR/vunSr4aQffXvuGnR383/AAAAFDxk
+Z2lsQHlhaG9vLWluYy5jb20+wv8AAACGBBATCAA4/wAAAAWCVGvAG/8AAAACiwn/
+AAAACZC2VkQCOjdvYf8AAAAFlQgJCgv/AAAAA5YBAv8AAAACngEAAE1BAP0X8veD
+24IjmI5/C6ZAfVNXxgZZFhTAACFX75jUA3oD6AEAzoSwKf1aqH6oq62qhCN/pekX
++WAsVMBhNwzLpqtCRjLO/wAAAFYEAAAAABIIKoZIzj0DAQcCAwT50ain7vXiIRv8
+B1DO3x3cE/aattZ5sHNixJzRCXi2vQIA5QmOxZ6b5jjUekNbdHG3SZi1a2Ak5mfX
+fRxC/5VGAwEIB8L/AAAAZQQYEwgAGP8AAAAFglRrwBz/AAAACZC2VkQCOjdvYQAA
+FJAA9isX3xtGyMLYwp2F3nXm7QEdY5bq5VUcD/RJlj792VwA/1wH0pCzVLl4Q9F9
+ex7En5r7rHR5xwX82Msc+Rq9dSyO
+=7MrZ
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const dsaKeyWithSHA512 = `9901a2044f04b07f110400db244efecc7316553ee08d179972aab87bb1214de7692593fcf5b6feb1c80fba268722dd464748539b85b81d574cd2d7ad0ca2444de4d849b8756bad7768c486c83a824f9bba4af773d11742bdfb4ac3b89ef8cc9452d4aad31a37e4b630d33927bff68e879284a1672659b8b298222fc68f370f3e24dccacc4a862442b9438b00a0ea444a24088dc23e26df7daf8f43cba3bffc4fe703fe3d6cd7fdca199d54ed8ae501c30e3ec7871ea9cdd4cf63cfe6fc82281d70a5b8bb493f922cd99fba5f088935596af087c8d818d5ec4d0b9afa7f070b3d7c1dd32a84fca08d8280b4890c8da1dde334de8e3cad8450eed2a4a4fcc2db7b8e5528b869a74a7f0189e11ef097ef1253582348de072bb07a9fa8ab838e993cef0ee203ff49298723e2d1f549b00559f886cd417a41692ce58d0ac1307dc71d85a8af21b0cf6eaa14baf2922d3a70389bedf17cc514ba0febbd107675a372fe84b90162a9e88b14d4b1c6be855b96b33fb198c46f058568817780435b6936167ebb3724b680f32bf27382ada2e37a879b3d9de2abe0c3f399350afd1ad438883f4791e2e3b4184453412068617368207472756e636174696f6e207465737488620413110a002205024f04b07f021b03060b090807030206150802090a0b0416020301021e01021780000a0910ef20e0cefca131581318009e2bf3bf047a44d75a9bacd00161ee04d435522397009a03a60d51bd8a568c6c021c8d7cf1be8d990d6417b0020003`
+
+const unknownHashFunctionHex = `8a00000040040001990006050253863c24000a09103b4fe6acc0b21f32ffff0101010101010101010101010101010101010101010101010101010101010101010101010101`
+
+const rsaSignatureBadMPIlength = `8a00000040040001030006050253863c24000a09103b4fe6acc0b21f32ffff0101010101010101010101010101010101010101010101010101010101010101010101010101`
+
+const missingHashFunctionHex = `8a00000040040001030006050253863c24000a09103b4fe6acc0b21f32ffff0101010101010101010101010101010101010101010101010101010101010101010101010101`
+
+const campbellQuine = `a0b001000300fcffa0b001000d00f2ff000300fcffa0b001000d00f2ff8270a01c00000500faff8270a01c00000500faff000500faff001400ebff8270a01c00000500faff000500faff001400ebff428821c400001400ebff428821c400001400ebff428821c400001400ebff428821c400001400ebff428821c400000000ffff000000ffff000b00f4ff428821c400000000ffff000000ffff000b00f4ff0233214c40000100feff000233214c40000100feff0000`
+
+const keyV4forVerifyingSignedMessageV3 = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: GPGTools - https://gpgtools.org
+
+mI0EVfxoFQEEAMBIqmbDfYygcvP6Phr1wr1XI41IF7Qixqybs/foBF8qqblD9gIY
+BKpXjnBOtbkcVOJ0nljd3/sQIfH4E0vQwK5/4YRQSI59eKOqd6Fx+fWQOLG+uu6z
+tewpeCj9LLHvibx/Sc7VWRnrznia6ftrXxJ/wHMezSab3tnGC0YPVdGNABEBAAG0
+JEdvY3J5cHRvIFRlc3QgS2V5IDx0aGVtYXhAZ21haWwuY29tPoi5BBMBCgAjBQJV
+/GgVAhsDBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQeXnQmhdGW9PFVAP+
+K7TU0qX5ArvIONIxh/WAweyOk884c5cE8f+3NOPOOCRGyVy0FId5A7MmD5GOQh4H
+JseOZVEVCqlmngEvtHZb3U1VYtVGE5WZ+6rQhGsMcWP5qaT4soYwMBlSYxgYwQcx
+YhN9qOr292f9j2Y//TTIJmZT4Oa+lMxhWdqTfX+qMgG4jQRV/GgVAQQArhFSiij1
+b+hT3dnapbEU+23Z1yTu1DfF6zsxQ4XQWEV3eR8v+8mEDDNcz8oyyF56k6UQ3rXi
+UMTIwRDg4V6SbZmaFbZYCOwp/EmXJ3rfhm7z7yzXj2OFN22luuqbyVhuL7LRdB0M
+pxgmjXb4tTvfgKd26x34S+QqUJ7W6uprY4sAEQEAAYifBBgBCgAJBQJV/GgVAhsM
+AAoJEHl50JoXRlvT7y8D/02ckx4OMkKBZo7viyrBw0MLG92i+DC2bs35PooHR6zz
+786mitjOp5z2QWNLBvxC70S0qVfCIz8jKupO1J6rq6Z8CcbLF3qjm6h1omUBf8Nd
+EfXKD2/2HV6zMKVknnKzIEzauh+eCKS2CeJUSSSryap/QLVAjRnckaES/OsEWhNB
+=RZia
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const signedMessageV3 = `-----BEGIN PGP MESSAGE-----
+Comment: GPGTools - https://gpgtools.org
+
+owGbwMvMwMVYWXlhlrhb9GXG03JJDKF/MtxDMjKLFYAoUaEktbhEITe1uDgxPVWP
+q5NhKjMrWAVcC9evD8z/bF/uWNjqtk/X3y5/38XGRQHm/57rrDRYuGnTw597Xqka
+uM3137/hH3Os+Jf2dc0fXOITKwJvXJvecPVs0ta+Vg7ZO1MLn8w58Xx+6L58mbka
+DGHyU9yTueZE8D+QF/Tz28Y78dqtF56R1VPn9Xw4uJqrWYdd7b3vIZ1V6R4Nh05d
+iT57d/OhWwA=
+=hG7R
+-----END PGP MESSAGE-----
+`
+
+// https://mailarchive.ietf.org/arch/msg/openpgp/9SheW_LENE0Kxf7haNllovPyAdY/
+const v5PrivKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+lGEFXJH05BYAAAAtCSsGAQQB2kcPAQEHQFhZlVcVVtwf+21xNQPX+ecMJJBL0MPd
+fj75iux+my8QAAAAAAAiAQCHZ1SnSUmWqxEsoI6facIVZQu6mph3cBFzzTvcm5lA
+Ng5ctBhlbW1hLmdvbGRtYW5AZXhhbXBsZS5uZXSIlgUTFggASCIhBRk0e8mHJGQC
+X5nfPsLgAA7ZiEiS4fez6kyUAJFZVptUBQJckfTkAhsDBQsJCAcCAyICAQYVCgkI
+CwIEFgIDAQIeBwIXgAAA9cAA/jiR3yMsZMeEQ40u6uzEoXa6UXeV/S3wwJAXRJy9
+M8s0AP9vuL/7AyTfFXwwzSjDnYmzS0qAhbLDQ643N+MXGBJ2BZxmBVyR9OQSAAAA
+MgorBgEEAZdVAQUBAQdA+nysrzml2UCweAqtpDuncSPlvrcBWKU0yfU0YvYWWAoD
+AQgHAAAAAAAiAP9OdAPppjU1WwpqjIItkxr+VPQRT8Zm/Riw7U3F6v3OiBFHiHoF
+GBYIACwiIQUZNHvJhyRkAl+Z3z7C4AAO2YhIkuH3s+pMlACRWVabVAUCXJH05AIb
+DAAAOSQBAP4BOOIR/sGLNMOfeb5fPs/02QMieoiSjIBnijhob2U5AQC+RtOHCHx7
+TcIYl5/Uyoi+FOvPLcNw4hOv2nwUzSSVAw==
+=IiS2
+-----END PGP PRIVATE KEY BLOCK-----`
+
+// Generated with the above private key
+const v5PrivKeyMsg = `-----BEGIN PGP MESSAGE-----
+Version: OpenPGP.js v4.10.7
+Comment: https://openpgpjs.org
+
+xA0DAQoWGTR7yYckZAIByxF1B21zZy50eHRfbIGSdGVzdMJ3BQEWCgAGBQJf
+bIGSACMiIQUZNHvJhyRkAl+Z3z7C4AAO2YhIkuH3s+pMlACRWVabVDQvAP9G
+y29VPonFXqi2zKkpZrvyvZxg+n5e8Nt9wNbuxeCd3QD/TtO2s+JvjrE4Siwv
+UQdl5MlBka1QSNbMq2Bz7XwNPg4=
+=6lbM
+-----END PGP MESSAGE-----`
+
+const keyWithExpiredCrossSig = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+xsDNBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv
+/seOXpgecTdOcVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz
+/56fW2O0F23qIRd8UUJp5IIlN4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/
+5whqsyroEWDJoSV0yOb25B/iwk/pLUFoyhDG9bj0kIzDxrEqW+7Ba8nocQlecMF3
+X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8Je/ECwUWYUiAZxLIlMv
+9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx5wRZ4F0
+qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7eb
+SGXrl5ZMpbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wb
+vLIwa3T4CyshfT0AEQEAAc0hQm9iIEJhYmJhZ2UgPGJvYkBvcGVucGdwLmV4YW1w
+bGU+wsEABBMBCgATBYJeO2eVAgsJAxUICgKbAQIeAQAhCRD7/MgqAV5zMBYhBNGm
+bhojsYLJmA94jPv8yCoBXnMwKWUMAJ3FKZfJ2mXvh+GFqgymvK4NoKkDRPB0CbUN
+aDdG7ZOizQrWXo7Da2MYIZ6eZUDqBKLdhZ5gZfVnisDfu/yeCgpENaKib1MPHpA8
+nZQjnPejbBDomNqY8HRzr5jvXNlwywBpjWGtegCKUY9xbSynjbfzIlMrWL4S+Rfl
++bOOQKRyYJWXmECmVyqY8cz2VUYmETjNcwC8VCDUxQnhtcCJ7Aej22hfYwVEPb/J
+BsJBPq8WECCiGfJ9Y2y6TF+62KzG9Kfs5hqUeHhQy8V4TSi479ewwL7DH86XmIIK
+chSANBS+7iyMtctjNZfmF9zYdGJFvjI/mbBR/lK66E515Inuf75XnL8hqlXuwqvG
+ni+i03Aet1DzULZEIio4uIU6ioc1lGO9h7K2Xn4S7QQH1QoISNMWqXibUR0RCGjw
+FsEDTt2QwJl8XXxoJCooM7BCcCQo+rMNVUHDjIwrdoQjPld3YZsUQQRcqH6bLuln
+cfn5ufl8zTGWKydoj/iTz8KcjZ7w187AzQRdpZzyAQwA1jC/XGxjK6ddgrRfW9j+
+s/U00++EvIsgTs2kr3Rg0GP7FLWV0YNtR1mpl55/bEl7yAxCDTkOgPUMXcaKlnQh
+6zrlt6H53mF6Bvs3inOHQvOsGtU0dqvb1vkTF0juLiJgPlM7pWv+pNQ6IA39vKoQ
+sTMBv4v5vYNXP9GgKbg8inUNT17BxzZYHfw5+q63ectgDm2on1e8CIRCZ76oBVwz
+dkVxoy3gjh1eENlk2D4P0uJNZzF1Q8GV67yLANGMCDICE/OkWn6daipYDzW4iJQt
+YPUWP4hWhjdm+CK+hg6IQUEn2Vtvi16D2blRP8BpUNNa4fNuylWVuJV76rIHvsLZ
+1pbM3LHpRgE8s6jivS3Rz3WRs0TmWCNnvHPqWizQ3VTy+r3UQVJ5AmhJDrZdZq9i
+aUIuZ01PoE1+CHiJwuxPtWvVAxf2POcm1M/F1fK1J0e+lKlQuyonTXqXR22Y41wr
+fP2aPk3nPSTW2DUAf3vRMZg57ZpRxLEhEMxcM4/LMR+PABEBAAHCwrIEGAEKAAkF
+gl8sAVYCmwIB3QkQ+/zIKgFeczDA+qAEGQEKAAwFgl47Z5UFgwB4TOAAIQkQfC+q
+Tfk8N7IWIQQd3OFfCSF87i87N2B8L6pN+Tw3st58C/0exp0X2U4LqicSHEOSqHZj
+jiysdqIELHGyo5DSPv92UFPp36aqjF9OFgtNNwSa56fmAVCD4+hor/fKARRIeIjF
+qdIC5Y/9a4B10NQFJa5lsvB38x/d39LI2kEoglZnqWgdJskROo3vNQF4KlIcm6FH
+dn4WI8UkC5oUUcrpZVMSKoacIaxLwqnXT42nIVgYYuqrd/ZagZZjG5WlrTOd5+NI
+zi/l0fWProcPHGLjmAh4Thu8i7omtVw1nQaMnq9I77ffg3cPDgXknYrLL+q8xXh/
+0mEJyIhnmPwllWCSZuLv9DrD5pOexFfdlwXhf6cLzNpW6QhXD/Tf5KrqIPr9aOv8
+9xaEEXWh0vEby2kIsI2++ft+vfdIyxYw/wKqx0awTSnuBV1rG3z1dswX4BfoY66x
+Bz3KOVqlz9+mG/FTRQwrgPvR+qgLCHbuotxoGN7fzW+PI75hQG5JQAqhsC9sHjQH
+UrI21/VUNwzfw3v5pYsWuFb5bdQ3ASJetICQiMy7IW8WIQTRpm4aI7GCyZgPeIz7
+/MgqAV5zMG6/C/wLpPl/9e6Hf5wmXIUwpZNQbNZvpiCcyx9sXsHXaycOQVxn3McZ
+nYOUP9/mobl1tIeDQyTNbkxWjU0zzJl8XQsDZerb5098pg+x7oGIL7M1vn5s5JMl
+owROourqF88JEtOBxLMxlAM7X4hB48xKQ3Hu9hS1GdnqLKki4MqRGl4l5FUwyGOM
+GjyS3TzkfiDJNwQxybQiC9n57ij20ieNyLfuWCMLcNNnZUgZtnF6wCctoq/0ZIWu
+a7nvuA/XC2WW9YjEJJiWdy5109pqac+qWiY11HWy/nms4gpMdxVpT0RhrKGWq4o0
+M5q3ZElOoeN70UO3OSbU5EVrG7gB1GuwF9mTHUVlV0veSTw0axkta3FGT//XfSpD
+lRrCkyLzwq0M+UUHQAuYpAfobDlDdnxxOD2jm5GyTzak3GSVFfjW09QFVO6HlGp5
+01/jtzkUiS6nwoHHkfnyn0beZuR8X6KlcrzLB0VFgQFLmkSM9cSOgYhD0PTu9aHb
+hW1Hj9AO8lzggBQ=
+=Nt+N
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const sigFromKeyWithExpiredCrossSig = `-----BEGIN PGP SIGNATURE-----
+
+wsDzBAABCgAGBYJfLAFsACEJEHwvqk35PDeyFiEEHdzhXwkhfO4vOzdgfC+qTfk8
+N7KiqwwAts4QGB7v9bABCC2qkTxJhmStC0wQMcHRcjL/qAiVnmasQWmvE9KVsdm3
+AaXd8mIx4a37/RRvr9dYrY2eE4uw72cMqPxNja2tvVXkHQvk1oEUqfkvbXs4ypKI
+NyeTWjXNOTZEbg0hbm3nMy+Wv7zgB1CEvAsEboLDJlhGqPcD+X8a6CJGrBGUBUrv
+KVmZr3U6vEzClz3DBLpoddCQseJRhT4YM1nKmBlZ5quh2LFgTSpajv5OsZheqt9y
+EZAPbqmLhDmWRQwGzkWHKceKS7nZ/ox2WK6OS7Ob8ZGZkM64iPo6/EGj5Yc19vQN
+AGiIaPEGszBBWlOpHTPhNm0LB0nMWqqaT87oNYwP8CQuuxDb6rKJ2lffCmZH27Lb
+UbQZcH8J+0UhpeaiadPZxH5ATJAcenmVtVVMLVOFnm+eIlxzov9ntpgGYt8hLdXB
+ITEG9mMgp3TGS9ZzSifMZ8UGtHdp9QdBg8NEVPFzDOMGxpc/Bftav7RRRuPiAER+
+7A5CBid5
+=aQkm
+-----END PGP SIGNATURE-----
+`
+
+const signedMessageWithCriticalNotation = `-----BEGIN PGP MESSAGE-----
+
+owGbwMvMwMH4oOW7S46CznTG09xJDDE3Wl1KUotLuDousDAwcjBYiSmyXL+48d6x
+U1PSGUxcj8IUszKBVMpMaWAAAgEGZpAeh9SKxNyCnFS95PzcytRiBi5OAZjyXXzM
+f8WYLqv7TXP61Sa4rqT12CI3xaN73YS2pt089f96odCKaEPnWJ3iSGmzJaW/ug10
+2Zo8Wj2k4s7t8wt4H3HtTu+y5UZfV3VOO+l//sdE/o+Lsub8FZH7/eOq7OnbNp4n
+vwjE8mqJXetNMfj8r2SCyvkEnlVRYR+/mnge+ib56FdJ8uKtqSxyvgA=
+=fRXs
+-----END PGP MESSAGE-----`
+
+const criticalNotationSigner = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mI0EUmEvTgEEANyWtQQMOybQ9JltDqmaX0WnNPJeLILIM36sw6zL0nfTQ5zXSS3+
+fIF6P29lJFxpblWk02PSID5zX/DYU9/zjM2xPO8Oa4xo0cVTOTLj++Ri5mtr//f5
+GLsIXxFrBJhD/ghFsL3Op0GXOeLJ9A5bsOn8th7x6JucNKuaRB6bQbSPABEBAAG0
+JFRlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPoi5BBMBAgAjBQJS
+YS9OAhsvBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQSmNhOk1uQJQwDAP6
+AgrTyqkRlJVqz2pb46TfbDM2TDF7o9CBnBzIGoxBhlRwpqALz7z2kxBDmwpQa+ki
+Bq3jZN/UosY9y8bhwMAlnrDY9jP1gdCo+H0sD48CdXybblNwaYpwqC8VSpDdTndf
+9j2wE/weihGp/DAdy/2kyBCaiOY1sjhUfJ1GogF49rC4jQRSYS9OAQQA6R/PtBFa
+JaT4jq10yqASk4sqwVMsc6HcifM5lSdxzExFP74naUMMyEsKHP53QxTF0Grqusag
+Qg/ZtgT0CN1HUM152y7ACOdp1giKjpMzOTQClqCoclyvWOFB+L/SwGEIJf7LSCEr
+woBuJifJc8xAVr0XX0JthoW+uP91eTQ3XpsAEQEAAYkBPQQYAQIACQUCUmEvTgIb
+LgCoCRBKY2E6TW5AlJ0gBBkBAgAGBQJSYS9OAAoJEOCE90RsICyXuqIEANmmiRCA
+SF7YK7PvFkieJNwzeK0V3F2lGX+uu6Y3Q/Zxdtwc4xR+me/CSBmsURyXTO29OWhP
+GLszPH9zSJU9BdDi6v0yNprmFPX/1Ng0Abn/sCkwetvjxC1YIvTLFwtUL/7v6NS2
+bZpsUxRTg9+cSrMWWSNjiY9qUKajm1tuzPDZXAUEAMNmAN3xXN/Kjyvj2OK2ck0X
+W748sl/tc3qiKPMJ+0AkMF7Pjhmh9nxqE9+QCEl7qinFqqBLjuzgUhBU4QlwX1GD
+AtNTq6ihLMD5v1d82ZC7tNatdlDMGWnIdvEMCv2GZcuIqDQ9rXWs49e7tq1NncLY
+hz3tYjKhoFTKEIq3y3Pp
+=h/aX
+-----END PGP PUBLIC KEY BLOCK-----`
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
new file mode 100644
index 00000000..a4369596
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
@@ -0,0 +1,407 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package s2k implements the various OpenPGP string-to-key transforms as
+// specified in RFC 4800 section 3.7.1, and Argon2 specified in
+// draft-ietf-openpgp-crypto-refresh-08 section 3.7.1.4.
+package s2k // import "github.com/ProtonMail/go-crypto/openpgp/s2k"
+
+import (
+ "crypto"
+ "hash"
+ "io"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "golang.org/x/crypto/argon2"
+)
+
+type Mode uint8
+
+// Defines the default S2KMode constants
+//
+// 0 (simple), 1(salted), 3(iterated), 4(argon2)
+const (
+ SimpleS2K Mode = 0
+ SaltedS2K Mode = 1
+ IteratedSaltedS2K Mode = 3
+ Argon2S2K Mode = 4
+ GnuS2K Mode = 101
+)
+
+const Argon2SaltSize int = 16
+
+// Params contains all the parameters of the s2k packet
+type Params struct {
+ // mode is the mode of s2k function.
+ // It can be 0 (simple), 1(salted), 3(iterated)
+ // 2(reserved) 100-110(private/experimental).
+ mode Mode
+ // hashId is the ID of the hash function used in any of the modes
+ hashId byte
+ // salt is a byte array to use as a salt in hashing process or argon2
+ saltBytes [Argon2SaltSize]byte
+ // countByte is used to determine how many rounds of hashing are to
+ // be performed in s2k mode 3. See RFC 4880 Section 3.7.1.3.
+ countByte byte
+ // passes is a parameter in Argon2 to determine the number of iterations
+ // See RFC the crypto refresh Section 3.7.1.4.
+ passes byte
+ // parallelism is a parameter in Argon2 to determine the degree of paralellism
+ // See RFC the crypto refresh Section 3.7.1.4.
+ parallelism byte
+ // memoryExp is a parameter in Argon2 to determine the memory usage
+ // i.e., 2 ** memoryExp kibibytes
+ // See RFC the crypto refresh Section 3.7.1.4.
+ memoryExp byte
+}
+
+// encodeCount converts an iterative "count" in the range 1024 to
+// 65011712, inclusive, to an encoded count. The return value is the
+// octet that is actually stored in the GPG file. encodeCount panics
+// if i is not in the above range (encodedCount above takes care to
+// pass i in the correct range). See RFC 4880 Section 3.7.7.1.
+func encodeCount(i int) uint8 {
+ if i < 65536 || i > 65011712 {
+ panic("count arg i outside the required range")
+ }
+
+ for encoded := 96; encoded < 256; encoded++ {
+ count := decodeCount(uint8(encoded))
+ if count >= i {
+ return uint8(encoded)
+ }
+ }
+
+ return 255
+}
+
+// decodeCount returns the s2k mode 3 iterative "count" corresponding to
+// the encoded octet c.
+func decodeCount(c uint8) int {
+ return (16 + int(c&15)) << (uint32(c>>4) + 6)
+}
+
+// encodeMemory converts the Argon2 "memory" in the range parallelism*8 to
+// 2**31, inclusive, to an encoded memory. The return value is the
+// octet that is actually stored in the GPG file. encodeMemory panics
+// if is not in the above range
+// See OpenPGP crypto refresh Section 3.7.1.4.
+func encodeMemory(memory uint32, parallelism uint8) uint8 {
+ if memory < (8 * uint32(parallelism)) || memory > uint32(2147483648) {
+ panic("Memory argument memory is outside the required range")
+ }
+
+ for exp := 3; exp < 31; exp++ {
+ compare := decodeMemory(uint8(exp))
+ if compare >= memory {
+ return uint8(exp)
+ }
+ }
+
+ return 31
+}
+
+// decodeMemory computes the decoded memory in kibibytes as 2**memoryExponent
+func decodeMemory(memoryExponent uint8) uint32 {
+ return uint32(1) << memoryExponent
+}
+
+// Simple writes to out the result of computing the Simple S2K function (RFC
+// 4880, section 3.7.1.1) using the given hash and input passphrase.
+func Simple(out []byte, h hash.Hash, in []byte) {
+ Salted(out, h, in, nil)
+}
+
+var zero [1]byte
+
+// Salted writes to out the result of computing the Salted S2K function (RFC
+// 4880, section 3.7.1.2) using the given hash, input passphrase and salt.
+func Salted(out []byte, h hash.Hash, in []byte, salt []byte) {
+ done := 0
+ var digest []byte
+
+ for i := 0; done < len(out); i++ {
+ h.Reset()
+ for j := 0; j < i; j++ {
+ h.Write(zero[:])
+ }
+ h.Write(salt)
+ h.Write(in)
+ digest = h.Sum(digest[:0])
+ n := copy(out[done:], digest)
+ done += n
+ }
+}
+
+// Iterated writes to out the result of computing the Iterated and Salted S2K
+// function (RFC 4880, section 3.7.1.3) using the given hash, input passphrase,
+// salt and iteration count.
+func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) {
+ combined := make([]byte, len(in)+len(salt))
+ copy(combined, salt)
+ copy(combined[len(salt):], in)
+
+ if count < len(combined) {
+ count = len(combined)
+ }
+
+ done := 0
+ var digest []byte
+ for i := 0; done < len(out); i++ {
+ h.Reset()
+ for j := 0; j < i; j++ {
+ h.Write(zero[:])
+ }
+ written := 0
+ for written < count {
+ if written+len(combined) > count {
+ todo := count - written
+ h.Write(combined[:todo])
+ written = count
+ } else {
+ h.Write(combined)
+ written += len(combined)
+ }
+ }
+ digest = h.Sum(digest[:0])
+ n := copy(out[done:], digest)
+ done += n
+ }
+}
+
+// Argon2 writes to out the key derived from the password (in) with the Argon2
+// function (the crypto refresh, section 3.7.1.4)
+func Argon2(out []byte, in []byte, salt []byte, passes uint8, paralellism uint8, memoryExp uint8) {
+ key := argon2.IDKey(in, salt, uint32(passes), decodeMemory(memoryExp), paralellism, uint32(len(out)))
+ copy(out[:], key)
+}
+
+// Generate generates valid parameters from given configuration.
+// It will enforce the Iterated and Salted or Argon2 S2K method.
+func Generate(rand io.Reader, c *Config) (*Params, error) {
+ var params *Params
+ if c != nil && c.Mode() == Argon2S2K {
+ // handle Argon2 case
+ argonConfig := c.Argon2()
+ params = &Params{
+ mode: Argon2S2K,
+ passes: argonConfig.Passes(),
+ parallelism: argonConfig.Parallelism(),
+ memoryExp: argonConfig.EncodedMemory(),
+ }
+ } else if c != nil && c.PassphraseIsHighEntropy && c.Mode() == SaltedS2K { // Allow SaltedS2K if PassphraseIsHighEntropy
+ hashId, ok := algorithm.HashToHashId(c.hash())
+ if !ok {
+ return nil, errors.UnsupportedError("no such hash")
+ }
+
+ params = &Params{
+ mode: SaltedS2K,
+ hashId: hashId,
+ }
+ } else { // Enforce IteratedSaltedS2K method otherwise
+ hashId, ok := algorithm.HashToHashId(c.hash())
+ if !ok {
+ return nil, errors.UnsupportedError("no such hash")
+ }
+ if c != nil {
+ c.S2KMode = IteratedSaltedS2K
+ }
+ params = &Params{
+ mode: IteratedSaltedS2K,
+ hashId: hashId,
+ countByte: c.EncodedCount(),
+ }
+ }
+ if _, err := io.ReadFull(rand, params.salt()); err != nil {
+ return nil, err
+ }
+ return params, nil
+}
+
+// Parse reads a binary specification for a string-to-key transformation from r
+// and returns a function which performs that transform. If the S2K is a special
+// GNU extension that indicates that the private key is missing, then the error
+// returned is errors.ErrDummyPrivateKey.
+func Parse(r io.Reader) (f func(out, in []byte), err error) {
+ params, err := ParseIntoParams(r)
+ if err != nil {
+ return nil, err
+ }
+
+ return params.Function()
+}
+
+// ParseIntoParams reads a binary specification for a string-to-key
+// transformation from r and returns a struct describing the s2k parameters.
+func ParseIntoParams(r io.Reader) (params *Params, err error) {
+ var buf [Argon2SaltSize + 3]byte
+
+ _, err = io.ReadFull(r, buf[:1])
+ if err != nil {
+ return
+ }
+
+ params = &Params{
+ mode: Mode(buf[0]),
+ }
+
+ switch params.mode {
+ case SimpleS2K:
+ _, err = io.ReadFull(r, buf[:1])
+ if err != nil {
+ return nil, err
+ }
+ params.hashId = buf[0]
+ return params, nil
+ case SaltedS2K:
+ _, err = io.ReadFull(r, buf[:9])
+ if err != nil {
+ return nil, err
+ }
+ params.hashId = buf[0]
+ copy(params.salt(), buf[1:9])
+ return params, nil
+ case IteratedSaltedS2K:
+ _, err = io.ReadFull(r, buf[:10])
+ if err != nil {
+ return nil, err
+ }
+ params.hashId = buf[0]
+ copy(params.salt(), buf[1:9])
+ params.countByte = buf[9]
+ return params, nil
+ case Argon2S2K:
+ _, err = io.ReadFull(r, buf[:Argon2SaltSize+3])
+ if err != nil {
+ return nil, err
+ }
+ copy(params.salt(), buf[:Argon2SaltSize])
+ params.passes = buf[Argon2SaltSize]
+ params.parallelism = buf[Argon2SaltSize+1]
+ params.memoryExp = buf[Argon2SaltSize+2]
+ return params, nil
+ case GnuS2K:
+ // This is a GNU extension. See
+ // https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/DETAILS;h=fe55ae16ab4e26d8356dc574c9e8bc935e71aef1;hb=23191d7851eae2217ecdac6484349849a24fd94a#l1109
+ if _, err = io.ReadFull(r, buf[:5]); err != nil {
+ return nil, err
+ }
+ params.hashId = buf[0]
+ if buf[1] == 'G' && buf[2] == 'N' && buf[3] == 'U' && buf[4] == 1 {
+ return params, nil
+ }
+ return nil, errors.UnsupportedError("GNU S2K extension")
+ }
+
+ return nil, errors.UnsupportedError("S2K function")
+}
+
+func (params *Params) Dummy() bool {
+ return params != nil && params.mode == GnuS2K
+}
+
+func (params *Params) salt() []byte {
+ switch params.mode {
+ case SaltedS2K, IteratedSaltedS2K: return params.saltBytes[:8]
+ case Argon2S2K: return params.saltBytes[:Argon2SaltSize]
+ default: return nil
+ }
+}
+
+func (params *Params) Function() (f func(out, in []byte), err error) {
+ if params.Dummy() {
+ return nil, errors.ErrDummyPrivateKey("dummy key found")
+ }
+ var hashObj crypto.Hash
+ if params.mode != Argon2S2K {
+ var ok bool
+ hashObj, ok = algorithm.HashIdToHashWithSha1(params.hashId)
+ if !ok {
+ return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(params.hashId)))
+ }
+ if !hashObj.Available() {
+ return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashObj)))
+ }
+ }
+
+ switch params.mode {
+ case SimpleS2K:
+ f := func(out, in []byte) {
+ Simple(out, hashObj.New(), in)
+ }
+
+ return f, nil
+ case SaltedS2K:
+ f := func(out, in []byte) {
+ Salted(out, hashObj.New(), in, params.salt())
+ }
+
+ return f, nil
+ case IteratedSaltedS2K:
+ f := func(out, in []byte) {
+ Iterated(out, hashObj.New(), in, params.salt(), decodeCount(params.countByte))
+ }
+
+ return f, nil
+ case Argon2S2K:
+ f := func(out, in []byte) {
+ Argon2(out, in, params.salt(), params.passes, params.parallelism, params.memoryExp)
+ }
+ return f, nil
+ }
+
+ return nil, errors.UnsupportedError("S2K function")
+}
+
+func (params *Params) Serialize(w io.Writer) (err error) {
+ if _, err = w.Write([]byte{uint8(params.mode)}); err != nil {
+ return
+ }
+ if params.mode != Argon2S2K {
+ if _, err = w.Write([]byte{params.hashId}); err != nil {
+ return
+ }
+ }
+ if params.Dummy() {
+ _, err = w.Write(append([]byte("GNU"), 1))
+ return
+ }
+ if params.mode > 0 {
+ if _, err = w.Write(params.salt()); err != nil {
+ return
+ }
+ if params.mode == IteratedSaltedS2K {
+ _, err = w.Write([]byte{params.countByte})
+ }
+ if params.mode == Argon2S2K {
+ _, err = w.Write([]byte{params.passes, params.parallelism, params.memoryExp})
+ }
+ }
+ return
+}
+
+// Serialize salts and stretches the given passphrase and writes the
+// resulting key into key. It also serializes an S2K descriptor to
+// w. The key stretching can be configured with c, which may be
+// nil. In that case, sensible defaults will be used.
+func Serialize(w io.Writer, key []byte, rand io.Reader, passphrase []byte, c *Config) error {
+ params, err := Generate(rand, c)
+ if err != nil {
+ return err
+ }
+ err = params.Serialize(w)
+ if err != nil {
+ return err
+ }
+
+ f, err := params.Function()
+ if err != nil {
+ return err
+ }
+ f(key, passphrase)
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go
new file mode 100644
index 00000000..25a4442d
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go
@@ -0,0 +1,26 @@
+package s2k
+
+// Cache stores keys derived with s2k functions from one passphrase
+// to avoid recomputation if multiple items are encrypted with
+// the same parameters.
+type Cache map[Params][]byte
+
+// GetOrComputeDerivedKey tries to retrieve the key
+// for the given s2k parameters from the cache.
+// If there is no hit, it derives the key with the s2k function from the passphrase,
+// updates the cache, and returns the key.
+func (c *Cache) GetOrComputeDerivedKey(passphrase []byte, params *Params, expectedKeySize int) ([]byte, error) {
+ key, found := (*c)[*params]
+ if !found || len(key) != expectedKeySize {
+ var err error
+ derivedKey := make([]byte, expectedKeySize)
+ s2k, err := params.Function()
+ if err != nil {
+ return nil, err
+ }
+ s2k(derivedKey, passphrase)
+ (*c)[*params] = key
+ return derivedKey, nil
+ }
+ return key, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go
new file mode 100644
index 00000000..b40be522
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go
@@ -0,0 +1,129 @@
+package s2k
+
+import "crypto"
+
+// Config collects configuration parameters for s2k key-stretching
+// transformations. A nil *Config is valid and results in all default
+// values.
+type Config struct {
+ // S2K (String to Key) mode, used for key derivation in the context of secret key encryption
+ // and passphrase-encrypted data. Either s2k.Argon2S2K or s2k.IteratedSaltedS2K may be used.
+ // If the passphrase is a high-entropy key, indicated by setting PassphraseIsHighEntropy to true,
+ // s2k.SaltedS2K can also be used.
+ // Note: Argon2 is the strongest option but not all OpenPGP implementations are compatible with it
+ //(pending standardisation).
+ // 0 (simple), 1(salted), 3(iterated), 4(argon2)
+ // 2(reserved) 100-110(private/experimental).
+ S2KMode Mode
+ // Only relevant if S2KMode is not set to s2k.Argon2S2K.
+ // Hash is the default hash function to be used. If
+ // nil, SHA256 is used.
+ Hash crypto.Hash
+ // Argon2 parameters for S2K (String to Key).
+ // Only relevant if S2KMode is set to s2k.Argon2S2K.
+ // If nil, default parameters are used.
+ // For more details on the choice of parameters, see https://tools.ietf.org/html/rfc9106#section-4.
+ Argon2Config *Argon2Config
+ // Only relevant if S2KMode is set to s2k.IteratedSaltedS2K.
+ // Iteration count for Iterated S2K (String to Key). It
+ // determines the strength of the passphrase stretching when
+ // the said passphrase is hashed to produce a key. S2KCount
+ // should be between 65536 and 65011712, inclusive. If Config
+ // is nil or S2KCount is 0, the value 16777216 used. Not all
+ // values in the above range can be represented. S2KCount will
+ // be rounded up to the next representable value if it cannot
+ // be encoded exactly. When set, it is strongly encrouraged to
+ // use a value that is at least 65536. See RFC 4880 Section
+ // 3.7.1.3.
+ S2KCount int
+ // Indicates whether the passphrase passed by the application is a
+ // high-entropy key (e.g. it's randomly generated or derived from
+ // another passphrase using a strong key derivation function).
+ // When true, allows the S2KMode to be s2k.SaltedS2K.
+ // When the passphrase is not a high-entropy key, using SaltedS2K is
+ // insecure, and not allowed by draft-ietf-openpgp-crypto-refresh-08.
+ PassphraseIsHighEntropy bool
+}
+
+// Argon2Config stores the Argon2 parameters
+// A nil *Argon2Config is valid and results in all default
+type Argon2Config struct {
+ NumberOfPasses uint8
+ DegreeOfParallelism uint8
+ // The memory parameter for Argon2 specifies desired memory usage in kibibytes.
+ // For example memory=64*1024 sets the memory cost to ~64 MB.
+ Memory uint32
+}
+
+func (c *Config) Mode() Mode {
+ if c == nil {
+ return IteratedSaltedS2K
+ }
+ return c.S2KMode
+}
+
+func (c *Config) hash() crypto.Hash {
+ if c == nil || uint(c.Hash) == 0 {
+ return crypto.SHA256
+ }
+
+ return c.Hash
+}
+
+func (c *Config) Argon2() *Argon2Config {
+ if c == nil || c.Argon2Config == nil {
+ return nil
+ }
+ return c.Argon2Config
+}
+
+// EncodedCount get encoded count
+func (c *Config) EncodedCount() uint8 {
+ if c == nil || c.S2KCount == 0 {
+ return 224 // The common case. Corresponding to 16777216
+ }
+
+ i := c.S2KCount
+
+ switch {
+ case i < 65536:
+ i = 65536
+ case i > 65011712:
+ i = 65011712
+ }
+
+ return encodeCount(i)
+}
+
+func (c *Argon2Config) Passes() uint8 {
+ if c == nil || c.NumberOfPasses == 0 {
+ return 3
+ }
+ return c.NumberOfPasses
+}
+
+func (c *Argon2Config) Parallelism() uint8 {
+ if c == nil || c.DegreeOfParallelism == 0 {
+ return 4
+ }
+ return c.DegreeOfParallelism
+}
+
+func (c *Argon2Config) EncodedMemory() uint8 {
+ if c == nil || c.Memory == 0 {
+ return 16 // 64 MiB of RAM
+ }
+
+ memory := c.Memory
+ lowerBound := uint32(c.Parallelism())*8
+ upperBound := uint32(2147483648)
+
+ switch {
+ case memory < lowerBound:
+ memory = lowerBound
+ case memory > upperBound:
+ memory = upperBound
+ }
+
+ return encodeMemory(memory, c.Parallelism())
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go
new file mode 100644
index 00000000..7fdd13a3
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go
@@ -0,0 +1,583 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openpgp
+
+import (
+ "crypto"
+ "hash"
+ "io"
+ "strconv"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/armor"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+)
+
+// DetachSign signs message with the private key from signer (which must
+// already have been decrypted) and writes the signature to w.
+// If config is nil, sensible defaults will be used.
+func DetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
+ return detachSign(w, signer, message, packet.SigTypeBinary, config)
+}
+
+// ArmoredDetachSign signs message with the private key from signer (which
+// must already have been decrypted) and writes an armored signature to w.
+// If config is nil, sensible defaults will be used.
+func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) (err error) {
+ return armoredDetachSign(w, signer, message, packet.SigTypeBinary, config)
+}
+
+// DetachSignText signs message (after canonicalising the line endings) with
+// the private key from signer (which must already have been decrypted) and
+// writes the signature to w.
+// If config is nil, sensible defaults will be used.
+func DetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
+ return detachSign(w, signer, message, packet.SigTypeText, config)
+}
+
+// ArmoredDetachSignText signs message (after canonicalising the line endings)
+// with the private key from signer (which must already have been decrypted)
+// and writes an armored signature to w.
+// If config is nil, sensible defaults will be used.
+func ArmoredDetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
+ return armoredDetachSign(w, signer, message, packet.SigTypeText, config)
+}
+
+func armoredDetachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
+ out, err := armor.Encode(w, SignatureType, nil)
+ if err != nil {
+ return
+ }
+ err = detachSign(out, signer, message, sigType, config)
+ if err != nil {
+ return
+ }
+ return out.Close()
+}
+
+func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
+ signingKey, ok := signer.SigningKeyById(config.Now(), config.SigningKey())
+ if !ok {
+ return errors.InvalidArgumentError("no valid signing keys")
+ }
+ if signingKey.PrivateKey == nil {
+ return errors.InvalidArgumentError("signing key doesn't have a private key")
+ }
+ if signingKey.PrivateKey.Encrypted {
+ return errors.InvalidArgumentError("signing key is encrypted")
+ }
+ if _, ok := algorithm.HashToHashId(config.Hash()); !ok {
+ return errors.InvalidArgumentError("invalid hash function")
+ }
+
+ sig := createSignaturePacket(signingKey.PublicKey, sigType, config)
+
+ h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType)
+ if err != nil {
+ return
+ }
+ if _, err = io.Copy(wrappedHash, message); err != nil {
+ return err
+ }
+
+ err = sig.Sign(h, signingKey.PrivateKey, config)
+ if err != nil {
+ return
+ }
+
+ return sig.Serialize(w)
+}
+
+// FileHints contains metadata about encrypted files. This metadata is, itself,
+// encrypted.
+type FileHints struct {
+ // IsBinary can be set to hint that the contents are binary data.
+ IsBinary bool
+ // FileName hints at the name of the file that should be written. It's
+ // truncated to 255 bytes if longer. It may be empty to suggest that the
+ // file should not be written to disk. It may be equal to "_CONSOLE" to
+ // suggest the data should not be written to disk.
+ FileName string
+ // ModTime contains the modification time of the file, or the zero time if not applicable.
+ ModTime time.Time
+}
+
+// SymmetricallyEncrypt acts like gpg -c: it encrypts a file with a passphrase.
+// The resulting WriteCloser must be closed after the contents of the file have
+// been written.
+// If config is nil, sensible defaults will be used.
+func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ if hints == nil {
+ hints = &FileHints{}
+ }
+
+ key, err := packet.SerializeSymmetricKeyEncrypted(ciphertext, passphrase, config)
+ if err != nil {
+ return
+ }
+
+ var w io.WriteCloser
+ cipherSuite := packet.CipherSuite{
+ Cipher: config.Cipher(),
+ Mode: config.AEAD().Mode(),
+ }
+ w, err = packet.SerializeSymmetricallyEncrypted(ciphertext, config.Cipher(), config.AEAD() != nil, cipherSuite, key, config)
+ if err != nil {
+ return
+ }
+
+ literalData := w
+ if algo := config.Compression(); algo != packet.CompressionNone {
+ var compConfig *packet.CompressionConfig
+ if config != nil {
+ compConfig = config.CompressionConfig
+ }
+ literalData, err = packet.SerializeCompressed(w, algo, compConfig)
+ if err != nil {
+ return
+ }
+ }
+
+ var epochSeconds uint32
+ if !hints.ModTime.IsZero() {
+ epochSeconds = uint32(hints.ModTime.Unix())
+ }
+ return packet.SerializeLiteral(literalData, hints.IsBinary, hints.FileName, epochSeconds)
+}
+
+// intersectPreferences mutates and returns a prefix of a that contains only
+// the values in the intersection of a and b. The order of a is preserved.
+func intersectPreferences(a []uint8, b []uint8) (intersection []uint8) {
+ var j int
+ for _, v := range a {
+ for _, v2 := range b {
+ if v == v2 {
+ a[j] = v
+ j++
+ break
+ }
+ }
+ }
+
+ return a[:j]
+}
+
+// intersectPreferences mutates and returns a prefix of a that contains only
+// the values in the intersection of a and b. The order of a is preserved.
+func intersectCipherSuites(a [][2]uint8, b [][2]uint8) (intersection [][2]uint8) {
+ var j int
+ for _, v := range a {
+ for _, v2 := range b {
+ if v[0] == v2[0] && v[1] == v2[1] {
+ a[j] = v
+ j++
+ break
+ }
+ }
+ }
+
+ return a[:j]
+}
+
+func hashToHashId(h crypto.Hash) uint8 {
+ v, ok := algorithm.HashToHashId(h)
+ if !ok {
+ panic("tried to convert unknown hash")
+ }
+ return v
+}
+
+// EncryptText encrypts a message to a number of recipients and, optionally,
+// signs it. Optional information is contained in 'hints', also encrypted, that
+// aids the recipients in processing the message. The resulting WriteCloser
+// must be closed after the contents of the file have been written. If config
+// is nil, sensible defaults will be used. The signing is done in text mode.
+func EncryptText(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ return encrypt(ciphertext, ciphertext, to, signed, hints, packet.SigTypeText, config)
+}
+
+// Encrypt encrypts a message to a number of recipients and, optionally, signs
+// it. hints contains optional information, that is also encrypted, that aids
+// the recipients in processing the message. The resulting WriteCloser must
+// be closed after the contents of the file have been written.
+// If config is nil, sensible defaults will be used.
+func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ return encrypt(ciphertext, ciphertext, to, signed, hints, packet.SigTypeBinary, config)
+}
+
+// EncryptSplit encrypts a message to a number of recipients and, optionally, signs
+// it. hints contains optional information, that is also encrypted, that aids
+// the recipients in processing the message. The resulting WriteCloser must
+// be closed after the contents of the file have been written.
+// If config is nil, sensible defaults will be used.
+func EncryptSplit(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ return encrypt(keyWriter, dataWriter, to, signed, hints, packet.SigTypeBinary, config)
+}
+
+// EncryptTextSplit encrypts a message to a number of recipients and, optionally, signs
+// it. hints contains optional information, that is also encrypted, that aids
+// the recipients in processing the message. The resulting WriteCloser must
+// be closed after the contents of the file have been written.
+// If config is nil, sensible defaults will be used.
+func EncryptTextSplit(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ return encrypt(keyWriter, dataWriter, to, signed, hints, packet.SigTypeText, config)
+}
+
+// writeAndSign writes the data as a payload package and, optionally, signs
+// it. hints contains optional information, that is also encrypted,
+// that aids the recipients in processing the message. The resulting
+// WriteCloser must be closed after the contents of the file have been
+// written. If config is nil, sensible defaults will be used.
+func writeAndSign(payload io.WriteCloser, candidateHashes []uint8, signed *Entity, hints *FileHints, sigType packet.SignatureType, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ var signer *packet.PrivateKey
+ if signed != nil {
+ signKey, ok := signed.SigningKeyById(config.Now(), config.SigningKey())
+ if !ok {
+ return nil, errors.InvalidArgumentError("no valid signing keys")
+ }
+ signer = signKey.PrivateKey
+ if signer == nil {
+ return nil, errors.InvalidArgumentError("no private key in signing key")
+ }
+ if signer.Encrypted {
+ return nil, errors.InvalidArgumentError("signing key must be decrypted")
+ }
+ }
+
+ var hash crypto.Hash
+ for _, hashId := range candidateHashes {
+ if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() {
+ hash = h
+ break
+ }
+ }
+
+ // If the hash specified by config is a candidate, we'll use that.
+ if configuredHash := config.Hash(); configuredHash.Available() {
+ for _, hashId := range candidateHashes {
+ if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash {
+ hash = h
+ break
+ }
+ }
+ }
+
+ if hash == 0 {
+ hashId := candidateHashes[0]
+ name, ok := algorithm.HashIdToString(hashId)
+ if !ok {
+ name = "#" + strconv.Itoa(int(hashId))
+ }
+ return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)")
+ }
+
+ if signer != nil {
+ ops := &packet.OnePassSignature{
+ SigType: sigType,
+ Hash: hash,
+ PubKeyAlgo: signer.PubKeyAlgo,
+ KeyId: signer.KeyId,
+ IsLast: true,
+ }
+ if err := ops.Serialize(payload); err != nil {
+ return nil, err
+ }
+ }
+
+ if hints == nil {
+ hints = &FileHints{}
+ }
+
+ w := payload
+ if signer != nil {
+ // If we need to write a signature packet after the literal
+ // data then we need to stop literalData from closing
+ // encryptedData.
+ w = noOpCloser{w}
+
+ }
+ var epochSeconds uint32
+ if !hints.ModTime.IsZero() {
+ epochSeconds = uint32(hints.ModTime.Unix())
+ }
+ literalData, err := packet.SerializeLiteral(w, hints.IsBinary, hints.FileName, epochSeconds)
+ if err != nil {
+ return nil, err
+ }
+
+ if signer != nil {
+ h, wrappedHash, err := hashForSignature(hash, sigType)
+ if err != nil {
+ return nil, err
+ }
+ metadata := &packet.LiteralData{
+ Format: 't',
+ FileName: hints.FileName,
+ Time: epochSeconds,
+ }
+ if hints.IsBinary {
+ metadata.Format = 'b'
+ }
+ return signatureWriter{payload, literalData, hash, wrappedHash, h, signer, sigType, config, metadata}, nil
+ }
+ return literalData, nil
+}
+
+// encrypt encrypts a message to a number of recipients and, optionally, signs
+// it. hints contains optional information, that is also encrypted, that aids
+// the recipients in processing the message. The resulting WriteCloser must
+// be closed after the contents of the file have been written.
+// If config is nil, sensible defaults will be used.
+func encrypt(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *Entity, hints *FileHints, sigType packet.SignatureType, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ if len(to) == 0 {
+ return nil, errors.InvalidArgumentError("no encryption recipient provided")
+ }
+
+ // These are the possible ciphers that we'll use for the message.
+ candidateCiphers := []uint8{
+ uint8(packet.CipherAES256),
+ uint8(packet.CipherAES128),
+ }
+
+ // These are the possible hash functions that we'll use for the signature.
+ candidateHashes := []uint8{
+ hashToHashId(crypto.SHA256),
+ hashToHashId(crypto.SHA384),
+ hashToHashId(crypto.SHA512),
+ hashToHashId(crypto.SHA3_256),
+ hashToHashId(crypto.SHA3_512),
+ }
+
+ // Prefer GCM if everyone supports it
+ candidateCipherSuites := [][2]uint8{
+ {uint8(packet.CipherAES256), uint8(packet.AEADModeGCM)},
+ {uint8(packet.CipherAES256), uint8(packet.AEADModeEAX)},
+ {uint8(packet.CipherAES256), uint8(packet.AEADModeOCB)},
+ {uint8(packet.CipherAES128), uint8(packet.AEADModeGCM)},
+ {uint8(packet.CipherAES128), uint8(packet.AEADModeEAX)},
+ {uint8(packet.CipherAES128), uint8(packet.AEADModeOCB)},
+ }
+
+ candidateCompression := []uint8{
+ uint8(packet.CompressionNone),
+ uint8(packet.CompressionZIP),
+ uint8(packet.CompressionZLIB),
+ }
+
+ encryptKeys := make([]Key, len(to))
+
+ // AEAD is used only if config enables it and every key supports it
+ aeadSupported := config.AEAD() != nil
+
+ for i := range to {
+ var ok bool
+ encryptKeys[i], ok = to[i].EncryptionKey(config.Now())
+ if !ok {
+ return nil, errors.InvalidArgumentError("cannot encrypt a message to key id " + strconv.FormatUint(to[i].PrimaryKey.KeyId, 16) + " because it has no valid encryption keys")
+ }
+
+ sig := to[i].PrimaryIdentity().SelfSignature
+ if !sig.SEIPDv2 {
+ aeadSupported = false
+ }
+
+ candidateCiphers = intersectPreferences(candidateCiphers, sig.PreferredSymmetric)
+ candidateHashes = intersectPreferences(candidateHashes, sig.PreferredHash)
+ candidateCipherSuites = intersectCipherSuites(candidateCipherSuites, sig.PreferredCipherSuites)
+ candidateCompression = intersectPreferences(candidateCompression, sig.PreferredCompression)
+ }
+
+ // In the event that the intersection of supported algorithms is empty we use the ones
+ // labelled as MUST that every implementation supports.
+ if len(candidateCiphers) == 0 {
+ // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.3
+ candidateCiphers = []uint8{uint8(packet.CipherAES128)}
+ }
+ if len(candidateHashes) == 0 {
+ // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#hash-algos
+ candidateHashes = []uint8{hashToHashId(crypto.SHA256)}
+ }
+ if len(candidateCipherSuites) == 0 {
+ // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.6
+ candidateCipherSuites = [][2]uint8{{uint8(packet.CipherAES128), uint8(packet.AEADModeOCB)}}
+ }
+
+ cipher := packet.CipherFunction(candidateCiphers[0])
+ aeadCipherSuite := packet.CipherSuite{
+ Cipher: packet.CipherFunction(candidateCipherSuites[0][0]),
+ Mode: packet.AEADMode(candidateCipherSuites[0][1]),
+ }
+
+ // If the cipher specified by config is a candidate, we'll use that.
+ configuredCipher := config.Cipher()
+ for _, c := range candidateCiphers {
+ cipherFunc := packet.CipherFunction(c)
+ if cipherFunc == configuredCipher {
+ cipher = cipherFunc
+ break
+ }
+ }
+
+ symKey := make([]byte, cipher.KeySize())
+ if _, err := io.ReadFull(config.Random(), symKey); err != nil {
+ return nil, err
+ }
+
+ for _, key := range encryptKeys {
+ if err := packet.SerializeEncryptedKey(keyWriter, key.PublicKey, cipher, symKey, config); err != nil {
+ return nil, err
+ }
+ }
+
+ var payload io.WriteCloser
+ payload, err = packet.SerializeSymmetricallyEncrypted(dataWriter, cipher, aeadSupported, aeadCipherSuite, symKey, config)
+ if err != nil {
+ return
+ }
+
+ payload, err = handleCompression(payload, candidateCompression, config)
+ if err != nil {
+ return nil, err
+ }
+
+ return writeAndSign(payload, candidateHashes, signed, hints, sigType, config)
+}
+
+// Sign signs a message. The resulting WriteCloser must be closed after the
+// contents of the file have been written. hints contains optional information
+// that aids the recipients in processing the message.
+// If config is nil, sensible defaults will be used.
+func Sign(output io.Writer, signed *Entity, hints *FileHints, config *packet.Config) (input io.WriteCloser, err error) {
+ if signed == nil {
+ return nil, errors.InvalidArgumentError("no signer provided")
+ }
+
+ // These are the possible hash functions that we'll use for the signature.
+ candidateHashes := []uint8{
+ hashToHashId(crypto.SHA256),
+ hashToHashId(crypto.SHA384),
+ hashToHashId(crypto.SHA512),
+ hashToHashId(crypto.SHA3_256),
+ hashToHashId(crypto.SHA3_512),
+ }
+ defaultHashes := candidateHashes[0:1]
+ preferredHashes := signed.PrimaryIdentity().SelfSignature.PreferredHash
+ if len(preferredHashes) == 0 {
+ preferredHashes = defaultHashes
+ }
+ candidateHashes = intersectPreferences(candidateHashes, preferredHashes)
+ if len(candidateHashes) == 0 {
+ return nil, errors.InvalidArgumentError("cannot sign because signing key shares no common algorithms with candidate hashes")
+ }
+
+ return writeAndSign(noOpCloser{output}, candidateHashes, signed, hints, packet.SigTypeBinary, config)
+}
+
+// signatureWriter hashes the contents of a message while passing it along to
+// literalData. When closed, it closes literalData, writes a signature packet
+// to encryptedData and then also closes encryptedData.
+type signatureWriter struct {
+ encryptedData io.WriteCloser
+ literalData io.WriteCloser
+ hashType crypto.Hash
+ wrappedHash hash.Hash
+ h hash.Hash
+ signer *packet.PrivateKey
+ sigType packet.SignatureType
+ config *packet.Config
+ metadata *packet.LiteralData // V5 signatures protect document metadata
+}
+
+func (s signatureWriter) Write(data []byte) (int, error) {
+ s.wrappedHash.Write(data)
+ switch s.sigType {
+ case packet.SigTypeBinary:
+ return s.literalData.Write(data)
+ case packet.SigTypeText:
+ flag := 0
+ return writeCanonical(s.literalData, data, &flag)
+ }
+ return 0, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(s.sigType)))
+}
+
+func (s signatureWriter) Close() error {
+ sig := createSignaturePacket(&s.signer.PublicKey, s.sigType, s.config)
+ sig.Hash = s.hashType
+ sig.Metadata = s.metadata
+
+ if err := sig.Sign(s.h, s.signer, s.config); err != nil {
+ return err
+ }
+ if err := s.literalData.Close(); err != nil {
+ return err
+ }
+ if err := sig.Serialize(s.encryptedData); err != nil {
+ return err
+ }
+ return s.encryptedData.Close()
+}
+
+func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureType, config *packet.Config) *packet.Signature {
+ sigLifetimeSecs := config.SigLifetime()
+ return &packet.Signature{
+ Version: signer.Version,
+ SigType: sigType,
+ PubKeyAlgo: signer.PubKeyAlgo,
+ Hash: config.Hash(),
+ CreationTime: config.Now(),
+ IssuerKeyId: &signer.KeyId,
+ IssuerFingerprint: signer.Fingerprint,
+ Notations: config.Notations(),
+ SigLifetimeSecs: &sigLifetimeSecs,
+ }
+}
+
+// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
+// TODO: we have two of these in OpenPGP packages alone. This probably needs
+// to be promoted somewhere more common.
+type noOpCloser struct {
+ w io.Writer
+}
+
+func (c noOpCloser) Write(data []byte) (n int, err error) {
+ return c.w.Write(data)
+}
+
+func (c noOpCloser) Close() error {
+ return nil
+}
+
+func handleCompression(compressed io.WriteCloser, candidateCompression []uint8, config *packet.Config) (data io.WriteCloser, err error) {
+ data = compressed
+ confAlgo := config.Compression()
+ if confAlgo == packet.CompressionNone {
+ return
+ }
+
+ // Set algorithm labelled as MUST as fallback
+ // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.4
+ finalAlgo := packet.CompressionNone
+ // if compression specified by config available we will use it
+ for _, c := range candidateCompression {
+ if uint8(confAlgo) == c {
+ finalAlgo = confAlgo
+ break
+ }
+ }
+
+ if finalAlgo != packet.CompressionNone {
+ var compConfig *packet.CompressionConfig
+ if config != nil {
+ compConfig = config.CompressionConfig
+ }
+ data, err = packet.SerializeCompressed(compressed, finalAlgo, compConfig)
+ if err != nil {
+ return
+ }
+ }
+ return data, nil
+}
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..b7723185
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
@@ -0,0 +1,156 @@
+// +build amd64
+
+#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..810aa9e6
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
@@ -0,0 +1,193 @@
+// +build amd64
+
+#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, ¶mD) // 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, ¶mD) // 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, ¶mD) // 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, ¶mDTwist) // 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/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/github.com/cloudflare/circl/internal/sha3/xor_generic.go b/vendor/github.com/cloudflare/circl/internal/sha3/xor_generic.go
new file mode 100644
index 00000000..2b0c6617
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/xor_generic.go
@@ -0,0 +1,33 @@
+// 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 || appengine) && (!386 || appengine) && (!ppc64le || appengine)
+// +build !amd64 appengine
+// +build !386 appengine
+// +build !ppc64le appengine
+
+package sha3
+
+import "encoding/binary"
+
+// xorIn xors the bytes in buf into the state; it
+// makes no non-portable assumptions about memory layout
+// or alignment.
+func xorIn(d *State, buf []byte) {
+ n := len(buf) / 8
+
+ for i := 0; i < n; i++ {
+ a := binary.LittleEndian.Uint64(buf)
+ d.a[i] ^= a
+ buf = buf[8:]
+ }
+}
+
+// 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/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go b/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go
new file mode 100644
index 00000000..052fc8d3
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go
@@ -0,0 +1,61 @@
+// 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
+// +build !appengine
+
+package sha3
+
+import "unsafe"
+
+// A storageBuf is an aligned array of maxRate bytes.
+type storageBuf [maxRate / 8]uint64
+
+func (b *storageBuf) asBytes() *[maxRate]byte {
+ return (*[maxRate]byte)(unsafe.Pointer(b))
+}
+
+// xorInuses unaligned reads and writes to update d.a to contain d.a
+// XOR buf.
+func xorIn(d *State, buf []byte) {
+ n := len(buf)
+ bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
+ if n >= 72 {
+ d.a[0] ^= bw[0]
+ d.a[1] ^= bw[1]
+ d.a[2] ^= bw[2]
+ d.a[3] ^= bw[3]
+ d.a[4] ^= bw[4]
+ d.a[5] ^= bw[5]
+ d.a[6] ^= bw[6]
+ d.a[7] ^= bw[7]
+ d.a[8] ^= bw[8]
+ }
+ if n >= 104 {
+ d.a[9] ^= bw[9]
+ d.a[10] ^= bw[10]
+ d.a[11] ^= bw[11]
+ d.a[12] ^= bw[12]
+ }
+ if n >= 136 {
+ d.a[13] ^= bw[13]
+ d.a[14] ^= bw[14]
+ d.a[15] ^= bw[15]
+ d.a[16] ^= bw[16]
+ }
+ if n >= 144 {
+ d.a[17] ^= bw[17]
+ }
+ if n >= 168 {
+ d.a[18] ^= bw[18]
+ d.a[19] ^= bw[19]
+ d.a[20] ^= bw[20]
+ }
+}
+
+func copyOut(d *State, buf []byte) {
+ ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
+ copy(buf, ab[:])
+}
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> 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..435addf5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
@@ -0,0 +1,74 @@
+// +build amd64
+
+#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/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, ¶mD) // 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, ¶mD)
+ 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/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/emirpasic/gods/LICENSE b/vendor/github.com/emirpasic/gods/LICENSE
new file mode 100644
index 00000000..e5e449b6
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/LICENSE
@@ -0,0 +1,41 @@
+Copyright (c) 2015, Emir Pasic
+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.
+
+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.
+
+-------------------------------------------------------------------------------
+
+AVL Tree:
+
+Copyright (c) 2017 Benjamin Scher Purcell
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/vendor/github.com/emirpasic/gods/containers/containers.go b/vendor/github.com/emirpasic/gods/containers/containers.go
new file mode 100644
index 00000000..a512a3cb
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/containers/containers.go
@@ -0,0 +1,36 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package containers provides core interfaces and functions for data structures.
+//
+// Container is the base interface for all data structures to implement.
+//
+// Iterators provide stateful iterators.
+//
+// Enumerable provides Ruby inspired (each, select, map, find, any?, etc.) container functions.
+//
+// Serialization provides serializers (marshalers) and deserializers (unmarshalers).
+package containers
+
+import "github.com/emirpasic/gods/utils"
+
+// Container is base interface that all data structures implement.
+type Container interface {
+ Empty() bool
+ Size() int
+ Clear()
+ Values() []interface{}
+ String() string
+}
+
+// GetSortedValues returns sorted container's elements with respect to the passed comparator.
+// Does not affect the ordering of elements within the container.
+func GetSortedValues(container Container, comparator utils.Comparator) []interface{} {
+ values := container.Values()
+ if len(values) < 2 {
+ return values
+ }
+ utils.Sort(values, comparator)
+ return values
+}
diff --git a/vendor/github.com/emirpasic/gods/containers/enumerable.go b/vendor/github.com/emirpasic/gods/containers/enumerable.go
new file mode 100644
index 00000000..70660054
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/containers/enumerable.go
@@ -0,0 +1,57 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package containers
+
+// EnumerableWithIndex provides functions for ordered containers whose values can be fetched by an index.
+type EnumerableWithIndex interface {
+ // Each calls the given function once for each element, passing that element's index and value.
+ Each(func(index int, value interface{}))
+
+ // Map invokes the given function once for each element and returns a
+ // container containing the values returned by the given function.
+ // Map(func(index int, value interface{}) interface{}) Container
+
+ // Select returns a new container containing all elements for which the given function returns a true value.
+ // Select(func(index int, value interface{}) bool) Container
+
+ // Any passes each element of the container to the given function and
+ // returns true if the function ever returns true for any element.
+ Any(func(index int, value interface{}) bool) bool
+
+ // All passes each element of the container to the given function and
+ // returns true if the function returns true for all elements.
+ All(func(index int, value interface{}) bool) bool
+
+ // Find passes each element of the container to the given function and returns
+ // the first (index,value) for which the function is true or -1,nil otherwise
+ // if no element matches the criteria.
+ Find(func(index int, value interface{}) bool) (int, interface{})
+}
+
+// EnumerableWithKey provides functions for ordered containers whose values whose elements are key/value pairs.
+type EnumerableWithKey interface {
+ // Each calls the given function once for each element, passing that element's key and value.
+ Each(func(key interface{}, value interface{}))
+
+ // Map invokes the given function once for each element and returns a container
+ // containing the values returned by the given function as key/value pairs.
+ // Map(func(key interface{}, value interface{}) (interface{}, interface{})) Container
+
+ // Select returns a new container containing all elements for which the given function returns a true value.
+ // Select(func(key interface{}, value interface{}) bool) Container
+
+ // Any passes each element of the container to the given function and
+ // returns true if the function ever returns true for any element.
+ Any(func(key interface{}, value interface{}) bool) bool
+
+ // All passes each element of the container to the given function and
+ // returns true if the function returns true for all elements.
+ All(func(key interface{}, value interface{}) bool) bool
+
+ // Find passes each element of the container to the given function and returns
+ // the first (key,value) for which the function is true or nil,nil otherwise if no element
+ // matches the criteria.
+ Find(func(key interface{}, value interface{}) bool) (interface{}, interface{})
+}
diff --git a/vendor/github.com/emirpasic/gods/containers/iterator.go b/vendor/github.com/emirpasic/gods/containers/iterator.go
new file mode 100644
index 00000000..73994ec8
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/containers/iterator.go
@@ -0,0 +1,133 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package containers
+
+// IteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.
+type IteratorWithIndex interface {
+ // Next moves the iterator to the next element and returns true if there was a next element in the container.
+ // If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
+ // If Next() was called for the first time, then it will point the iterator to the first element if it exists.
+ // Modifies the state of the iterator.
+ Next() bool
+
+ // Value returns the current element's value.
+ // Does not modify the state of the iterator.
+ Value() interface{}
+
+ // Index returns the current element's index.
+ // Does not modify the state of the iterator.
+ Index() int
+
+ // Begin resets the iterator to its initial state (one-before-first)
+ // Call Next() to fetch the first element if any.
+ Begin()
+
+ // First moves the iterator to the first element and returns true if there was a first element in the container.
+ // If First() returns true, then first element's index and value can be retrieved by Index() and Value().
+ // Modifies the state of the iterator.
+ First() bool
+
+ // NextTo moves the iterator to the next element from current position that satisfies the condition given by the
+ // passed function, and returns true if there was a next element in the container.
+ // If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
+ // Modifies the state of the iterator.
+ NextTo(func(index int, value interface{}) bool) bool
+}
+
+// IteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
+type IteratorWithKey interface {
+ // Next moves the iterator to the next element and returns true if there was a next element in the container.
+ // If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
+ // If Next() was called for the first time, then it will point the iterator to the first element if it exists.
+ // Modifies the state of the iterator.
+ Next() bool
+
+ // Value returns the current element's value.
+ // Does not modify the state of the iterator.
+ Value() interface{}
+
+ // Key returns the current element's key.
+ // Does not modify the state of the iterator.
+ Key() interface{}
+
+ // Begin resets the iterator to its initial state (one-before-first)
+ // Call Next() to fetch the first element if any.
+ Begin()
+
+ // First moves the iterator to the first element and returns true if there was a first element in the container.
+ // If First() returns true, then first element's key and value can be retrieved by Key() and Value().
+ // Modifies the state of the iterator.
+ First() bool
+
+ // NextTo moves the iterator to the next element from current position that satisfies the condition given by the
+ // passed function, and returns true if there was a next element in the container.
+ // If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().
+ // Modifies the state of the iterator.
+ NextTo(func(key interface{}, value interface{}) bool) bool
+}
+
+// ReverseIteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.
+//
+// Essentially it is the same as IteratorWithIndex, but provides additional:
+//
+// Prev() function to enable traversal in reverse
+//
+// Last() function to move the iterator to the last element.
+//
+// End() function to move the iterator past the last element (one-past-the-end).
+type ReverseIteratorWithIndex interface {
+ // Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
+ // If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
+ // Modifies the state of the iterator.
+ Prev() bool
+
+ // End moves the iterator past the last element (one-past-the-end).
+ // Call Prev() to fetch the last element if any.
+ End()
+
+ // Last moves the iterator to the last element and returns true if there was a last element in the container.
+ // If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
+ // Modifies the state of the iterator.
+ Last() bool
+
+ // PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
+ // passed function, and returns true if there was a next element in the container.
+ // If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
+ // Modifies the state of the iterator.
+ PrevTo(func(index int, value interface{}) bool) bool
+
+ IteratorWithIndex
+}
+
+// ReverseIteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
+//
+// Essentially it is the same as IteratorWithKey, but provides additional:
+//
+// Prev() function to enable traversal in reverse
+//
+// Last() function to move the iterator to the last element.
+type ReverseIteratorWithKey interface {
+ // Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
+ // If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
+ // Modifies the state of the iterator.
+ Prev() bool
+
+ // End moves the iterator past the last element (one-past-the-end).
+ // Call Prev() to fetch the last element if any.
+ End()
+
+ // Last moves the iterator to the last element and returns true if there was a last element in the container.
+ // If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
+ // Modifies the state of the iterator.
+ Last() bool
+
+ // PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
+ // passed function, and returns true if there was a next element in the container.
+ // If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().
+ // Modifies the state of the iterator.
+ PrevTo(func(key interface{}, value interface{}) bool) bool
+
+ IteratorWithKey
+}
diff --git a/vendor/github.com/emirpasic/gods/containers/serialization.go b/vendor/github.com/emirpasic/gods/containers/serialization.go
new file mode 100644
index 00000000..fd9cbe23
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/containers/serialization.go
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package containers
+
+// JSONSerializer provides JSON serialization
+type JSONSerializer interface {
+ // ToJSON outputs the JSON representation of containers's elements.
+ ToJSON() ([]byte, error)
+ // MarshalJSON @implements json.Marshaler
+ MarshalJSON() ([]byte, error)
+}
+
+// JSONDeserializer provides JSON deserialization
+type JSONDeserializer interface {
+ // FromJSON populates containers's elements from the input JSON representation.
+ FromJSON([]byte) error
+ // UnmarshalJSON @implements json.Unmarshaler
+ UnmarshalJSON([]byte) error
+}
diff --git a/vendor/github.com/emirpasic/gods/lists/arraylist/arraylist.go b/vendor/github.com/emirpasic/gods/lists/arraylist/arraylist.go
new file mode 100644
index 00000000..60ce4583
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/lists/arraylist/arraylist.go
@@ -0,0 +1,227 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package arraylist implements the array list.
+//
+// Structure is not thread safe.
+//
+// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29
+package arraylist
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/emirpasic/gods/lists"
+ "github.com/emirpasic/gods/utils"
+)
+
+// Assert List implementation
+var _ lists.List = (*List)(nil)
+
+// List holds the elements in a slice
+type List struct {
+ elements []interface{}
+ size int
+}
+
+const (
+ growthFactor = float32(2.0) // growth by 100%
+ shrinkFactor = float32(0.25) // shrink when size is 25% of capacity (0 means never shrink)
+)
+
+// New instantiates a new list and adds the passed values, if any, to the list
+func New(values ...interface{}) *List {
+ list := &List{}
+ if len(values) > 0 {
+ list.Add(values...)
+ }
+ return list
+}
+
+// Add appends a value at the end of the list
+func (list *List) Add(values ...interface{}) {
+ list.growBy(len(values))
+ for _, value := range values {
+ list.elements[list.size] = value
+ list.size++
+ }
+}
+
+// Get returns the element at index.
+// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.
+func (list *List) Get(index int) (interface{}, bool) {
+
+ if !list.withinRange(index) {
+ return nil, false
+ }
+
+ return list.elements[index], true
+}
+
+// Remove removes the element at the given index from the list.
+func (list *List) Remove(index int) {
+
+ if !list.withinRange(index) {
+ return
+ }
+
+ list.elements[index] = nil // cleanup reference
+ copy(list.elements[index:], list.elements[index+1:list.size]) // shift to the left by one (slow operation, need ways to optimize this)
+ list.size--
+
+ list.shrink()
+}
+
+// Contains checks if elements (one or more) are present in the set.
+// All elements have to be present in the set for the method to return true.
+// Performance time complexity of n^2.
+// Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.
+func (list *List) Contains(values ...interface{}) bool {
+
+ for _, searchValue := range values {
+ found := false
+ for index := 0; index < list.size; index++ {
+ if list.elements[index] == searchValue {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return false
+ }
+ }
+ return true
+}
+
+// Values returns all elements in the list.
+func (list *List) Values() []interface{} {
+ newElements := make([]interface{}, list.size, list.size)
+ copy(newElements, list.elements[:list.size])
+ return newElements
+}
+
+//IndexOf returns index of provided element
+func (list *List) IndexOf(value interface{}) int {
+ if list.size == 0 {
+ return -1
+ }
+ for index, element := range list.elements {
+ if element == value {
+ return index
+ }
+ }
+ return -1
+}
+
+// Empty returns true if list does not contain any elements.
+func (list *List) Empty() bool {
+ return list.size == 0
+}
+
+// Size returns number of elements within the list.
+func (list *List) Size() int {
+ return list.size
+}
+
+// Clear removes all elements from the list.
+func (list *List) Clear() {
+ list.size = 0
+ list.elements = []interface{}{}
+}
+
+// Sort sorts values (in-place) using.
+func (list *List) Sort(comparator utils.Comparator) {
+ if len(list.elements) < 2 {
+ return
+ }
+ utils.Sort(list.elements[:list.size], comparator)
+}
+
+// Swap swaps the two values at the specified positions.
+func (list *List) Swap(i, j int) {
+ if list.withinRange(i) && list.withinRange(j) {
+ list.elements[i], list.elements[j] = list.elements[j], list.elements[i]
+ }
+}
+
+// Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.
+// Does not do anything if position is negative or bigger than list's size
+// Note: position equal to list's size is valid, i.e. append.
+func (list *List) Insert(index int, values ...interface{}) {
+
+ if !list.withinRange(index) {
+ // Append
+ if index == list.size {
+ list.Add(values...)
+ }
+ return
+ }
+
+ l := len(values)
+ list.growBy(l)
+ list.size += l
+ copy(list.elements[index+l:], list.elements[index:list.size-l])
+ copy(list.elements[index:], values)
+}
+
+// Set the value at specified index
+// Does not do anything if position is negative or bigger than list's size
+// Note: position equal to list's size is valid, i.e. append.
+func (list *List) Set(index int, value interface{}) {
+
+ if !list.withinRange(index) {
+ // Append
+ if index == list.size {
+ list.Add(value)
+ }
+ return
+ }
+
+ list.elements[index] = value
+}
+
+// String returns a string representation of container
+func (list *List) String() string {
+ str := "ArrayList\n"
+ values := []string{}
+ for _, value := range list.elements[:list.size] {
+ values = append(values, fmt.Sprintf("%v", value))
+ }
+ str += strings.Join(values, ", ")
+ return str
+}
+
+// Check that the index is within bounds of the list
+func (list *List) withinRange(index int) bool {
+ return index >= 0 && index < list.size
+}
+
+func (list *List) resize(cap int) {
+ newElements := make([]interface{}, cap, cap)
+ copy(newElements, list.elements)
+ list.elements = newElements
+}
+
+// Expand the array if necessary, i.e. capacity will be reached if we add n elements
+func (list *List) growBy(n int) {
+ // When capacity is reached, grow by a factor of growthFactor and add number of elements
+ currentCapacity := cap(list.elements)
+ if list.size+n >= currentCapacity {
+ newCapacity := int(growthFactor * float32(currentCapacity+n))
+ list.resize(newCapacity)
+ }
+}
+
+// Shrink the array if necessary, i.e. when size is shrinkFactor percent of current capacity
+func (list *List) shrink() {
+ if shrinkFactor == 0.0 {
+ return
+ }
+ // Shrink when size is at shrinkFactor * capacity
+ currentCapacity := cap(list.elements)
+ if list.size <= int(float32(currentCapacity)*shrinkFactor) {
+ list.resize(list.size)
+ }
+}
diff --git a/vendor/github.com/emirpasic/gods/lists/arraylist/enumerable.go b/vendor/github.com/emirpasic/gods/lists/arraylist/enumerable.go
new file mode 100644
index 00000000..8bd60b0a
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/lists/arraylist/enumerable.go
@@ -0,0 +1,78 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arraylist
+
+import "github.com/emirpasic/gods/containers"
+
+// Assert Enumerable implementation
+var _ containers.EnumerableWithIndex = (*List)(nil)
+
+// Each calls the given function once for each element, passing that element's index and value.
+func (list *List) Each(f func(index int, value interface{})) {
+ iterator := list.Iterator()
+ for iterator.Next() {
+ f(iterator.Index(), iterator.Value())
+ }
+}
+
+// Map invokes the given function once for each element and returns a
+// container containing the values returned by the given function.
+func (list *List) Map(f func(index int, value interface{}) interface{}) *List {
+ newList := &List{}
+ iterator := list.Iterator()
+ for iterator.Next() {
+ newList.Add(f(iterator.Index(), iterator.Value()))
+ }
+ return newList
+}
+
+// Select returns a new container containing all elements for which the given function returns a true value.
+func (list *List) Select(f func(index int, value interface{}) bool) *List {
+ newList := &List{}
+ iterator := list.Iterator()
+ for iterator.Next() {
+ if f(iterator.Index(), iterator.Value()) {
+ newList.Add(iterator.Value())
+ }
+ }
+ return newList
+}
+
+// Any passes each element of the collection to the given function and
+// returns true if the function ever returns true for any element.
+func (list *List) Any(f func(index int, value interface{}) bool) bool {
+ iterator := list.Iterator()
+ for iterator.Next() {
+ if f(iterator.Index(), iterator.Value()) {
+ return true
+ }
+ }
+ return false
+}
+
+// All passes each element of the collection to the given function and
+// returns true if the function returns true for all elements.
+func (list *List) All(f func(index int, value interface{}) bool) bool {
+ iterator := list.Iterator()
+ for iterator.Next() {
+ if !f(iterator.Index(), iterator.Value()) {
+ return false
+ }
+ }
+ return true
+}
+
+// Find passes each element of the container to the given function and returns
+// the first (index,value) for which the function is true or -1,nil otherwise
+// if no element matches the criteria.
+func (list *List) Find(f func(index int, value interface{}) bool) (int, interface{}) {
+ iterator := list.Iterator()
+ for iterator.Next() {
+ if f(iterator.Index(), iterator.Value()) {
+ return iterator.Index(), iterator.Value()
+ }
+ }
+ return -1, nil
+}
diff --git a/vendor/github.com/emirpasic/gods/lists/arraylist/iterator.go b/vendor/github.com/emirpasic/gods/lists/arraylist/iterator.go
new file mode 100644
index 00000000..f9efe20c
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/lists/arraylist/iterator.go
@@ -0,0 +1,110 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arraylist
+
+import "github.com/emirpasic/gods/containers"
+
+// Assert Iterator implementation
+var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil)
+
+// Iterator holding the iterator's state
+type Iterator struct {
+ list *List
+ index int
+}
+
+// Iterator returns a stateful iterator whose values can be fetched by an index.
+func (list *List) Iterator() Iterator {
+ return Iterator{list: list, index: -1}
+}
+
+// Next moves the iterator to the next element and returns true if there was a next element in the container.
+// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
+// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
+// Modifies the state of the iterator.
+func (iterator *Iterator) Next() bool {
+ if iterator.index < iterator.list.size {
+ iterator.index++
+ }
+ return iterator.list.withinRange(iterator.index)
+}
+
+// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
+// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) Prev() bool {
+ if iterator.index >= 0 {
+ iterator.index--
+ }
+ return iterator.list.withinRange(iterator.index)
+}
+
+// Value returns the current element's value.
+// Does not modify the state of the iterator.
+func (iterator *Iterator) Value() interface{} {
+ return iterator.list.elements[iterator.index]
+}
+
+// Index returns the current element's index.
+// Does not modify the state of the iterator.
+func (iterator *Iterator) Index() int {
+ return iterator.index
+}
+
+// Begin resets the iterator to its initial state (one-before-first)
+// Call Next() to fetch the first element if any.
+func (iterator *Iterator) Begin() {
+ iterator.index = -1
+}
+
+// End moves the iterator past the last element (one-past-the-end).
+// Call Prev() to fetch the last element if any.
+func (iterator *Iterator) End() {
+ iterator.index = iterator.list.size
+}
+
+// First moves the iterator to the first element and returns true if there was a first element in the container.
+// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) First() bool {
+ iterator.Begin()
+ return iterator.Next()
+}
+
+// Last moves the iterator to the last element and returns true if there was a last element in the container.
+// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) Last() bool {
+ iterator.End()
+ return iterator.Prev()
+}
+
+// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
+// passed function, and returns true if there was a next element in the container.
+// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
+ for iterator.Next() {
+ index, value := iterator.Index(), iterator.Value()
+ if f(index, value) {
+ return true
+ }
+ }
+ return false
+}
+
+// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
+// passed function, and returns true if there was a next element in the container.
+// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) PrevTo(f func(index int, value interface{}) bool) bool {
+ for iterator.Prev() {
+ index, value := iterator.Index(), iterator.Value()
+ if f(index, value) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/emirpasic/gods/lists/arraylist/serialization.go b/vendor/github.com/emirpasic/gods/lists/arraylist/serialization.go
new file mode 100644
index 00000000..5e86fe96
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/lists/arraylist/serialization.go
@@ -0,0 +1,38 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package arraylist
+
+import (
+ "encoding/json"
+ "github.com/emirpasic/gods/containers"
+)
+
+// Assert Serialization implementation
+var _ containers.JSONSerializer = (*List)(nil)
+var _ containers.JSONDeserializer = (*List)(nil)
+
+// ToJSON outputs the JSON representation of list's elements.
+func (list *List) ToJSON() ([]byte, error) {
+ return json.Marshal(list.elements[:list.size])
+}
+
+// FromJSON populates list's elements from the input JSON representation.
+func (list *List) FromJSON(data []byte) error {
+ err := json.Unmarshal(data, &list.elements)
+ if err == nil {
+ list.size = len(list.elements)
+ }
+ return err
+}
+
+// UnmarshalJSON @implements json.Unmarshaler
+func (list *List) UnmarshalJSON(bytes []byte) error {
+ return list.FromJSON(bytes)
+}
+
+// MarshalJSON @implements json.Marshaler
+func (list *List) MarshalJSON() ([]byte, error) {
+ return list.ToJSON()
+}
diff --git a/vendor/github.com/emirpasic/gods/lists/lists.go b/vendor/github.com/emirpasic/gods/lists/lists.go
new file mode 100644
index 00000000..55bd619e
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/lists/lists.go
@@ -0,0 +1,34 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package lists provides an abstract List interface.
+//
+// In computer science, a list or sequence is an abstract data type that represents an ordered sequence of values, where the same value may occur more than once. An instance of a list is a computer representation of the mathematical concept of a finite sequence; the (potentially) infinite analog of a list is a stream. Lists are a basic example of containers, as they contain other values. If the same value occurs multiple times, each occurrence is considered a distinct item.
+//
+// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29
+package lists
+
+import (
+ "github.com/emirpasic/gods/containers"
+ "github.com/emirpasic/gods/utils"
+)
+
+// List interface that all lists implement
+type List interface {
+ Get(index int) (interface{}, bool)
+ Remove(index int)
+ Add(values ...interface{})
+ Contains(values ...interface{}) bool
+ Sort(comparator utils.Comparator)
+ Swap(index1, index2 int)
+ Insert(index int, values ...interface{})
+ Set(index int, value interface{})
+
+ containers.Container
+ // Empty() bool
+ // Size() int
+ // Clear()
+ // Values() []interface{}
+ // String() string
+}
diff --git a/vendor/github.com/emirpasic/gods/trees/binaryheap/binaryheap.go b/vendor/github.com/emirpasic/gods/trees/binaryheap/binaryheap.go
new file mode 100644
index 00000000..e658f257
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/trees/binaryheap/binaryheap.go
@@ -0,0 +1,166 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package binaryheap implements a binary heap backed by array list.
+//
+// Comparator defines this heap as either min or max heap.
+//
+// Structure is not thread safe.
+//
+// References: http://en.wikipedia.org/wiki/Binary_heap
+package binaryheap
+
+import (
+ "fmt"
+ "github.com/emirpasic/gods/lists/arraylist"
+ "github.com/emirpasic/gods/trees"
+ "github.com/emirpasic/gods/utils"
+ "strings"
+)
+
+// Assert Tree implementation
+var _ trees.Tree = (*Heap)(nil)
+
+// Heap holds elements in an array-list
+type Heap struct {
+ list *arraylist.List
+ Comparator utils.Comparator
+}
+
+// NewWith instantiates a new empty heap tree with the custom comparator.
+func NewWith(comparator utils.Comparator) *Heap {
+ return &Heap{list: arraylist.New(), Comparator: comparator}
+}
+
+// NewWithIntComparator instantiates a new empty heap with the IntComparator, i.e. elements are of type int.
+func NewWithIntComparator() *Heap {
+ return &Heap{list: arraylist.New(), Comparator: utils.IntComparator}
+}
+
+// NewWithStringComparator instantiates a new empty heap with the StringComparator, i.e. elements are of type string.
+func NewWithStringComparator() *Heap {
+ return &Heap{list: arraylist.New(), Comparator: utils.StringComparator}
+}
+
+// Push adds a value onto the heap and bubbles it up accordingly.
+func (heap *Heap) Push(values ...interface{}) {
+ if len(values) == 1 {
+ heap.list.Add(values[0])
+ heap.bubbleUp()
+ } else {
+ // Reference: https://en.wikipedia.org/wiki/Binary_heap#Building_a_heap
+ for _, value := range values {
+ heap.list.Add(value)
+ }
+ size := heap.list.Size()/2 + 1
+ for i := size; i >= 0; i-- {
+ heap.bubbleDownIndex(i)
+ }
+ }
+}
+
+// Pop removes top element on heap and returns it, or nil if heap is empty.
+// Second return parameter is true, unless the heap was empty and there was nothing to pop.
+func (heap *Heap) Pop() (value interface{}, ok bool) {
+ value, ok = heap.list.Get(0)
+ if !ok {
+ return
+ }
+ lastIndex := heap.list.Size() - 1
+ heap.list.Swap(0, lastIndex)
+ heap.list.Remove(lastIndex)
+ heap.bubbleDown()
+ return
+}
+
+// Peek returns top element on the heap without removing it, or nil if heap is empty.
+// Second return parameter is true, unless the heap was empty and there was nothing to peek.
+func (heap *Heap) Peek() (value interface{}, ok bool) {
+ return heap.list.Get(0)
+}
+
+// Empty returns true if heap does not contain any elements.
+func (heap *Heap) Empty() bool {
+ return heap.list.Empty()
+}
+
+// Size returns number of elements within the heap.
+func (heap *Heap) Size() int {
+ return heap.list.Size()
+}
+
+// Clear removes all elements from the heap.
+func (heap *Heap) Clear() {
+ heap.list.Clear()
+}
+
+// Values returns all elements in the heap.
+func (heap *Heap) Values() []interface{} {
+ values := make([]interface{}, heap.list.Size(), heap.list.Size())
+ for it := heap.Iterator(); it.Next(); {
+ values[it.Index()] = it.Value()
+ }
+ return values
+}
+
+// String returns a string representation of container
+func (heap *Heap) String() string {
+ str := "BinaryHeap\n"
+ values := []string{}
+ for it := heap.Iterator(); it.Next(); {
+ values = append(values, fmt.Sprintf("%v", it.Value()))
+ }
+ str += strings.Join(values, ", ")
+ return str
+}
+
+// Performs the "bubble down" operation. This is to place the element that is at the root
+// of the heap in its correct place so that the heap maintains the min/max-heap order property.
+func (heap *Heap) bubbleDown() {
+ heap.bubbleDownIndex(0)
+}
+
+// Performs the "bubble down" operation. This is to place the element that is at the index
+// of the heap in its correct place so that the heap maintains the min/max-heap order property.
+func (heap *Heap) bubbleDownIndex(index int) {
+ size := heap.list.Size()
+ for leftIndex := index<<1 + 1; leftIndex < size; leftIndex = index<<1 + 1 {
+ rightIndex := index<<1 + 2
+ smallerIndex := leftIndex
+ leftValue, _ := heap.list.Get(leftIndex)
+ rightValue, _ := heap.list.Get(rightIndex)
+ if rightIndex < size && heap.Comparator(leftValue, rightValue) > 0 {
+ smallerIndex = rightIndex
+ }
+ indexValue, _ := heap.list.Get(index)
+ smallerValue, _ := heap.list.Get(smallerIndex)
+ if heap.Comparator(indexValue, smallerValue) > 0 {
+ heap.list.Swap(index, smallerIndex)
+ } else {
+ break
+ }
+ index = smallerIndex
+ }
+}
+
+// Performs the "bubble up" operation. This is to place a newly inserted
+// element (i.e. last element in the list) in its correct place so that
+// the heap maintains the min/max-heap order property.
+func (heap *Heap) bubbleUp() {
+ index := heap.list.Size() - 1
+ for parentIndex := (index - 1) >> 1; index > 0; parentIndex = (index - 1) >> 1 {
+ indexValue, _ := heap.list.Get(index)
+ parentValue, _ := heap.list.Get(parentIndex)
+ if heap.Comparator(parentValue, indexValue) <= 0 {
+ break
+ }
+ heap.list.Swap(index, parentIndex)
+ index = parentIndex
+ }
+}
+
+// Check that the index is within bounds of the list
+func (heap *Heap) withinRange(index int) bool {
+ return index >= 0 && index < heap.list.Size()
+}
diff --git a/vendor/github.com/emirpasic/gods/trees/binaryheap/iterator.go b/vendor/github.com/emirpasic/gods/trees/binaryheap/iterator.go
new file mode 100644
index 00000000..f2179633
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/trees/binaryheap/iterator.go
@@ -0,0 +1,143 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package binaryheap
+
+import (
+ "github.com/emirpasic/gods/containers"
+)
+
+// Assert Iterator implementation
+var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil)
+
+// Iterator returns a stateful iterator whose values can be fetched by an index.
+type Iterator struct {
+ heap *Heap
+ index int
+}
+
+// Iterator returns a stateful iterator whose values can be fetched by an index.
+func (heap *Heap) Iterator() Iterator {
+ return Iterator{heap: heap, index: -1}
+}
+
+// Next moves the iterator to the next element and returns true if there was a next element in the container.
+// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
+// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
+// Modifies the state of the iterator.
+func (iterator *Iterator) Next() bool {
+ if iterator.index < iterator.heap.Size() {
+ iterator.index++
+ }
+ return iterator.heap.withinRange(iterator.index)
+}
+
+// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
+// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) Prev() bool {
+ if iterator.index >= 0 {
+ iterator.index--
+ }
+ return iterator.heap.withinRange(iterator.index)
+}
+
+// Value returns the current element's value.
+// Does not modify the state of the iterator.
+func (iterator *Iterator) Value() interface{} {
+ start, end := evaluateRange(iterator.index)
+ if end > iterator.heap.Size() {
+ end = iterator.heap.Size()
+ }
+ tmpHeap := NewWith(iterator.heap.Comparator)
+ for n := start; n < end; n++ {
+ value, _ := iterator.heap.list.Get(n)
+ tmpHeap.Push(value)
+ }
+ for n := 0; n < iterator.index-start; n++ {
+ tmpHeap.Pop()
+ }
+ value, _ := tmpHeap.Pop()
+ return value
+}
+
+// Index returns the current element's index.
+// Does not modify the state of the iterator.
+func (iterator *Iterator) Index() int {
+ return iterator.index
+}
+
+// Begin resets the iterator to its initial state (one-before-first)
+// Call Next() to fetch the first element if any.
+func (iterator *Iterator) Begin() {
+ iterator.index = -1
+}
+
+// End moves the iterator past the last element (one-past-the-end).
+// Call Prev() to fetch the last element if any.
+func (iterator *Iterator) End() {
+ iterator.index = iterator.heap.Size()
+}
+
+// First moves the iterator to the first element and returns true if there was a first element in the container.
+// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) First() bool {
+ iterator.Begin()
+ return iterator.Next()
+}
+
+// Last moves the iterator to the last element and returns true if there was a last element in the container.
+// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) Last() bool {
+ iterator.End()
+ return iterator.Prev()
+}
+
+// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
+// passed function, and returns true if there was a next element in the container.
+// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
+ for iterator.Next() {
+ index, value := iterator.Index(), iterator.Value()
+ if f(index, value) {
+ return true
+ }
+ }
+ return false
+}
+
+// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
+// passed function, and returns true if there was a next element in the container.
+// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
+// Modifies the state of the iterator.
+func (iterator *Iterator) PrevTo(f func(index int, value interface{}) bool) bool {
+ for iterator.Prev() {
+ index, value := iterator.Index(), iterator.Value()
+ if f(index, value) {
+ return true
+ }
+ }
+ return false
+}
+
+// numOfBits counts the number of bits of an int
+func numOfBits(n int) uint {
+ var count uint
+ for n != 0 {
+ count++
+ n >>= 1
+ }
+ return count
+}
+
+// evaluateRange evaluates the index range [start,end) of same level nodes in the heap as the index
+func evaluateRange(index int) (start int, end int) {
+ bits := numOfBits(index+1) - 1
+ start = 1< b
+type Comparator func(a, b interface{}) int
+
+// StringComparator provides a fast comparison on strings
+func StringComparator(a, b interface{}) int {
+ s1 := a.(string)
+ s2 := b.(string)
+ min := len(s2)
+ if len(s1) < len(s2) {
+ min = len(s1)
+ }
+ diff := 0
+ for i := 0; i < min && diff == 0; i++ {
+ diff = int(s1[i]) - int(s2[i])
+ }
+ if diff == 0 {
+ diff = len(s1) - len(s2)
+ }
+ if diff < 0 {
+ return -1
+ }
+ if diff > 0 {
+ return 1
+ }
+ return 0
+}
+
+// IntComparator provides a basic comparison on int
+func IntComparator(a, b interface{}) int {
+ aAsserted := a.(int)
+ bAsserted := b.(int)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// Int8Comparator provides a basic comparison on int8
+func Int8Comparator(a, b interface{}) int {
+ aAsserted := a.(int8)
+ bAsserted := b.(int8)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// Int16Comparator provides a basic comparison on int16
+func Int16Comparator(a, b interface{}) int {
+ aAsserted := a.(int16)
+ bAsserted := b.(int16)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// Int32Comparator provides a basic comparison on int32
+func Int32Comparator(a, b interface{}) int {
+ aAsserted := a.(int32)
+ bAsserted := b.(int32)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// Int64Comparator provides a basic comparison on int64
+func Int64Comparator(a, b interface{}) int {
+ aAsserted := a.(int64)
+ bAsserted := b.(int64)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// UIntComparator provides a basic comparison on uint
+func UIntComparator(a, b interface{}) int {
+ aAsserted := a.(uint)
+ bAsserted := b.(uint)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// UInt8Comparator provides a basic comparison on uint8
+func UInt8Comparator(a, b interface{}) int {
+ aAsserted := a.(uint8)
+ bAsserted := b.(uint8)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// UInt16Comparator provides a basic comparison on uint16
+func UInt16Comparator(a, b interface{}) int {
+ aAsserted := a.(uint16)
+ bAsserted := b.(uint16)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// UInt32Comparator provides a basic comparison on uint32
+func UInt32Comparator(a, b interface{}) int {
+ aAsserted := a.(uint32)
+ bAsserted := b.(uint32)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// UInt64Comparator provides a basic comparison on uint64
+func UInt64Comparator(a, b interface{}) int {
+ aAsserted := a.(uint64)
+ bAsserted := b.(uint64)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// Float32Comparator provides a basic comparison on float32
+func Float32Comparator(a, b interface{}) int {
+ aAsserted := a.(float32)
+ bAsserted := b.(float32)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// Float64Comparator provides a basic comparison on float64
+func Float64Comparator(a, b interface{}) int {
+ aAsserted := a.(float64)
+ bAsserted := b.(float64)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// ByteComparator provides a basic comparison on byte
+func ByteComparator(a, b interface{}) int {
+ aAsserted := a.(byte)
+ bAsserted := b.(byte)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// RuneComparator provides a basic comparison on rune
+func RuneComparator(a, b interface{}) int {
+ aAsserted := a.(rune)
+ bAsserted := b.(rune)
+ switch {
+ case aAsserted > bAsserted:
+ return 1
+ case aAsserted < bAsserted:
+ return -1
+ default:
+ return 0
+ }
+}
+
+// TimeComparator provides a basic comparison on time.Time
+func TimeComparator(a, b interface{}) int {
+ aAsserted := a.(time.Time)
+ bAsserted := b.(time.Time)
+
+ switch {
+ case aAsserted.After(bAsserted):
+ return 1
+ case aAsserted.Before(bAsserted):
+ return -1
+ default:
+ return 0
+ }
+}
diff --git a/vendor/github.com/emirpasic/gods/utils/sort.go b/vendor/github.com/emirpasic/gods/utils/sort.go
new file mode 100644
index 00000000..79ced1f5
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/utils/sort.go
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package utils
+
+import "sort"
+
+// Sort sorts values (in-place) with respect to the given comparator.
+//
+// Uses Go's sort (hybrid of quicksort for large and then insertion sort for smaller slices).
+func Sort(values []interface{}, comparator Comparator) {
+ sort.Sort(sortable{values, comparator})
+}
+
+type sortable struct {
+ values []interface{}
+ comparator Comparator
+}
+
+func (s sortable) Len() int {
+ return len(s.values)
+}
+func (s sortable) Swap(i, j int) {
+ s.values[i], s.values[j] = s.values[j], s.values[i]
+}
+func (s sortable) Less(i, j int) bool {
+ return s.comparator(s.values[i], s.values[j]) < 0
+}
diff --git a/vendor/github.com/emirpasic/gods/utils/utils.go b/vendor/github.com/emirpasic/gods/utils/utils.go
new file mode 100644
index 00000000..262c6257
--- /dev/null
+++ b/vendor/github.com/emirpasic/gods/utils/utils.go
@@ -0,0 +1,47 @@
+// Copyright (c) 2015, Emir Pasic. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package utils provides common utility functions.
+//
+// Provided functionalities:
+// - sorting
+// - comparators
+package utils
+
+import (
+ "fmt"
+ "strconv"
+)
+
+// ToString converts a value to string.
+func ToString(value interface{}) string {
+ switch value := value.(type) {
+ case string:
+ return value
+ case int8:
+ return strconv.FormatInt(int64(value), 10)
+ case int16:
+ return strconv.FormatInt(int64(value), 10)
+ case int32:
+ return strconv.FormatInt(int64(value), 10)
+ case int64:
+ return strconv.FormatInt(value, 10)
+ case uint8:
+ return strconv.FormatUint(uint64(value), 10)
+ case uint16:
+ return strconv.FormatUint(uint64(value), 10)
+ case uint32:
+ return strconv.FormatUint(uint64(value), 10)
+ case uint64:
+ return strconv.FormatUint(value, 10)
+ case float32:
+ return strconv.FormatFloat(float64(value), 'g', -1, 64)
+ case float64:
+ return strconv.FormatFloat(value, 'g', -1, 64)
+ case bool:
+ return strconv.FormatBool(value)
+ default:
+ return fmt.Sprintf("%+v", value)
+ }
+}
diff --git a/vendor/github.com/go-git/gcfg/.gitignore b/vendor/github.com/go-git/gcfg/.gitignore
new file mode 100644
index 00000000..2d830686
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/.gitignore
@@ -0,0 +1 @@
+coverage.out
diff --git a/vendor/github.com/go-git/gcfg/LICENSE b/vendor/github.com/go-git/gcfg/LICENSE
new file mode 100644
index 00000000..87a5cede
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2012 Péter Surányi. Portions 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/go-git/gcfg/Makefile b/vendor/github.com/go-git/gcfg/Makefile
new file mode 100644
index 00000000..73604da6
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/Makefile
@@ -0,0 +1,17 @@
+# General
+WORKDIR = $(PWD)
+
+# Go parameters
+GOCMD = go
+GOTEST = $(GOCMD) test
+
+# Coverage
+COVERAGE_REPORT = coverage.out
+COVERAGE_MODE = count
+
+test:
+ $(GOTEST) ./...
+
+test-coverage:
+ echo "" > $(COVERAGE_REPORT); \
+ $(GOTEST) -coverprofile=$(COVERAGE_REPORT) -coverpkg=./... -covermode=$(COVERAGE_MODE) ./...
diff --git a/vendor/github.com/go-git/gcfg/README b/vendor/github.com/go-git/gcfg/README
new file mode 100644
index 00000000..1ff233a5
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/README
@@ -0,0 +1,4 @@
+Gcfg reads INI-style configuration files into Go structs;
+supports user-defined types and subsections.
+
+Package docs: https://godoc.org/gopkg.in/gcfg.v1
diff --git a/vendor/github.com/go-git/gcfg/doc.go b/vendor/github.com/go-git/gcfg/doc.go
new file mode 100644
index 00000000..7bdefbf0
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/doc.go
@@ -0,0 +1,145 @@
+// Package gcfg reads "INI-style" text-based configuration files with
+// "name=value" pairs grouped into sections (gcfg files).
+//
+// This package is still a work in progress; see the sections below for planned
+// changes.
+//
+// Syntax
+//
+// The syntax is based on that used by git config:
+// http://git-scm.com/docs/git-config#_syntax .
+// There are some (planned) differences compared to the git config format:
+// - improve data portability:
+// - must be encoded in UTF-8 (for now) and must not contain the 0 byte
+// - include and "path" type is not supported
+// (path type may be implementable as a user-defined type)
+// - internationalization
+// - section and variable names can contain unicode letters, unicode digits
+// (as defined in http://golang.org/ref/spec#Characters ) and hyphens
+// (U+002D), starting with a unicode letter
+// - disallow potentially ambiguous or misleading definitions:
+// - `[sec.sub]` format is not allowed (deprecated in gitconfig)
+// - `[sec ""]` is not allowed
+// - use `[sec]` for section name "sec" and empty subsection name
+// - (planned) within a single file, definitions must be contiguous for each:
+// - section: '[secA]' -> '[secB]' -> '[secA]' is an error
+// - subsection: '[sec "A"]' -> '[sec "B"]' -> '[sec "A"]' is an error
+// - multivalued variable: 'multi=a' -> 'other=x' -> 'multi=b' is an error
+//
+// Data structure
+//
+// The functions in this package read values into a user-defined struct.
+// Each section corresponds to a struct field in the config struct, and each
+// variable in a section corresponds to a data field in the section struct.
+// The mapping of each section or variable name to fields is done either based
+// on the "gcfg" struct tag or by matching the name of the section or variable,
+// ignoring case. In the latter case, hyphens '-' in section and variable names
+// correspond to underscores '_' in field names.
+// Fields must be exported; to use a section or variable name starting with a
+// letter that is neither upper- or lower-case, prefix the field name with 'X'.
+// (See https://code.google.com/p/go/issues/detail?id=5763#c4 .)
+//
+// For sections with subsections, the corresponding field in config must be a
+// map, rather than a struct, with string keys and pointer-to-struct values.
+// Values for subsection variables are stored in the map with the subsection
+// name used as the map key.
+// (Note that unlike section and variable names, subsection names are case
+// sensitive.)
+// When using a map, and there is a section with the same section name but
+// without a subsection name, its values are stored with the empty string used
+// as the key.
+// It is possible to provide default values for subsections in the section
+// "default-" (or by setting values in the corresponding struct
+// field "Default_").
+//
+// The functions in this package panic if config is not a pointer to a struct,
+// or when a field is not of a suitable type (either a struct or a map with
+// string keys and pointer-to-struct values).
+//
+// Parsing of values
+//
+// The section structs in the config struct may contain single-valued or
+// multi-valued variables. Variables of unnamed slice type (that is, a type
+// starting with `[]`) are treated as multi-value; all others (including named
+// slice types) are treated as single-valued variables.
+//
+// Single-valued variables are handled based on the type as follows.
+// Unnamed pointer types (that is, types starting with `*`) are dereferenced,
+// and if necessary, a new instance is allocated.
+//
+// For types implementing the encoding.TextUnmarshaler interface, the
+// UnmarshalText method is used to set the value. Implementing this method is
+// the recommended way for parsing user-defined types.
+//
+// For fields of string kind, the value string is assigned to the field, after
+// unquoting and unescaping as needed.
+// For fields of bool kind, the field is set to true if the value is "true",
+// "yes", "on" or "1", and set to false if the value is "false", "no", "off" or
+// "0", ignoring case. In addition, single-valued bool fields can be specified
+// with a "blank" value (variable name without equals sign and value); in such
+// case the value is set to true.
+//
+// Predefined integer types [u]int(|8|16|32|64) and big.Int are parsed as
+// decimal or hexadecimal (if having '0x' prefix). (This is to prevent
+// unintuitively handling zero-padded numbers as octal.) Other types having
+// [u]int* as the underlying type, such as os.FileMode and uintptr allow
+// decimal, hexadecimal, or octal values.
+// Parsing mode for integer types can be overridden using the struct tag option
+// ",int=mode" where mode is a combination of the 'd', 'h', and 'o' characters
+// (each standing for decimal, hexadecimal, and octal, respectively.)
+//
+// All other types are parsed using fmt.Sscanf with the "%v" verb.
+//
+// For multi-valued variables, each individual value is parsed as above and
+// appended to the slice. If the first value is specified as a "blank" value
+// (variable name without equals sign and value), a new slice is allocated;
+// that is any values previously set in the slice will be ignored.
+//
+// The types subpackage for provides helpers for parsing "enum-like" and integer
+// types.
+//
+// Error handling
+//
+// There are 3 types of errors:
+//
+// - programmer errors / panics:
+// - invalid configuration structure
+// - data errors:
+// - fatal errors:
+// - invalid configuration syntax
+// - warnings:
+// - data that doesn't belong to any part of the config structure
+//
+// Programmer errors trigger panics. These are should be fixed by the programmer
+// before releasing code that uses gcfg.
+//
+// Data errors cause gcfg to return a non-nil error value. This includes the
+// case when there are extra unknown key-value definitions in the configuration
+// data (extra data).
+// However, in some occasions it is desirable to be able to proceed in
+// situations when the only data error is that of extra data.
+// These errors are handled at a different (warning) priority and can be
+// filtered out programmatically. To ignore extra data warnings, wrap the
+// gcfg.Read*Into invocation into a call to gcfg.FatalOnly.
+//
+// TODO
+//
+// The following is a list of changes under consideration:
+// - documentation
+// - self-contained syntax documentation
+// - more practical examples
+// - move TODOs to issue tracker (eventually)
+// - syntax
+// - reconsider valid escape sequences
+// (gitconfig doesn't support \r in value, \t in subsection name, etc.)
+// - reading / parsing gcfg files
+// - define internal representation structure
+// - support multiple inputs (readers, strings, files)
+// - support declaring encoding (?)
+// - support varying fields sets for subsections (?)
+// - writing gcfg files
+// - error handling
+// - make error context accessible programmatically?
+// - limit input size?
+//
+package gcfg // import "github.com/go-git/gcfg"
diff --git a/vendor/github.com/go-git/gcfg/errors.go b/vendor/github.com/go-git/gcfg/errors.go
new file mode 100644
index 00000000..853c7602
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/errors.go
@@ -0,0 +1,41 @@
+package gcfg
+
+import (
+ "gopkg.in/warnings.v0"
+)
+
+// FatalOnly filters the results of a Read*Into invocation and returns only
+// fatal errors. That is, errors (warnings) indicating data for unknown
+// sections / variables is ignored. Example invocation:
+//
+// err := gcfg.FatalOnly(gcfg.ReadFileInto(&cfg, configFile))
+// if err != nil {
+// ...
+//
+func FatalOnly(err error) error {
+ return warnings.FatalOnly(err)
+}
+
+func isFatal(err error) bool {
+ _, ok := err.(extraData)
+ return !ok
+}
+
+type extraData struct {
+ section string
+ subsection *string
+ variable *string
+}
+
+func (e extraData) Error() string {
+ s := "can't store data at section \"" + e.section + "\""
+ if e.subsection != nil {
+ s += ", subsection \"" + *e.subsection + "\""
+ }
+ if e.variable != nil {
+ s += ", variable \"" + *e.variable + "\""
+ }
+ return s
+}
+
+var _ error = extraData{}
diff --git a/vendor/github.com/go-git/gcfg/read.go b/vendor/github.com/go-git/gcfg/read.go
new file mode 100644
index 00000000..ea5d2edd
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/read.go
@@ -0,0 +1,273 @@
+package gcfg
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "gopkg.in/warnings.v0"
+
+ "github.com/go-git/gcfg/scanner"
+ "github.com/go-git/gcfg/token"
+)
+
+var unescape = map[rune]rune{'\\': '\\', '"': '"', 'n': '\n', 't': '\t', 'b': '\b', '\n': '\n'}
+
+// no error: invalid literals should be caught by scanner
+func unquote(s string) string {
+ u, q, esc := make([]rune, 0, len(s)), false, false
+ for _, c := range s {
+ if esc {
+ uc, ok := unescape[c]
+ switch {
+ case ok:
+ u = append(u, uc)
+ fallthrough
+ case !q && c == '\n':
+ esc = false
+ continue
+ }
+ panic("invalid escape sequence")
+ }
+ switch c {
+ case '"':
+ q = !q
+ case '\\':
+ esc = true
+ default:
+ u = append(u, c)
+ }
+ }
+ if q {
+ panic("missing end quote")
+ }
+ if esc {
+ panic("invalid escape sequence")
+ }
+ return string(u)
+}
+
+func read(c *warnings.Collector, callback func(string, string, string, string, bool) error,
+ fset *token.FileSet, file *token.File, src []byte) error {
+ //
+ var s scanner.Scanner
+ var errs scanner.ErrorList
+ s.Init(file, src, func(p token.Position, m string) { errs.Add(p, m) }, 0)
+ sect, sectsub := "", ""
+ pos, tok, lit := s.Scan()
+ errfn := func(msg string) error {
+ return fmt.Errorf("%s: %s", fset.Position(pos), msg)
+ }
+ for {
+ if errs.Len() > 0 {
+ if err := c.Collect(errs.Err()); err != nil {
+ return err
+ }
+ }
+ switch tok {
+ case token.EOF:
+ return nil
+ case token.EOL, token.COMMENT:
+ pos, tok, lit = s.Scan()
+ case token.LBRACK:
+ pos, tok, lit = s.Scan()
+ if errs.Len() > 0 {
+ if err := c.Collect(errs.Err()); err != nil {
+ return err
+ }
+ }
+ if tok != token.IDENT {
+ if err := c.Collect(errfn("expected section name")); err != nil {
+ return err
+ }
+ }
+ sect, sectsub = lit, ""
+ pos, tok, lit = s.Scan()
+ if errs.Len() > 0 {
+ if err := c.Collect(errs.Err()); err != nil {
+ return err
+ }
+ }
+ if tok == token.STRING {
+ sectsub = unquote(lit)
+ if sectsub == "" {
+ if err := c.Collect(errfn("empty subsection name")); err != nil {
+ return err
+ }
+ }
+ pos, tok, lit = s.Scan()
+ if errs.Len() > 0 {
+ if err := c.Collect(errs.Err()); err != nil {
+ return err
+ }
+ }
+ }
+ if tok != token.RBRACK {
+ if sectsub == "" {
+ if err := c.Collect(errfn("expected subsection name or right bracket")); err != nil {
+ return err
+ }
+ }
+ if err := c.Collect(errfn("expected right bracket")); err != nil {
+ return err
+ }
+ }
+ pos, tok, lit = s.Scan()
+ if tok != token.EOL && tok != token.EOF && tok != token.COMMENT {
+ if err := c.Collect(errfn("expected EOL, EOF, or comment")); err != nil {
+ return err
+ }
+ }
+ // If a section/subsection header was found, ensure a
+ // container object is created, even if there are no
+ // variables further down.
+ err := c.Collect(callback(sect, sectsub, "", "", true))
+ if err != nil {
+ return err
+ }
+ case token.IDENT:
+ if sect == "" {
+ if err := c.Collect(errfn("expected section header")); err != nil {
+ return err
+ }
+ }
+ n := lit
+ pos, tok, lit = s.Scan()
+ if errs.Len() > 0 {
+ return errs.Err()
+ }
+ blank, v := tok == token.EOF || tok == token.EOL || tok == token.COMMENT, ""
+ if !blank {
+ if tok != token.ASSIGN {
+ if err := c.Collect(errfn("expected '='")); err != nil {
+ return err
+ }
+ }
+ pos, tok, lit = s.Scan()
+ if errs.Len() > 0 {
+ if err := c.Collect(errs.Err()); err != nil {
+ return err
+ }
+ }
+ if tok != token.STRING {
+ if err := c.Collect(errfn("expected value")); err != nil {
+ return err
+ }
+ }
+ v = unquote(lit)
+ pos, tok, lit = s.Scan()
+ if errs.Len() > 0 {
+ if err := c.Collect(errs.Err()); err != nil {
+ return err
+ }
+ }
+ if tok != token.EOL && tok != token.EOF && tok != token.COMMENT {
+ if err := c.Collect(errfn("expected EOL, EOF, or comment")); err != nil {
+ return err
+ }
+ }
+ }
+ err := c.Collect(callback(sect, sectsub, n, v, blank))
+ if err != nil {
+ return err
+ }
+ default:
+ if sect == "" {
+ if err := c.Collect(errfn("expected section header")); err != nil {
+ return err
+ }
+ }
+ if err := c.Collect(errfn("expected section header or variable declaration")); err != nil {
+ return err
+ }
+ }
+ }
+ panic("never reached")
+}
+
+func readInto(config interface{}, fset *token.FileSet, file *token.File,
+ src []byte) error {
+ //
+ c := warnings.NewCollector(isFatal)
+ firstPassCallback := func(s string, ss string, k string, v string, bv bool) error {
+ return set(c, config, s, ss, k, v, bv, false)
+ }
+ err := read(c, firstPassCallback, fset, file, src)
+ if err != nil {
+ return err
+ }
+ secondPassCallback := func(s string, ss string, k string, v string, bv bool) error {
+ return set(c, config, s, ss, k, v, bv, true)
+ }
+ err = read(c, secondPassCallback, fset, file, src)
+ if err != nil {
+ return err
+ }
+ return c.Done()
+}
+
+// ReadWithCallback reads gcfg formatted data from reader and calls
+// callback with each section and option found.
+//
+// Callback is called with section, subsection, option key, option value
+// and blank value flag as arguments.
+//
+// When a section is found, callback is called with nil subsection, option key
+// and option value.
+//
+// When a subsection is found, callback is called with nil option key and
+// option value.
+//
+// If blank value flag is true, it means that the value was not set for an option
+// (as opposed to set to empty string).
+//
+// If callback returns an error, ReadWithCallback terminates with an error too.
+func ReadWithCallback(reader io.Reader, callback func(string, string, string, string, bool) error) error {
+ src, err := io.ReadAll(reader)
+ if err != nil {
+ return err
+ }
+
+ fset := token.NewFileSet()
+ file := fset.AddFile("", fset.Base(), len(src))
+ c := warnings.NewCollector(isFatal)
+
+ return read(c, callback, fset, file, src)
+}
+
+// ReadInto reads gcfg formatted data from reader and sets the values into the
+// corresponding fields in config.
+func ReadInto(config interface{}, reader io.Reader) error {
+ src, err := io.ReadAll(reader)
+ if err != nil {
+ return err
+ }
+ fset := token.NewFileSet()
+ file := fset.AddFile("", fset.Base(), len(src))
+ return readInto(config, fset, file, src)
+}
+
+// ReadStringInto reads gcfg formatted data from str and sets the values into
+// the corresponding fields in config.
+func ReadStringInto(config interface{}, str string) error {
+ r := strings.NewReader(str)
+ return ReadInto(config, r)
+}
+
+// ReadFileInto reads gcfg formatted data from the file filename and sets the
+// values into the corresponding fields in config.
+func ReadFileInto(config interface{}, filename string) error {
+ f, err := os.Open(filename)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ src, err := io.ReadAll(f)
+ if err != nil {
+ return err
+ }
+ fset := token.NewFileSet()
+ file := fset.AddFile(filename, fset.Base(), len(src))
+ return readInto(config, fset, file, src)
+}
diff --git a/vendor/github.com/go-git/gcfg/scanner/errors.go b/vendor/github.com/go-git/gcfg/scanner/errors.go
new file mode 100644
index 00000000..a6e00f5c
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/scanner/errors.go
@@ -0,0 +1,121 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scanner
+
+import (
+ "fmt"
+ "io"
+ "sort"
+)
+
+import (
+ "github.com/go-git/gcfg/token"
+)
+
+// In an ErrorList, an error is represented by an *Error.
+// The position Pos, if valid, points to the beginning of
+// the offending token, and the error condition is described
+// by Msg.
+//
+type Error struct {
+ Pos token.Position
+ Msg string
+}
+
+// Error implements the error interface.
+func (e Error) Error() string {
+ if e.Pos.Filename != "" || e.Pos.IsValid() {
+ // don't print ""
+ // TODO(gri) reconsider the semantics of Position.IsValid
+ return e.Pos.String() + ": " + e.Msg
+ }
+ return e.Msg
+}
+
+// ErrorList is a list of *Errors.
+// The zero value for an ErrorList is an empty ErrorList ready to use.
+//
+type ErrorList []*Error
+
+// Add adds an Error with given position and error message to an ErrorList.
+func (p *ErrorList) Add(pos token.Position, msg string) {
+ *p = append(*p, &Error{pos, msg})
+}
+
+// Reset resets an ErrorList to no errors.
+func (p *ErrorList) Reset() { *p = (*p)[0:0] }
+
+// ErrorList implements the sort Interface.
+func (p ErrorList) Len() int { return len(p) }
+func (p ErrorList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+func (p ErrorList) Less(i, j int) bool {
+ e := &p[i].Pos
+ f := &p[j].Pos
+ if e.Filename < f.Filename {
+ return true
+ }
+ if e.Filename == f.Filename {
+ return e.Offset < f.Offset
+ }
+ return false
+}
+
+// Sort sorts an ErrorList. *Error entries are sorted by position,
+// other errors are sorted by error message, and before any *Error
+// entry.
+//
+func (p ErrorList) Sort() {
+ sort.Sort(p)
+}
+
+// RemoveMultiples sorts an ErrorList and removes all but the first error per line.
+func (p *ErrorList) RemoveMultiples() {
+ sort.Sort(p)
+ var last token.Position // initial last.Line is != any legal error line
+ i := 0
+ for _, e := range *p {
+ if e.Pos.Filename != last.Filename || e.Pos.Line != last.Line {
+ last = e.Pos
+ (*p)[i] = e
+ i++
+ }
+ }
+ (*p) = (*p)[0:i]
+}
+
+// An ErrorList implements the error interface.
+func (p ErrorList) Error() string {
+ switch len(p) {
+ case 0:
+ return "no errors"
+ case 1:
+ return p[0].Error()
+ }
+ return fmt.Sprintf("%s (and %d more errors)", p[0], len(p)-1)
+}
+
+// Err returns an error equivalent to this error list.
+// If the list is empty, Err returns nil.
+func (p ErrorList) Err() error {
+ if len(p) == 0 {
+ return nil
+ }
+ return p
+}
+
+// PrintError is a utility function that prints a list of errors to w,
+// one error per line, if the err parameter is an ErrorList. Otherwise
+// it prints the err string.
+//
+func PrintError(w io.Writer, err error) {
+ if list, ok := err.(ErrorList); ok {
+ for _, e := range list {
+ fmt.Fprintf(w, "%s\n", e)
+ }
+ } else if err != nil {
+ fmt.Fprintf(w, "%s\n", err)
+ }
+}
diff --git a/vendor/github.com/go-git/gcfg/scanner/scanner.go b/vendor/github.com/go-git/gcfg/scanner/scanner.go
new file mode 100644
index 00000000..b3da03d0
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/scanner/scanner.go
@@ -0,0 +1,334 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package scanner implements a scanner for gcfg configuration text.
+// It takes a []byte as source which can then be tokenized
+// through repeated calls to the Scan method.
+//
+// Note that the API for the scanner package may change to accommodate new
+// features or implementation changes in gcfg.
+package scanner
+
+import (
+ "fmt"
+ "path/filepath"
+ "unicode"
+ "unicode/utf8"
+
+ "github.com/go-git/gcfg/token"
+)
+
+// An ErrorHandler may be provided to Scanner.Init. If a syntax error is
+// encountered and a handler was installed, the handler is called with a
+// position and an error message. The position points to the beginning of
+// the offending token.
+type ErrorHandler func(pos token.Position, msg string)
+
+// A Scanner holds the scanner's internal state while processing
+// a given text. It can be allocated as part of another data
+// structure but must be initialized via Init before use.
+type Scanner struct {
+ // immutable state
+ file *token.File // source file handle
+ dir string // directory portion of file.Name()
+ src []byte // source
+ err ErrorHandler // error reporting; or nil
+ mode Mode // scanning mode
+
+ // scanning state
+ ch rune // current character
+ offset int // character offset
+ rdOffset int // reading offset (position after current character)
+ lineOffset int // current line offset
+ nextVal bool // next token is expected to be a value
+
+ // public state - ok to modify
+ ErrorCount int // number of errors encountered
+}
+
+// Read the next Unicode char into s.ch.
+// s.ch < 0 means end-of-file.
+func (s *Scanner) next() {
+ if s.rdOffset < len(s.src) {
+ s.offset = s.rdOffset
+ if s.ch == '\n' {
+ s.lineOffset = s.offset
+ s.file.AddLine(s.offset)
+ }
+ r, w := rune(s.src[s.rdOffset]), 1
+ switch {
+ case r == 0:
+ s.error(s.offset, "illegal character NUL")
+ case r >= 0x80:
+ // not ASCII
+ r, w = utf8.DecodeRune(s.src[s.rdOffset:])
+ if r == utf8.RuneError && w == 1 {
+ s.error(s.offset, "illegal UTF-8 encoding")
+ }
+ }
+ s.rdOffset += w
+ s.ch = r
+ } else {
+ s.offset = len(s.src)
+ if s.ch == '\n' {
+ s.lineOffset = s.offset
+ s.file.AddLine(s.offset)
+ }
+ s.ch = -1 // eof
+ }
+}
+
+// A mode value is a set of flags (or 0).
+// They control scanner behavior.
+type Mode uint
+
+const (
+ ScanComments Mode = 1 << iota // return comments as COMMENT tokens
+)
+
+// Init prepares the scanner s to tokenize the text src by setting the
+// scanner at the beginning of src. The scanner uses the file set file
+// for position information and it adds line information for each line.
+// It is ok to re-use the same file when re-scanning the same file as
+// line information which is already present is ignored. Init causes a
+// panic if the file size does not match the src size.
+//
+// Calls to Scan will invoke the error handler err if they encounter a
+// syntax error and err is not nil. Also, for each error encountered,
+// the Scanner field ErrorCount is incremented by one. The mode parameter
+// determines how comments are handled.
+//
+// Note that Init may call err if there is an error in the first character
+// of the file.
+func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode) {
+ // Explicitly initialize all fields since a scanner may be reused.
+ if file.Size() != len(src) {
+ panic(fmt.Sprintf("file size (%d) does not match src len (%d)", file.Size(), len(src)))
+ }
+ s.file = file
+ s.dir, _ = filepath.Split(file.Name())
+ s.src = src
+ s.err = err
+ s.mode = mode
+
+ s.ch = ' '
+ s.offset = 0
+ s.rdOffset = 0
+ s.lineOffset = 0
+ s.ErrorCount = 0
+ s.nextVal = false
+
+ s.next()
+}
+
+func (s *Scanner) error(offs int, msg string) {
+ if s.err != nil {
+ s.err(s.file.Position(s.file.Pos(offs)), msg)
+ }
+ s.ErrorCount++
+}
+
+func (s *Scanner) scanComment() string {
+ // initial [;#] already consumed
+ offs := s.offset - 1 // position of initial [;#]
+
+ for s.ch != '\n' && s.ch >= 0 {
+ s.next()
+ }
+ return string(s.src[offs:s.offset])
+}
+
+func isLetter(ch rune) bool {
+ return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch >= 0x80 && unicode.IsLetter(ch)
+}
+
+func isDigit(ch rune) bool {
+ return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch)
+}
+
+func (s *Scanner) scanIdentifier() string {
+ offs := s.offset
+ for isLetter(s.ch) || isDigit(s.ch) || s.ch == '-' {
+ s.next()
+ }
+ return string(s.src[offs:s.offset])
+}
+
+// val indicate if we are scanning a value (vs a header)
+func (s *Scanner) scanEscape(val bool) {
+ offs := s.offset
+ ch := s.ch
+ s.next() // always make progress
+ switch ch {
+ case '\\', '"', '\n':
+ // ok
+ case 'n', 't', 'b':
+ if val {
+ break // ok
+ }
+ fallthrough
+ default:
+ s.error(offs, "unknown escape sequence")
+ }
+}
+
+func (s *Scanner) scanString() string {
+ // '"' opening already consumed
+ offs := s.offset - 1
+
+ for s.ch != '"' {
+ ch := s.ch
+ s.next()
+ if ch == '\n' || ch < 0 {
+ s.error(offs, "string not terminated")
+ break
+ }
+ if ch == '\\' {
+ s.scanEscape(false)
+ }
+ }
+
+ s.next()
+
+ return string(s.src[offs:s.offset])
+}
+
+func stripCR(b []byte) []byte {
+ c := make([]byte, len(b))
+ i := 0
+ for _, ch := range b {
+ if ch != '\r' {
+ c[i] = ch
+ i++
+ }
+ }
+ return c[:i]
+}
+
+func (s *Scanner) scanValString() string {
+ offs := s.offset
+
+ hasCR := false
+ end := offs
+ inQuote := false
+loop:
+ for inQuote || s.ch >= 0 && s.ch != '\n' && s.ch != ';' && s.ch != '#' {
+ ch := s.ch
+ s.next()
+ switch {
+ case inQuote && ch == '\\':
+ s.scanEscape(true)
+ case !inQuote && ch == '\\':
+ if s.ch == '\r' {
+ hasCR = true
+ s.next()
+ }
+ if s.ch != '\n' {
+ s.scanEscape(true)
+ } else {
+ s.next()
+ }
+ case ch == '"':
+ inQuote = !inQuote
+ case ch == '\r':
+ hasCR = true
+ case ch < 0 || inQuote && ch == '\n':
+ s.error(offs, "string not terminated")
+ break loop
+ }
+ if inQuote || !isWhiteSpace(ch) {
+ end = s.offset
+ }
+ }
+
+ lit := s.src[offs:end]
+ if hasCR {
+ lit = stripCR(lit)
+ }
+
+ return string(lit)
+}
+
+func isWhiteSpace(ch rune) bool {
+ return ch == ' ' || ch == '\t' || ch == '\r'
+}
+
+func (s *Scanner) skipWhitespace() {
+ for isWhiteSpace(s.ch) {
+ s.next()
+ }
+}
+
+// Scan scans the next token and returns the token position, the token,
+// and its literal string if applicable. The source end is indicated by
+// token.EOF.
+//
+// If the returned token is a literal (token.IDENT, token.STRING) or
+// token.COMMENT, the literal string has the corresponding value.
+//
+// If the returned token is token.ILLEGAL, the literal string is the
+// offending character.
+//
+// In all other cases, Scan returns an empty literal string.
+//
+// For more tolerant parsing, Scan will return a valid token if
+// possible even if a syntax error was encountered. Thus, even
+// if the resulting token sequence contains no illegal tokens,
+// a client may not assume that no error occurred. Instead it
+// must check the scanner's ErrorCount or the number of calls
+// of the error handler, if there was one installed.
+//
+// Scan adds line information to the file added to the file
+// set with Init. Token positions are relative to that file
+// and thus relative to the file set.
+func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string) {
+scanAgain:
+ s.skipWhitespace()
+
+ // current token start
+ pos = s.file.Pos(s.offset)
+
+ // determine token value
+ switch ch := s.ch; {
+ case s.nextVal:
+ lit = s.scanValString()
+ tok = token.STRING
+ s.nextVal = false
+ case isLetter(ch):
+ lit = s.scanIdentifier()
+ tok = token.IDENT
+ default:
+ s.next() // always make progress
+ switch ch {
+ case -1:
+ tok = token.EOF
+ case '\n':
+ tok = token.EOL
+ case '"':
+ tok = token.STRING
+ lit = s.scanString()
+ case '[':
+ tok = token.LBRACK
+ case ']':
+ tok = token.RBRACK
+ case ';', '#':
+ // comment
+ lit = s.scanComment()
+ if s.mode&ScanComments == 0 {
+ // skip comment
+ goto scanAgain
+ }
+ tok = token.COMMENT
+ case '=':
+ tok = token.ASSIGN
+ s.nextVal = true
+ default:
+ s.error(s.file.Offset(pos), fmt.Sprintf("illegal character %#U", ch))
+ tok = token.ILLEGAL
+ lit = string(ch)
+ }
+ }
+
+ return
+}
diff --git a/vendor/github.com/go-git/gcfg/set.go b/vendor/github.com/go-git/gcfg/set.go
new file mode 100644
index 00000000..dc9795db
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/set.go
@@ -0,0 +1,334 @@
+package gcfg
+
+import (
+ "bytes"
+ "encoding"
+ "encoding/gob"
+ "fmt"
+ "math/big"
+ "reflect"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+
+ "gopkg.in/warnings.v0"
+
+ "github.com/go-git/gcfg/types"
+)
+
+type tag struct {
+ ident string
+ intMode string
+}
+
+func newTag(ts string) tag {
+ t := tag{}
+ s := strings.Split(ts, ",")
+ t.ident = s[0]
+ for _, tse := range s[1:] {
+ if strings.HasPrefix(tse, "int=") {
+ t.intMode = tse[len("int="):]
+ }
+ }
+ return t
+}
+
+func fieldFold(v reflect.Value, name string) (reflect.Value, tag) {
+ var n string
+ r0, _ := utf8.DecodeRuneInString(name)
+ if unicode.IsLetter(r0) && !unicode.IsLower(r0) && !unicode.IsUpper(r0) {
+ n = "X"
+ }
+ n += strings.Replace(name, "-", "_", -1)
+ f, ok := v.Type().FieldByNameFunc(func(fieldName string) bool {
+ if !v.FieldByName(fieldName).CanSet() {
+ return false
+ }
+ f, _ := v.Type().FieldByName(fieldName)
+ t := newTag(f.Tag.Get("gcfg"))
+ if t.ident != "" {
+ return strings.EqualFold(t.ident, name)
+ }
+ return strings.EqualFold(n, fieldName)
+ })
+ if !ok {
+ return reflect.Value{}, tag{}
+ }
+ return v.FieldByName(f.Name), newTag(f.Tag.Get("gcfg"))
+}
+
+type setter func(destp interface{}, blank bool, val string, t tag) error
+
+var errUnsupportedType = fmt.Errorf("unsupported type")
+var errBlankUnsupported = fmt.Errorf("blank value not supported for type")
+
+var setters = []setter{
+ typeSetter, textUnmarshalerSetter, kindSetter, scanSetter,
+}
+
+func textUnmarshalerSetter(d interface{}, blank bool, val string, t tag) error {
+ dtu, ok := d.(encoding.TextUnmarshaler)
+ if !ok {
+ return errUnsupportedType
+ }
+ if blank {
+ return errBlankUnsupported
+ }
+ return dtu.UnmarshalText([]byte(val))
+}
+
+func boolSetter(d interface{}, blank bool, val string, t tag) error {
+ if blank {
+ reflect.ValueOf(d).Elem().Set(reflect.ValueOf(true))
+ return nil
+ }
+ b, err := types.ParseBool(val)
+ if err == nil {
+ reflect.ValueOf(d).Elem().Set(reflect.ValueOf(b))
+ }
+ return err
+}
+
+func intMode(mode string) types.IntMode {
+ var m types.IntMode
+ if strings.ContainsAny(mode, "dD") {
+ m |= types.Dec
+ }
+ if strings.ContainsAny(mode, "hH") {
+ m |= types.Hex
+ }
+ if strings.ContainsAny(mode, "oO") {
+ m |= types.Oct
+ }
+ return m
+}
+
+var typeModes = map[reflect.Type]types.IntMode{
+ reflect.TypeOf(int(0)): types.Dec | types.Hex,
+ reflect.TypeOf(int8(0)): types.Dec | types.Hex,
+ reflect.TypeOf(int16(0)): types.Dec | types.Hex,
+ reflect.TypeOf(int32(0)): types.Dec | types.Hex,
+ reflect.TypeOf(int64(0)): types.Dec | types.Hex,
+ reflect.TypeOf(uint(0)): types.Dec | types.Hex,
+ reflect.TypeOf(uint8(0)): types.Dec | types.Hex,
+ reflect.TypeOf(uint16(0)): types.Dec | types.Hex,
+ reflect.TypeOf(uint32(0)): types.Dec | types.Hex,
+ reflect.TypeOf(uint64(0)): types.Dec | types.Hex,
+ // use default mode (allow dec/hex/oct) for uintptr type
+ reflect.TypeOf(big.Int{}): types.Dec | types.Hex,
+}
+
+func intModeDefault(t reflect.Type) types.IntMode {
+ m, ok := typeModes[t]
+ if !ok {
+ m = types.Dec | types.Hex | types.Oct
+ }
+ return m
+}
+
+func intSetter(d interface{}, blank bool, val string, t tag) error {
+ if blank {
+ return errBlankUnsupported
+ }
+ mode := intMode(t.intMode)
+ if mode == 0 {
+ mode = intModeDefault(reflect.TypeOf(d).Elem())
+ }
+ return types.ParseInt(d, val, mode)
+}
+
+func stringSetter(d interface{}, blank bool, val string, t tag) error {
+ if blank {
+ return errBlankUnsupported
+ }
+ dsp, ok := d.(*string)
+ if !ok {
+ return errUnsupportedType
+ }
+ *dsp = val
+ return nil
+}
+
+var kindSetters = map[reflect.Kind]setter{
+ reflect.String: stringSetter,
+ reflect.Bool: boolSetter,
+ reflect.Int: intSetter,
+ reflect.Int8: intSetter,
+ reflect.Int16: intSetter,
+ reflect.Int32: intSetter,
+ reflect.Int64: intSetter,
+ reflect.Uint: intSetter,
+ reflect.Uint8: intSetter,
+ reflect.Uint16: intSetter,
+ reflect.Uint32: intSetter,
+ reflect.Uint64: intSetter,
+ reflect.Uintptr: intSetter,
+}
+
+var typeSetters = map[reflect.Type]setter{
+ reflect.TypeOf(big.Int{}): intSetter,
+}
+
+func typeSetter(d interface{}, blank bool, val string, tt tag) error {
+ t := reflect.ValueOf(d).Type().Elem()
+ setter, ok := typeSetters[t]
+ if !ok {
+ return errUnsupportedType
+ }
+ return setter(d, blank, val, tt)
+}
+
+func kindSetter(d interface{}, blank bool, val string, tt tag) error {
+ k := reflect.ValueOf(d).Type().Elem().Kind()
+ setter, ok := kindSetters[k]
+ if !ok {
+ return errUnsupportedType
+ }
+ return setter(d, blank, val, tt)
+}
+
+func scanSetter(d interface{}, blank bool, val string, tt tag) error {
+ if blank {
+ return errBlankUnsupported
+ }
+ return types.ScanFully(d, val, 'v')
+}
+
+func newValue(c *warnings.Collector, sect string, vCfg reflect.Value,
+ vType reflect.Type) (reflect.Value, error) {
+ //
+ pv := reflect.New(vType)
+ dfltName := "default-" + sect
+ dfltField, _ := fieldFold(vCfg, dfltName)
+ var err error
+ if dfltField.IsValid() {
+ b := bytes.NewBuffer(nil)
+ ge := gob.NewEncoder(b)
+ if err = c.Collect(ge.EncodeValue(dfltField)); err != nil {
+ return pv, err
+ }
+ gd := gob.NewDecoder(bytes.NewReader(b.Bytes()))
+ if err = c.Collect(gd.DecodeValue(pv.Elem())); err != nil {
+ return pv, err
+ }
+ }
+ return pv, nil
+}
+
+func set(c *warnings.Collector, cfg interface{}, sect, sub, name string,
+ value string, blankValue bool, subsectPass bool) error {
+ //
+ vPCfg := reflect.ValueOf(cfg)
+ if vPCfg.Kind() != reflect.Ptr || vPCfg.Elem().Kind() != reflect.Struct {
+ panic(fmt.Errorf("config must be a pointer to a struct"))
+ }
+ vCfg := vPCfg.Elem()
+ vSect, _ := fieldFold(vCfg, sect)
+ if !vSect.IsValid() {
+ err := extraData{section: sect}
+ return c.Collect(err)
+ }
+ isSubsect := vSect.Kind() == reflect.Map
+ if subsectPass != isSubsect {
+ return nil
+ }
+ if isSubsect {
+ vst := vSect.Type()
+ if vst.Key().Kind() != reflect.String ||
+ vst.Elem().Kind() != reflect.Ptr ||
+ vst.Elem().Elem().Kind() != reflect.Struct {
+ panic(fmt.Errorf("map field for section must have string keys and "+
+ " pointer-to-struct values: section %q", sect))
+ }
+ if vSect.IsNil() {
+ vSect.Set(reflect.MakeMap(vst))
+ }
+ k := reflect.ValueOf(sub)
+ pv := vSect.MapIndex(k)
+ if !pv.IsValid() {
+ vType := vSect.Type().Elem().Elem()
+ var err error
+ if pv, err = newValue(c, sect, vCfg, vType); err != nil {
+ return err
+ }
+ vSect.SetMapIndex(k, pv)
+ }
+ vSect = pv.Elem()
+ } else if vSect.Kind() != reflect.Struct {
+ panic(fmt.Errorf("field for section must be a map or a struct: "+
+ "section %q", sect))
+ } else if sub != "" {
+ err := extraData{section: sect, subsection: &sub}
+ return c.Collect(err)
+ }
+ // Empty name is a special value, meaning that only the
+ // section/subsection object is to be created, with no values set.
+ if name == "" {
+ return nil
+ }
+ vVar, t := fieldFold(vSect, name)
+ if !vVar.IsValid() {
+ var err error
+ if isSubsect {
+ err = extraData{section: sect, subsection: &sub, variable: &name}
+ } else {
+ err = extraData{section: sect, variable: &name}
+ }
+ return c.Collect(err)
+ }
+ // vVal is either single-valued var, or newly allocated value within multi-valued var
+ var vVal reflect.Value
+ // multi-value if unnamed slice type
+ isMulti := vVar.Type().Name() == "" && vVar.Kind() == reflect.Slice ||
+ vVar.Type().Name() == "" && vVar.Kind() == reflect.Ptr && vVar.Type().Elem().Name() == "" && vVar.Type().Elem().Kind() == reflect.Slice
+ if isMulti && vVar.Kind() == reflect.Ptr {
+ if vVar.IsNil() {
+ vVar.Set(reflect.New(vVar.Type().Elem()))
+ }
+ vVar = vVar.Elem()
+ }
+ if isMulti && blankValue {
+ vVar.Set(reflect.Zero(vVar.Type()))
+ return nil
+ }
+ if isMulti {
+ vVal = reflect.New(vVar.Type().Elem()).Elem()
+ } else {
+ vVal = vVar
+ }
+ isDeref := vVal.Type().Name() == "" && vVal.Type().Kind() == reflect.Ptr
+ isNew := isDeref && vVal.IsNil()
+ // vAddr is address of value to set (dereferenced & allocated as needed)
+ var vAddr reflect.Value
+ switch {
+ case isNew:
+ vAddr = reflect.New(vVal.Type().Elem())
+ case isDeref && !isNew:
+ vAddr = vVal
+ default:
+ vAddr = vVal.Addr()
+ }
+ vAddrI := vAddr.Interface()
+ err, ok := error(nil), false
+ for _, s := range setters {
+ err = s(vAddrI, blankValue, value, t)
+ if err == nil {
+ ok = true
+ break
+ }
+ if err != errUnsupportedType {
+ return err
+ }
+ }
+ if !ok {
+ // in case all setters returned errUnsupportedType
+ return err
+ }
+ if isNew { // set reference if it was dereferenced and newly allocated
+ vVal.Set(vAddr)
+ }
+ if isMulti { // append if multi-valued
+ vVar.Set(reflect.Append(vVar, vVal))
+ }
+ return nil
+}
diff --git a/vendor/github.com/go-git/gcfg/token/position.go b/vendor/github.com/go-git/gcfg/token/position.go
new file mode 100644
index 00000000..fc45c1e7
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/token/position.go
@@ -0,0 +1,435 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(gri) consider making this a separate package outside the go directory.
+
+package token
+
+import (
+ "fmt"
+ "sort"
+ "sync"
+)
+
+// -----------------------------------------------------------------------------
+// Positions
+
+// Position describes an arbitrary source position
+// including the file, line, and column location.
+// A Position is valid if the line number is > 0.
+//
+type Position struct {
+ Filename string // filename, if any
+ Offset int // offset, starting at 0
+ Line int // line number, starting at 1
+ Column int // column number, starting at 1 (character count)
+}
+
+// IsValid returns true if the position is valid.
+func (pos *Position) IsValid() bool { return pos.Line > 0 }
+
+// String returns a string in one of several forms:
+//
+// file:line:column valid position with file name
+// line:column valid position without file name
+// file invalid position with file name
+// - invalid position without file name
+//
+func (pos Position) String() string {
+ s := pos.Filename
+ if pos.IsValid() {
+ if s != "" {
+ s += ":"
+ }
+ s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
+ }
+ if s == "" {
+ s = "-"
+ }
+ return s
+}
+
+// Pos is a compact encoding of a source position within a file set.
+// It can be converted into a Position for a more convenient, but much
+// larger, representation.
+//
+// The Pos value for a given file is a number in the range [base, base+size],
+// where base and size are specified when adding the file to the file set via
+// AddFile.
+//
+// To create the Pos value for a specific source offset, first add
+// the respective file to the current file set (via FileSet.AddFile)
+// and then call File.Pos(offset) for that file. Given a Pos value p
+// for a specific file set fset, the corresponding Position value is
+// obtained by calling fset.Position(p).
+//
+// Pos values can be compared directly with the usual comparison operators:
+// If two Pos values p and q are in the same file, comparing p and q is
+// equivalent to comparing the respective source file offsets. If p and q
+// are in different files, p < q is true if the file implied by p was added
+// to the respective file set before the file implied by q.
+//
+type Pos int
+
+// The zero value for Pos is NoPos; there is no file and line information
+// associated with it, and NoPos().IsValid() is false. NoPos is always
+// smaller than any other Pos value. The corresponding Position value
+// for NoPos is the zero value for Position.
+//
+const NoPos Pos = 0
+
+// IsValid returns true if the position is valid.
+func (p Pos) IsValid() bool {
+ return p != NoPos
+}
+
+// -----------------------------------------------------------------------------
+// File
+
+// A File is a handle for a file belonging to a FileSet.
+// A File has a name, size, and line offset table.
+//
+type File struct {
+ set *FileSet
+ name string // file name as provided to AddFile
+ base int // Pos value range for this file is [base...base+size]
+ size int // file size as provided to AddFile
+
+ // lines and infos are protected by set.mutex
+ lines []int
+ infos []lineInfo
+}
+
+// Name returns the file name of file f as registered with AddFile.
+func (f *File) Name() string {
+ return f.name
+}
+
+// Base returns the base offset of file f as registered with AddFile.
+func (f *File) Base() int {
+ return f.base
+}
+
+// Size returns the size of file f as registered with AddFile.
+func (f *File) Size() int {
+ return f.size
+}
+
+// LineCount returns the number of lines in file f.
+func (f *File) LineCount() int {
+ f.set.mutex.RLock()
+ n := len(f.lines)
+ f.set.mutex.RUnlock()
+ return n
+}
+
+// AddLine adds the line offset for a new line.
+// The line offset must be larger than the offset for the previous line
+// and smaller than the file size; otherwise the line offset is ignored.
+//
+func (f *File) AddLine(offset int) {
+ f.set.mutex.Lock()
+ if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size {
+ f.lines = append(f.lines, offset)
+ }
+ f.set.mutex.Unlock()
+}
+
+// SetLines sets the line offsets for a file and returns true if successful.
+// The line offsets are the offsets of the first character of each line;
+// for instance for the content "ab\nc\n" the line offsets are {0, 3}.
+// An empty file has an empty line offset table.
+// Each line offset must be larger than the offset for the previous line
+// and smaller than the file size; otherwise SetLines fails and returns
+// false.
+//
+func (f *File) SetLines(lines []int) bool {
+ // verify validity of lines table
+ size := f.size
+ for i, offset := range lines {
+ if i > 0 && offset <= lines[i-1] || size <= offset {
+ return false
+ }
+ }
+
+ // set lines table
+ f.set.mutex.Lock()
+ f.lines = lines
+ f.set.mutex.Unlock()
+ return true
+}
+
+// SetLinesForContent sets the line offsets for the given file content.
+func (f *File) SetLinesForContent(content []byte) {
+ var lines []int
+ line := 0
+ for offset, b := range content {
+ if line >= 0 {
+ lines = append(lines, line)
+ }
+ line = -1
+ if b == '\n' {
+ line = offset + 1
+ }
+ }
+
+ // set lines table
+ f.set.mutex.Lock()
+ f.lines = lines
+ f.set.mutex.Unlock()
+}
+
+// A lineInfo object describes alternative file and line number
+// information (such as provided via a //line comment in a .go
+// file) for a given file offset.
+type lineInfo struct {
+ // fields are exported to make them accessible to gob
+ Offset int
+ Filename string
+ Line int
+}
+
+// AddLineInfo adds alternative file and line number information for
+// a given file offset. The offset must be larger than the offset for
+// the previously added alternative line info and smaller than the
+// file size; otherwise the information is ignored.
+//
+// AddLineInfo is typically used to register alternative position
+// information for //line filename:line comments in source files.
+//
+func (f *File) AddLineInfo(offset int, filename string, line int) {
+ f.set.mutex.Lock()
+ if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size {
+ f.infos = append(f.infos, lineInfo{offset, filename, line})
+ }
+ f.set.mutex.Unlock()
+}
+
+// Pos returns the Pos value for the given file offset;
+// the offset must be <= f.Size().
+// f.Pos(f.Offset(p)) == p.
+//
+func (f *File) Pos(offset int) Pos {
+ if offset > f.size {
+ panic("illegal file offset")
+ }
+ return Pos(f.base + offset)
+}
+
+// Offset returns the offset for the given file position p;
+// p must be a valid Pos value in that file.
+// f.Offset(f.Pos(offset)) == offset.
+//
+func (f *File) Offset(p Pos) int {
+ if int(p) < f.base || int(p) > f.base+f.size {
+ panic("illegal Pos value")
+ }
+ return int(p) - f.base
+}
+
+// Line returns the line number for the given file position p;
+// p must be a Pos value in that file or NoPos.
+//
+func (f *File) Line(p Pos) int {
+ // TODO(gri) this can be implemented much more efficiently
+ return f.Position(p).Line
+}
+
+func searchLineInfos(a []lineInfo, x int) int {
+ return sort.Search(len(a), func(i int) bool { return a[i].Offset > x }) - 1
+}
+
+// info returns the file name, line, and column number for a file offset.
+func (f *File) info(offset int) (filename string, line, column int) {
+ filename = f.name
+ if i := searchInts(f.lines, offset); i >= 0 {
+ line, column = i+1, offset-f.lines[i]+1
+ }
+ if len(f.infos) > 0 {
+ // almost no files have extra line infos
+ if i := searchLineInfos(f.infos, offset); i >= 0 {
+ alt := &f.infos[i]
+ filename = alt.Filename
+ if i := searchInts(f.lines, alt.Offset); i >= 0 {
+ line += alt.Line - i - 1
+ }
+ }
+ }
+ return
+}
+
+func (f *File) position(p Pos) (pos Position) {
+ offset := int(p) - f.base
+ pos.Offset = offset
+ pos.Filename, pos.Line, pos.Column = f.info(offset)
+ return
+}
+
+// Position returns the Position value for the given file position p;
+// p must be a Pos value in that file or NoPos.
+//
+func (f *File) Position(p Pos) (pos Position) {
+ if p != NoPos {
+ if int(p) < f.base || int(p) > f.base+f.size {
+ panic("illegal Pos value")
+ }
+ pos = f.position(p)
+ }
+ return
+}
+
+// -----------------------------------------------------------------------------
+// FileSet
+
+// A FileSet represents a set of source files.
+// Methods of file sets are synchronized; multiple goroutines
+// may invoke them concurrently.
+//
+type FileSet struct {
+ mutex sync.RWMutex // protects the file set
+ base int // base offset for the next file
+ files []*File // list of files in the order added to the set
+ last *File // cache of last file looked up
+}
+
+// NewFileSet creates a new file set.
+func NewFileSet() *FileSet {
+ s := new(FileSet)
+ s.base = 1 // 0 == NoPos
+ return s
+}
+
+// Base returns the minimum base offset that must be provided to
+// AddFile when adding the next file.
+//
+func (s *FileSet) Base() int {
+ s.mutex.RLock()
+ b := s.base
+ s.mutex.RUnlock()
+ return b
+
+}
+
+// AddFile adds a new file with a given filename, base offset, and file size
+// to the file set s and returns the file. Multiple files may have the same
+// name. The base offset must not be smaller than the FileSet's Base(), and
+// size must not be negative.
+//
+// Adding the file will set the file set's Base() value to base + size + 1
+// as the minimum base value for the next file. The following relationship
+// exists between a Pos value p for a given file offset offs:
+//
+// int(p) = base + offs
+//
+// with offs in the range [0, size] and thus p in the range [base, base+size].
+// For convenience, File.Pos may be used to create file-specific position
+// values from a file offset.
+//
+func (s *FileSet) AddFile(filename string, base, size int) *File {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ if base < s.base || size < 0 {
+ panic("illegal base or size")
+ }
+ // base >= s.base && size >= 0
+ f := &File{s, filename, base, size, []int{0}, nil}
+ base += size + 1 // +1 because EOF also has a position
+ if base < 0 {
+ panic("token.Pos offset overflow (> 2G of source code in file set)")
+ }
+ // add the file to the file set
+ s.base = base
+ s.files = append(s.files, f)
+ s.last = f
+ return f
+}
+
+// Iterate calls f for the files in the file set in the order they were added
+// until f returns false.
+//
+func (s *FileSet) Iterate(f func(*File) bool) {
+ for i := 0; ; i++ {
+ var file *File
+ s.mutex.RLock()
+ if i < len(s.files) {
+ file = s.files[i]
+ }
+ s.mutex.RUnlock()
+ if file == nil || !f(file) {
+ break
+ }
+ }
+}
+
+func searchFiles(a []*File, x int) int {
+ return sort.Search(len(a), func(i int) bool { return a[i].base > x }) - 1
+}
+
+func (s *FileSet) file(p Pos) *File {
+ // common case: p is in last file
+ if f := s.last; f != nil && f.base <= int(p) && int(p) <= f.base+f.size {
+ return f
+ }
+ // p is not in last file - search all files
+ if i := searchFiles(s.files, int(p)); i >= 0 {
+ f := s.files[i]
+ // f.base <= int(p) by definition of searchFiles
+ if int(p) <= f.base+f.size {
+ s.last = f
+ return f
+ }
+ }
+ return nil
+}
+
+// File returns the file that contains the position p.
+// If no such file is found (for instance for p == NoPos),
+// the result is nil.
+//
+func (s *FileSet) File(p Pos) (f *File) {
+ if p != NoPos {
+ s.mutex.RLock()
+ f = s.file(p)
+ s.mutex.RUnlock()
+ }
+ return
+}
+
+// Position converts a Pos in the fileset into a general Position.
+func (s *FileSet) Position(p Pos) (pos Position) {
+ if p != NoPos {
+ s.mutex.RLock()
+ if f := s.file(p); f != nil {
+ pos = f.position(p)
+ }
+ s.mutex.RUnlock()
+ }
+ return
+}
+
+// -----------------------------------------------------------------------------
+// Helper functions
+
+func searchInts(a []int, x int) int {
+ // This function body is a manually inlined version of:
+ //
+ // return sort.Search(len(a), func(i int) bool { return a[i] > x }) - 1
+ //
+ // With better compiler optimizations, this may not be needed in the
+ // future, but at the moment this change improves the go/printer
+ // benchmark performance by ~30%. This has a direct impact on the
+ // speed of gofmt and thus seems worthwhile (2011-04-29).
+ // TODO(gri): Remove this when compilers have caught up.
+ i, j := 0, len(a)
+ for i < j {
+ h := i + (j-i)/2 // avoid overflow when computing h
+ // i ≤ h < j
+ if a[h] <= x {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ return i - 1
+}
diff --git a/vendor/github.com/go-git/gcfg/token/serialize.go b/vendor/github.com/go-git/gcfg/token/serialize.go
new file mode 100644
index 00000000..4adc8f9e
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/token/serialize.go
@@ -0,0 +1,56 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package token
+
+type serializedFile struct {
+ // fields correspond 1:1 to fields with same (lower-case) name in File
+ Name string
+ Base int
+ Size int
+ Lines []int
+ Infos []lineInfo
+}
+
+type serializedFileSet struct {
+ Base int
+ Files []serializedFile
+}
+
+// Read calls decode to deserialize a file set into s; s must not be nil.
+func (s *FileSet) Read(decode func(interface{}) error) error {
+ var ss serializedFileSet
+ if err := decode(&ss); err != nil {
+ return err
+ }
+
+ s.mutex.Lock()
+ s.base = ss.Base
+ files := make([]*File, len(ss.Files))
+ for i := 0; i < len(ss.Files); i++ {
+ f := &ss.Files[i]
+ files[i] = &File{s, f.Name, f.Base, f.Size, f.Lines, f.Infos}
+ }
+ s.files = files
+ s.last = nil
+ s.mutex.Unlock()
+
+ return nil
+}
+
+// Write calls encode to serialize the file set s.
+func (s *FileSet) Write(encode func(interface{}) error) error {
+ var ss serializedFileSet
+
+ s.mutex.Lock()
+ ss.Base = s.base
+ files := make([]serializedFile, len(s.files))
+ for i, f := range s.files {
+ files[i] = serializedFile{f.name, f.base, f.size, f.lines, f.infos}
+ }
+ ss.Files = files
+ s.mutex.Unlock()
+
+ return encode(ss)
+}
diff --git a/vendor/github.com/go-git/gcfg/token/token.go b/vendor/github.com/go-git/gcfg/token/token.go
new file mode 100644
index 00000000..b3c7c83f
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/token/token.go
@@ -0,0 +1,83 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package token defines constants representing the lexical tokens of the gcfg
+// configuration syntax and basic operations on tokens (printing, predicates).
+//
+// Note that the API for the token package may change to accommodate new
+// features or implementation changes in gcfg.
+//
+package token
+
+import "strconv"
+
+// Token is the set of lexical tokens of the gcfg configuration syntax.
+type Token int
+
+// The list of tokens.
+const (
+ // Special tokens
+ ILLEGAL Token = iota
+ EOF
+ COMMENT
+
+ literal_beg
+ // Identifiers and basic type literals
+ // (these tokens stand for classes of literals)
+ IDENT // section-name, variable-name
+ STRING // "subsection-name", variable value
+ literal_end
+
+ operator_beg
+ // Operators and delimiters
+ ASSIGN // =
+ LBRACK // [
+ RBRACK // ]
+ EOL // \n
+ operator_end
+)
+
+var tokens = [...]string{
+ ILLEGAL: "ILLEGAL",
+
+ EOF: "EOF",
+ COMMENT: "COMMENT",
+
+ IDENT: "IDENT",
+ STRING: "STRING",
+
+ ASSIGN: "=",
+ LBRACK: "[",
+ RBRACK: "]",
+ EOL: "\n",
+}
+
+// String returns the string corresponding to the token tok.
+// For operators and delimiters, the string is the actual token character
+// sequence (e.g., for the token ASSIGN, the string is "="). For all other
+// tokens the string corresponds to the token constant name (e.g. for the
+// token IDENT, the string is "IDENT").
+//
+func (tok Token) String() string {
+ s := ""
+ if 0 <= tok && tok < Token(len(tokens)) {
+ s = tokens[tok]
+ }
+ if s == "" {
+ s = "token(" + strconv.Itoa(int(tok)) + ")"
+ }
+ return s
+}
+
+// Predicates
+
+// IsLiteral returns true for tokens corresponding to identifiers
+// and basic type literals; it returns false otherwise.
+//
+func (tok Token) IsLiteral() bool { return literal_beg < tok && tok < literal_end }
+
+// IsOperator returns true for tokens corresponding to operators and
+// delimiters; it returns false otherwise.
+//
+func (tok Token) IsOperator() bool { return operator_beg < tok && tok < operator_end }
diff --git a/vendor/github.com/go-git/gcfg/types/bool.go b/vendor/github.com/go-git/gcfg/types/bool.go
new file mode 100644
index 00000000..8dcae0d8
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/types/bool.go
@@ -0,0 +1,23 @@
+package types
+
+// BoolValues defines the name and value mappings for ParseBool.
+var BoolValues = map[string]interface{}{
+ "true": true, "yes": true, "on": true, "1": true,
+ "false": false, "no": false, "off": false, "0": false,
+}
+
+var boolParser = func() *EnumParser {
+ ep := &EnumParser{}
+ ep.AddVals(BoolValues)
+ return ep
+}()
+
+// ParseBool parses bool values according to the definitions in BoolValues.
+// Parsing is case-insensitive.
+func ParseBool(s string) (bool, error) {
+ v, err := boolParser.Parse(s)
+ if err != nil {
+ return false, err
+ }
+ return v.(bool), nil
+}
diff --git a/vendor/github.com/go-git/gcfg/types/doc.go b/vendor/github.com/go-git/gcfg/types/doc.go
new file mode 100644
index 00000000..9f9c345f
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/types/doc.go
@@ -0,0 +1,4 @@
+// Package types defines helpers for type conversions.
+//
+// The API for this package is not finalized yet.
+package types
diff --git a/vendor/github.com/go-git/gcfg/types/enum.go b/vendor/github.com/go-git/gcfg/types/enum.go
new file mode 100644
index 00000000..1a0c7ef4
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/types/enum.go
@@ -0,0 +1,44 @@
+package types
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+// EnumParser parses "enum" values; i.e. a predefined set of strings to
+// predefined values.
+type EnumParser struct {
+ Type string // type name; if not set, use type of first value added
+ CaseMatch bool // if true, matching of strings is case-sensitive
+ // PrefixMatch bool
+ vals map[string]interface{}
+}
+
+// AddVals adds strings and values to an EnumParser.
+func (ep *EnumParser) AddVals(vals map[string]interface{}) {
+ if ep.vals == nil {
+ ep.vals = make(map[string]interface{})
+ }
+ for k, v := range vals {
+ if ep.Type == "" {
+ ep.Type = reflect.TypeOf(v).Name()
+ }
+ if !ep.CaseMatch {
+ k = strings.ToLower(k)
+ }
+ ep.vals[k] = v
+ }
+}
+
+// Parse parses the string and returns the value or an error.
+func (ep EnumParser) Parse(s string) (interface{}, error) {
+ if !ep.CaseMatch {
+ s = strings.ToLower(s)
+ }
+ v, ok := ep.vals[s]
+ if !ok {
+ return false, fmt.Errorf("failed to parse %s %#q", ep.Type, s)
+ }
+ return v, nil
+}
diff --git a/vendor/github.com/go-git/gcfg/types/int.go b/vendor/github.com/go-git/gcfg/types/int.go
new file mode 100644
index 00000000..af7e75c1
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/types/int.go
@@ -0,0 +1,86 @@
+package types
+
+import (
+ "fmt"
+ "strings"
+)
+
+// An IntMode is a mode for parsing integer values, representing a set of
+// accepted bases.
+type IntMode uint8
+
+// IntMode values for ParseInt; can be combined using binary or.
+const (
+ Dec IntMode = 1 << iota
+ Hex
+ Oct
+)
+
+// String returns a string representation of IntMode; e.g. `IntMode(Dec|Hex)`.
+func (m IntMode) String() string {
+ var modes []string
+ if m&Dec != 0 {
+ modes = append(modes, "Dec")
+ }
+ if m&Hex != 0 {
+ modes = append(modes, "Hex")
+ }
+ if m&Oct != 0 {
+ modes = append(modes, "Oct")
+ }
+ return "IntMode(" + strings.Join(modes, "|") + ")"
+}
+
+var errIntAmbig = fmt.Errorf("ambiguous integer value; must include '0' prefix")
+
+func prefix0(val string) bool {
+ return strings.HasPrefix(val, "0") || strings.HasPrefix(val, "-0")
+}
+
+func prefix0x(val string) bool {
+ return strings.HasPrefix(val, "0x") || strings.HasPrefix(val, "-0x")
+}
+
+// ParseInt parses val using mode into intptr, which must be a pointer to an
+// integer kind type. Non-decimal value require prefix `0` or `0x` in the cases
+// when mode permits ambiguity of base; otherwise the prefix can be omitted.
+func ParseInt(intptr interface{}, val string, mode IntMode) error {
+ val = strings.TrimSpace(val)
+ verb := byte(0)
+ switch mode {
+ case Dec:
+ verb = 'd'
+ case Dec + Hex:
+ if prefix0x(val) {
+ verb = 'v'
+ } else {
+ verb = 'd'
+ }
+ case Dec + Oct:
+ if prefix0(val) && !prefix0x(val) {
+ verb = 'v'
+ } else {
+ verb = 'd'
+ }
+ case Dec + Hex + Oct:
+ verb = 'v'
+ case Hex:
+ if prefix0x(val) {
+ verb = 'v'
+ } else {
+ verb = 'x'
+ }
+ case Oct:
+ verb = 'o'
+ case Hex + Oct:
+ if prefix0(val) {
+ verb = 'v'
+ } else {
+ return errIntAmbig
+ }
+ }
+ if verb == 0 {
+ panic("unsupported mode")
+ }
+ return ScanFully(intptr, val, verb)
+}
diff --git a/vendor/github.com/go-git/gcfg/types/scan.go b/vendor/github.com/go-git/gcfg/types/scan.go
new file mode 100644
index 00000000..db2f6ed3
--- /dev/null
+++ b/vendor/github.com/go-git/gcfg/types/scan.go
@@ -0,0 +1,23 @@
+package types
+
+import (
+ "fmt"
+ "io"
+ "reflect"
+)
+
+// ScanFully uses fmt.Sscanf with verb to fully scan val into ptr.
+func ScanFully(ptr interface{}, val string, verb byte) error {
+ t := reflect.ValueOf(ptr).Elem().Type()
+ // attempt to read extra bytes to make sure the value is consumed
+ var b []byte
+ n, err := fmt.Sscanf(val, "%"+string(verb)+"%s", ptr, &b)
+ switch {
+ case n < 1 || n == 1 && err != io.EOF:
+ return fmt.Errorf("failed to parse %q as %v: %v", val, t, err)
+ case n > 1:
+ return fmt.Errorf("failed to parse %q as %v: extra characters %q", val, t, string(b))
+ }
+ // n == 1 && err == io.EOF
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/.gitignore b/vendor/github.com/go-git/go-billy/v5/.gitignore
new file mode 100644
index 00000000..7aeb4669
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/.gitignore
@@ -0,0 +1,4 @@
+/coverage.txt
+/vendor
+Gopkg.lock
+Gopkg.toml
diff --git a/vendor/github.com/go-git/go-billy/v5/LICENSE b/vendor/github.com/go-git/go-billy/v5/LICENSE
new file mode 100644
index 00000000..9d607568
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ 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 "{}"
+ 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
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2017 Sourced Technologies S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/go-git/go-billy/v5/Makefile b/vendor/github.com/go-git/go-billy/v5/Makefile
new file mode 100644
index 00000000..74dad8b4
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/Makefile
@@ -0,0 +1,11 @@
+# Go parameters
+GOCMD = go
+GOTEST = $(GOCMD) test
+
+.PHONY: test
+test:
+ $(GOTEST) -race ./...
+
+test-coverage:
+ echo "" > $(COVERAGE_REPORT); \
+ $(GOTEST) -coverprofile=$(COVERAGE_REPORT) -coverpkg=./... -covermode=$(COVERAGE_MODE) ./...
diff --git a/vendor/github.com/go-git/go-billy/v5/README.md b/vendor/github.com/go-git/go-billy/v5/README.md
new file mode 100644
index 00000000..da5c0747
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/README.md
@@ -0,0 +1,73 @@
+# go-billy [![GoDoc](https://godoc.org/gopkg.in/go-git/go-billy.v5?status.svg)](https://pkg.go.dev/github.com/go-git/go-billy/v5) [![Test](https://github.com/go-git/go-billy/workflows/Test/badge.svg)](https://github.com/go-git/go-billy/actions?query=workflow%3ATest)
+
+The missing interface filesystem abstraction for Go.
+Billy implements an interface based on the `os` standard library, allowing to develop applications without dependency on the underlying storage. Makes it virtually free to implement mocks and testing over filesystem operations.
+
+Billy was born as part of [go-git/go-git](https://github.com/go-git/go-git) project.
+
+## Installation
+
+```go
+import "github.com/go-git/go-billy/v5" // with go modules enabled (GO111MODULE=on or outside GOPATH)
+import "github.com/go-git/go-billy" // with go modules disabled
+```
+
+## Usage
+
+Billy exposes filesystems using the
+[`Filesystem` interface](https://pkg.go.dev/github.com/go-git/go-billy/v5?tab=doc#Filesystem).
+Each filesystem implementation gives you a `New` method, whose arguments depend on
+the implementation itself, that returns a new `Filesystem`.
+
+The following example caches in memory all readable files in a directory from any
+billy's filesystem implementation.
+
+```go
+func LoadToMemory(origin billy.Filesystem, path string) (*memory.Memory, error) {
+ memory := memory.New()
+
+ files, err := origin.ReadDir("/")
+ if err != nil {
+ return nil, err
+ }
+
+ for _, file := range files {
+ if file.IsDir() {
+ continue
+ }
+
+ src, err := origin.Open(file.Name())
+ if err != nil {
+ return nil, err
+ }
+
+ dst, err := memory.Create(file.Name())
+ if err != nil {
+ return nil, err
+ }
+
+ if _, err = io.Copy(dst, src); err != nil {
+ return nil, err
+ }
+
+ if err := dst.Close(); err != nil {
+ return nil, err
+ }
+
+ if err := src.Close(); err != nil {
+ return nil, err
+ }
+ }
+
+ return memory, nil
+}
+```
+
+## Why billy?
+
+The library billy deals with storage systems and Billy is the name of a well-known, IKEA
+bookcase. That's it.
+
+## License
+
+Apache License Version 2.0, see [LICENSE](LICENSE)
diff --git a/vendor/github.com/go-git/go-billy/v5/fs.go b/vendor/github.com/go-git/go-billy/v5/fs.go
new file mode 100644
index 00000000..a9efccde
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/fs.go
@@ -0,0 +1,202 @@
+package billy
+
+import (
+ "errors"
+ "io"
+ "os"
+ "time"
+)
+
+var (
+ ErrReadOnly = errors.New("read-only filesystem")
+ ErrNotSupported = errors.New("feature not supported")
+ ErrCrossedBoundary = errors.New("chroot boundary crossed")
+)
+
+// Capability holds the supported features of a billy filesystem. This does
+// not mean that the capability has to be supported by the underlying storage.
+// For example, a billy filesystem may support WriteCapability but the
+// storage be mounted in read only mode.
+type Capability uint64
+
+const (
+ // WriteCapability means that the fs is writable.
+ WriteCapability Capability = 1 << iota
+ // ReadCapability means that the fs is readable.
+ ReadCapability
+ // ReadAndWriteCapability is the ability to open a file in read and write mode.
+ ReadAndWriteCapability
+ // SeekCapability means it is able to move position inside the file.
+ SeekCapability
+ // TruncateCapability means that a file can be truncated.
+ TruncateCapability
+ // LockCapability is the ability to lock a file.
+ LockCapability
+
+ // DefaultCapabilities lists all capable features supported by filesystems
+ // without Capability interface. This list should not be changed until a
+ // major version is released.
+ DefaultCapabilities Capability = WriteCapability | ReadCapability |
+ ReadAndWriteCapability | SeekCapability | TruncateCapability |
+ LockCapability
+
+ // AllCapabilities lists all capable features.
+ AllCapabilities Capability = WriteCapability | ReadCapability |
+ ReadAndWriteCapability | SeekCapability | TruncateCapability |
+ LockCapability
+)
+
+// Filesystem abstract the operations in a storage-agnostic interface.
+// Each method implementation mimics the behavior of the equivalent functions
+// at the os package from the standard library.
+type Filesystem interface {
+ Basic
+ TempFile
+ Dir
+ Symlink
+ Chroot
+}
+
+// Basic abstract the basic operations in a storage-agnostic interface as
+// an extension to the Basic interface.
+type Basic interface {
+ // Create creates the named file with mode 0666 (before umask), truncating
+ // it if it already exists. If successful, methods on the returned File can
+ // be used for I/O; the associated file descriptor has mode O_RDWR.
+ Create(filename string) (File, error)
+ // Open opens the named file for reading. If successful, methods on the
+ // returned file can be used for reading; the associated file descriptor has
+ // mode O_RDONLY.
+ Open(filename string) (File, error)
+ // OpenFile is the generalized open call; most users will use Open or Create
+ // instead. It opens the named file with specified flag (O_RDONLY etc.) and
+ // perm, (0666 etc.) if applicable. If successful, methods on the returned
+ // File can be used for I/O.
+ OpenFile(filename string, flag int, perm os.FileMode) (File, error)
+ // Stat returns a FileInfo describing the named file.
+ Stat(filename string) (os.FileInfo, error)
+ // Rename renames (moves) oldpath to newpath. If newpath already exists and
+ // is not a directory, Rename replaces it. OS-specific restrictions may
+ // apply when oldpath and newpath are in different directories.
+ Rename(oldpath, newpath string) error
+ // Remove removes the named file or directory.
+ Remove(filename string) error
+ // Join joins any number of path elements into a single path, adding a
+ // Separator if necessary. Join calls filepath.Clean on the result; in
+ // particular, all empty strings are ignored. On Windows, the result is a
+ // UNC path if and only if the first path element is a UNC path.
+ Join(elem ...string) string
+}
+
+type TempFile interface {
+ // TempFile creates a new temporary file in the directory dir with a name
+ // beginning with prefix, opens the file for reading and writing, and
+ // returns the resulting *os.File. If dir is the empty string, TempFile
+ // uses the default directory for temporary files (see os.TempDir).
+ // Multiple programs calling TempFile simultaneously will not choose the
+ // same file. The caller can use f.Name() to find the pathname of the file.
+ // It is the caller's responsibility to remove the file when no longer
+ // needed.
+ TempFile(dir, prefix string) (File, error)
+}
+
+// Dir abstract the dir related operations in a storage-agnostic interface as
+// an extension to the Basic interface.
+type Dir interface {
+ // ReadDir reads the directory named by dirname and returns a list of
+ // directory entries sorted by filename.
+ ReadDir(path string) ([]os.FileInfo, error)
+ // MkdirAll creates a directory named path, along with any necessary
+ // parents, and returns nil, or else returns an error. The permission bits
+ // perm are used for all directories that MkdirAll creates. If path is/
+ // already a directory, MkdirAll does nothing and returns nil.
+ MkdirAll(filename string, perm os.FileMode) error
+}
+
+// Symlink abstract the symlink related operations in a storage-agnostic
+// interface as an extension to the Basic interface.
+type Symlink interface {
+ // Lstat returns a FileInfo describing the named file. If the file is a
+ // symbolic link, the returned FileInfo describes the symbolic link. Lstat
+ // makes no attempt to follow the link.
+ Lstat(filename string) (os.FileInfo, error)
+ // Symlink creates a symbolic-link from link to target. target may be an
+ // absolute or relative path, and need not refer to an existing node.
+ // Parent directories of link are created as necessary.
+ Symlink(target, link string) error
+ // Readlink returns the target path of link.
+ Readlink(link string) (string, error)
+}
+
+// Change abstract the FileInfo change related operations in a storage-agnostic
+// interface as an extension to the Basic interface
+type Change interface {
+ // Chmod changes the mode of the named file to mode. If the file is a
+ // symbolic link, it changes the mode of the link's target.
+ Chmod(name string, mode os.FileMode) error
+ // Lchown changes the numeric uid and gid of the named file. If the file is
+ // a symbolic link, it changes the uid and gid of the link itself.
+ Lchown(name string, uid, gid int) error
+ // Chown changes the numeric uid and gid of the named file. If the file is a
+ // symbolic link, it changes the uid and gid of the link's target.
+ Chown(name string, uid, gid int) error
+ // Chtimes changes the access and modification times of the named file,
+ // similar to the Unix utime() or utimes() functions.
+ //
+ // The underlying filesystem may truncate or round the values to a less
+ // precise time unit.
+ Chtimes(name string, atime time.Time, mtime time.Time) error
+}
+
+// Chroot abstract the chroot related operations in a storage-agnostic interface
+// as an extension to the Basic interface.
+type Chroot interface {
+ // Chroot returns a new filesystem from the same type where the new root is
+ // the given path. Files outside of the designated directory tree cannot be
+ // accessed.
+ Chroot(path string) (Filesystem, error)
+ // Root returns the root path of the filesystem.
+ Root() string
+}
+
+// File represent a file, being a subset of the os.File
+type File interface {
+ // Name returns the name of the file as presented to Open.
+ Name() string
+ io.Writer
+ io.Reader
+ io.ReaderAt
+ io.Seeker
+ io.Closer
+ // Lock locks the file like e.g. flock. It protects against access from
+ // other processes.
+ Lock() error
+ // Unlock unlocks the file.
+ Unlock() error
+ // Truncate the file.
+ Truncate(size int64) error
+}
+
+// Capable interface can return the available features of a filesystem.
+type Capable interface {
+ // Capabilities returns the capabilities of a filesystem in bit flags.
+ Capabilities() Capability
+}
+
+// Capabilities returns the features supported by a filesystem. If the FS
+// does not implement Capable interface it returns all features.
+func Capabilities(fs Basic) Capability {
+ capable, ok := fs.(Capable)
+ if !ok {
+ return DefaultCapabilities
+ }
+
+ return capable.Capabilities()
+}
+
+// CapabilityCheck tests the filesystem for the provided capabilities and
+// returns true in case it supports all of them.
+func CapabilityCheck(fs Basic, capabilities Capability) bool {
+ fsCaps := Capabilities(fs)
+ return fsCaps&capabilities == capabilities
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/helper/chroot/chroot.go b/vendor/github.com/go-git/go-billy/v5/helper/chroot/chroot.go
new file mode 100644
index 00000000..8b44e784
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/helper/chroot/chroot.go
@@ -0,0 +1,242 @@
+package chroot
+
+import (
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/helper/polyfill"
+)
+
+// ChrootHelper is a helper to implement billy.Chroot.
+type ChrootHelper struct {
+ underlying billy.Filesystem
+ base string
+}
+
+// New creates a new filesystem wrapping up the given 'fs'.
+// The created filesystem has its base in the given ChrootHelperectory of the
+// underlying filesystem.
+func New(fs billy.Basic, base string) billy.Filesystem {
+ return &ChrootHelper{
+ underlying: polyfill.New(fs),
+ base: base,
+ }
+}
+
+func (fs *ChrootHelper) underlyingPath(filename string) (string, error) {
+ if isCrossBoundaries(filename) {
+ return "", billy.ErrCrossedBoundary
+ }
+
+ return fs.Join(fs.Root(), filename), nil
+}
+
+func isCrossBoundaries(path string) bool {
+ path = filepath.ToSlash(path)
+ path = filepath.Clean(path)
+
+ return strings.HasPrefix(path, ".."+string(filepath.Separator))
+}
+
+func (fs *ChrootHelper) Create(filename string) (billy.File, error) {
+ fullpath, err := fs.underlyingPath(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ f, err := fs.underlying.Create(fullpath)
+ if err != nil {
+ return nil, err
+ }
+
+ return newFile(fs, f, filename), nil
+}
+
+func (fs *ChrootHelper) Open(filename string) (billy.File, error) {
+ fullpath, err := fs.underlyingPath(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ f, err := fs.underlying.Open(fullpath)
+ if err != nil {
+ return nil, err
+ }
+
+ return newFile(fs, f, filename), nil
+}
+
+func (fs *ChrootHelper) OpenFile(filename string, flag int, mode os.FileMode) (billy.File, error) {
+ fullpath, err := fs.underlyingPath(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ f, err := fs.underlying.OpenFile(fullpath, flag, mode)
+ if err != nil {
+ return nil, err
+ }
+
+ return newFile(fs, f, filename), nil
+}
+
+func (fs *ChrootHelper) Stat(filename string) (os.FileInfo, error) {
+ fullpath, err := fs.underlyingPath(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ return fs.underlying.Stat(fullpath)
+}
+
+func (fs *ChrootHelper) Rename(from, to string) error {
+ var err error
+ from, err = fs.underlyingPath(from)
+ if err != nil {
+ return err
+ }
+
+ to, err = fs.underlyingPath(to)
+ if err != nil {
+ return err
+ }
+
+ return fs.underlying.Rename(from, to)
+}
+
+func (fs *ChrootHelper) Remove(path string) error {
+ fullpath, err := fs.underlyingPath(path)
+ if err != nil {
+ return err
+ }
+
+ return fs.underlying.Remove(fullpath)
+}
+
+func (fs *ChrootHelper) Join(elem ...string) string {
+ return fs.underlying.Join(elem...)
+}
+
+func (fs *ChrootHelper) TempFile(dir, prefix string) (billy.File, error) {
+ fullpath, err := fs.underlyingPath(dir)
+ if err != nil {
+ return nil, err
+ }
+
+ f, err := fs.underlying.(billy.TempFile).TempFile(fullpath, prefix)
+ if err != nil {
+ return nil, err
+ }
+
+ return newFile(fs, f, fs.Join(dir, filepath.Base(f.Name()))), nil
+}
+
+func (fs *ChrootHelper) ReadDir(path string) ([]os.FileInfo, error) {
+ fullpath, err := fs.underlyingPath(path)
+ if err != nil {
+ return nil, err
+ }
+
+ return fs.underlying.(billy.Dir).ReadDir(fullpath)
+}
+
+func (fs *ChrootHelper) MkdirAll(filename string, perm os.FileMode) error {
+ fullpath, err := fs.underlyingPath(filename)
+ if err != nil {
+ return err
+ }
+
+ return fs.underlying.(billy.Dir).MkdirAll(fullpath, perm)
+}
+
+func (fs *ChrootHelper) Lstat(filename string) (os.FileInfo, error) {
+ fullpath, err := fs.underlyingPath(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ return fs.underlying.(billy.Symlink).Lstat(fullpath)
+}
+
+func (fs *ChrootHelper) Symlink(target, link string) error {
+ target = filepath.FromSlash(target)
+
+ // only rewrite target if it's already absolute
+ if filepath.IsAbs(target) || strings.HasPrefix(target, string(filepath.Separator)) {
+ target = fs.Join(fs.Root(), target)
+ target = filepath.Clean(filepath.FromSlash(target))
+ }
+
+ link, err := fs.underlyingPath(link)
+ if err != nil {
+ return err
+ }
+
+ return fs.underlying.(billy.Symlink).Symlink(target, link)
+}
+
+func (fs *ChrootHelper) Readlink(link string) (string, error) {
+ fullpath, err := fs.underlyingPath(link)
+ if err != nil {
+ return "", err
+ }
+
+ target, err := fs.underlying.(billy.Symlink).Readlink(fullpath)
+ if err != nil {
+ return "", err
+ }
+
+ if !filepath.IsAbs(target) && !strings.HasPrefix(target, string(filepath.Separator)) {
+ return target, nil
+ }
+
+ target, err = filepath.Rel(fs.base, target)
+ if err != nil {
+ return "", err
+ }
+
+ return string(os.PathSeparator) + target, nil
+}
+
+func (fs *ChrootHelper) Chroot(path string) (billy.Filesystem, error) {
+ fullpath, err := fs.underlyingPath(path)
+ if err != nil {
+ return nil, err
+ }
+
+ return New(fs.underlying, fullpath), nil
+}
+
+func (fs *ChrootHelper) Root() string {
+ return fs.base
+}
+
+func (fs *ChrootHelper) Underlying() billy.Basic {
+ return fs.underlying
+}
+
+// Capabilities implements the Capable interface.
+func (fs *ChrootHelper) Capabilities() billy.Capability {
+ return billy.Capabilities(fs.underlying)
+}
+
+type file struct {
+ billy.File
+ name string
+}
+
+func newFile(fs billy.Filesystem, f billy.File, filename string) billy.File {
+ filename = fs.Join(fs.Root(), filename)
+ filename, _ = filepath.Rel(fs.Root(), filename)
+
+ return &file{
+ File: f,
+ name: filename,
+ }
+}
+
+func (f *file) Name() string {
+ return f.name
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/helper/polyfill/polyfill.go b/vendor/github.com/go-git/go-billy/v5/helper/polyfill/polyfill.go
new file mode 100644
index 00000000..1efce0e7
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/helper/polyfill/polyfill.go
@@ -0,0 +1,105 @@
+package polyfill
+
+import (
+ "os"
+ "path/filepath"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+// Polyfill is a helper that implements all missing method from billy.Filesystem.
+type Polyfill struct {
+ billy.Basic
+ c capabilities
+}
+
+type capabilities struct{ tempfile, dir, symlink, chroot bool }
+
+// New creates a new filesystem wrapping up 'fs' the intercepts all the calls
+// made and errors if fs doesn't implement any of the billy interfaces.
+func New(fs billy.Basic) billy.Filesystem {
+ if original, ok := fs.(billy.Filesystem); ok {
+ return original
+ }
+
+ h := &Polyfill{Basic: fs}
+
+ _, h.c.tempfile = h.Basic.(billy.TempFile)
+ _, h.c.dir = h.Basic.(billy.Dir)
+ _, h.c.symlink = h.Basic.(billy.Symlink)
+ _, h.c.chroot = h.Basic.(billy.Chroot)
+ return h
+}
+
+func (h *Polyfill) TempFile(dir, prefix string) (billy.File, error) {
+ if !h.c.tempfile {
+ return nil, billy.ErrNotSupported
+ }
+
+ return h.Basic.(billy.TempFile).TempFile(dir, prefix)
+}
+
+func (h *Polyfill) ReadDir(path string) ([]os.FileInfo, error) {
+ if !h.c.dir {
+ return nil, billy.ErrNotSupported
+ }
+
+ return h.Basic.(billy.Dir).ReadDir(path)
+}
+
+func (h *Polyfill) MkdirAll(filename string, perm os.FileMode) error {
+ if !h.c.dir {
+ return billy.ErrNotSupported
+ }
+
+ return h.Basic.(billy.Dir).MkdirAll(filename, perm)
+}
+
+func (h *Polyfill) Symlink(target, link string) error {
+ if !h.c.symlink {
+ return billy.ErrNotSupported
+ }
+
+ return h.Basic.(billy.Symlink).Symlink(target, link)
+}
+
+func (h *Polyfill) Readlink(link string) (string, error) {
+ if !h.c.symlink {
+ return "", billy.ErrNotSupported
+ }
+
+ return h.Basic.(billy.Symlink).Readlink(link)
+}
+
+func (h *Polyfill) Lstat(path string) (os.FileInfo, error) {
+ if !h.c.symlink {
+ return nil, billy.ErrNotSupported
+ }
+
+ return h.Basic.(billy.Symlink).Lstat(path)
+}
+
+func (h *Polyfill) Chroot(path string) (billy.Filesystem, error) {
+ if !h.c.chroot {
+ return nil, billy.ErrNotSupported
+ }
+
+ return h.Basic.(billy.Chroot).Chroot(path)
+}
+
+func (h *Polyfill) Root() string {
+ if !h.c.chroot {
+ return string(filepath.Separator)
+ }
+
+ return h.Basic.(billy.Chroot).Root()
+}
+
+func (h *Polyfill) Underlying() billy.Basic {
+ return h.Basic
+}
+
+// Capabilities implements the Capable interface.
+func (h *Polyfill) Capabilities() billy.Capability {
+ return billy.Capabilities(h.Basic)
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/memfs/memory.go b/vendor/github.com/go-git/go-billy/v5/memfs/memory.go
new file mode 100644
index 00000000..dab73968
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/memfs/memory.go
@@ -0,0 +1,410 @@
+// Package memfs provides a billy filesystem base on memory.
+package memfs // import "github.com/go-git/go-billy/v5/memfs"
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/helper/chroot"
+ "github.com/go-git/go-billy/v5/util"
+)
+
+const separator = filepath.Separator
+
+// Memory a very convenient filesystem based on memory files
+type Memory struct {
+ s *storage
+
+ tempCount int
+}
+
+//New returns a new Memory filesystem.
+func New() billy.Filesystem {
+ fs := &Memory{s: newStorage()}
+ return chroot.New(fs, string(separator))
+}
+
+func (fs *Memory) Create(filename string) (billy.File, error) {
+ return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
+}
+
+func (fs *Memory) Open(filename string) (billy.File, error) {
+ return fs.OpenFile(filename, os.O_RDONLY, 0)
+}
+
+func (fs *Memory) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
+ f, has := fs.s.Get(filename)
+ if !has {
+ if !isCreate(flag) {
+ return nil, os.ErrNotExist
+ }
+
+ var err error
+ f, err = fs.s.New(filename, perm, flag)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ if isExclusive(flag) {
+ return nil, os.ErrExist
+ }
+
+ if target, isLink := fs.resolveLink(filename, f); isLink {
+ return fs.OpenFile(target, flag, perm)
+ }
+ }
+
+ if f.mode.IsDir() {
+ return nil, fmt.Errorf("cannot open directory: %s", filename)
+ }
+
+ return f.Duplicate(filename, perm, flag), nil
+}
+
+var errNotLink = errors.New("not a link")
+
+func (fs *Memory) resolveLink(fullpath string, f *file) (target string, isLink bool) {
+ if !isSymlink(f.mode) {
+ return fullpath, false
+ }
+
+ target = string(f.content.bytes)
+ if !isAbs(target) {
+ target = fs.Join(filepath.Dir(fullpath), target)
+ }
+
+ return target, true
+}
+
+// On Windows OS, IsAbs validates if a path is valid based on if stars with a
+// unit (eg.: `C:\`) to assert that is absolute, but in this mem implementation
+// any path starting by `separator` is also considered absolute.
+func isAbs(path string) bool {
+ return filepath.IsAbs(path) || strings.HasPrefix(path, string(separator))
+}
+
+func (fs *Memory) Stat(filename string) (os.FileInfo, error) {
+ f, has := fs.s.Get(filename)
+ if !has {
+ return nil, os.ErrNotExist
+ }
+
+ fi, _ := f.Stat()
+
+ var err error
+ if target, isLink := fs.resolveLink(filename, f); isLink {
+ fi, err = fs.Stat(target)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // the name of the file should always the name of the stated file, so we
+ // overwrite the Stat returned from the storage with it, since the
+ // filename may belong to a link.
+ fi.(*fileInfo).name = filepath.Base(filename)
+ return fi, nil
+}
+
+func (fs *Memory) Lstat(filename string) (os.FileInfo, error) {
+ f, has := fs.s.Get(filename)
+ if !has {
+ return nil, os.ErrNotExist
+ }
+
+ return f.Stat()
+}
+
+type ByName []os.FileInfo
+
+func (a ByName) Len() int { return len(a) }
+func (a ByName) Less(i, j int) bool { return a[i].Name() < a[j].Name() }
+func (a ByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+func (fs *Memory) ReadDir(path string) ([]os.FileInfo, error) {
+ if f, has := fs.s.Get(path); has {
+ if target, isLink := fs.resolveLink(path, f); isLink {
+ return fs.ReadDir(target)
+ }
+ }
+
+ var entries []os.FileInfo
+ for _, f := range fs.s.Children(path) {
+ fi, _ := f.Stat()
+ entries = append(entries, fi)
+ }
+
+ sort.Sort(ByName(entries))
+
+ return entries, nil
+}
+
+func (fs *Memory) MkdirAll(path string, perm os.FileMode) error {
+ _, err := fs.s.New(path, perm|os.ModeDir, 0)
+ return err
+}
+
+func (fs *Memory) TempFile(dir, prefix string) (billy.File, error) {
+ return util.TempFile(fs, dir, prefix)
+}
+
+func (fs *Memory) getTempFilename(dir, prefix string) string {
+ fs.tempCount++
+ filename := fmt.Sprintf("%s_%d_%d", prefix, fs.tempCount, time.Now().UnixNano())
+ return fs.Join(dir, filename)
+}
+
+func (fs *Memory) Rename(from, to string) error {
+ return fs.s.Rename(from, to)
+}
+
+func (fs *Memory) Remove(filename string) error {
+ return fs.s.Remove(filename)
+}
+
+func (fs *Memory) Join(elem ...string) string {
+ return filepath.Join(elem...)
+}
+
+func (fs *Memory) Symlink(target, link string) error {
+ _, err := fs.Stat(link)
+ if err == nil {
+ return os.ErrExist
+ }
+
+ if !os.IsNotExist(err) {
+ return err
+ }
+
+ return util.WriteFile(fs, link, []byte(target), 0777|os.ModeSymlink)
+}
+
+func (fs *Memory) Readlink(link string) (string, error) {
+ f, has := fs.s.Get(link)
+ if !has {
+ return "", os.ErrNotExist
+ }
+
+ if !isSymlink(f.mode) {
+ return "", &os.PathError{
+ Op: "readlink",
+ Path: link,
+ Err: fmt.Errorf("not a symlink"),
+ }
+ }
+
+ return string(f.content.bytes), nil
+}
+
+// Capabilities implements the Capable interface.
+func (fs *Memory) Capabilities() billy.Capability {
+ return billy.WriteCapability |
+ billy.ReadCapability |
+ billy.ReadAndWriteCapability |
+ billy.SeekCapability |
+ billy.TruncateCapability
+}
+
+type file struct {
+ name string
+ content *content
+ position int64
+ flag int
+ mode os.FileMode
+
+ isClosed bool
+}
+
+func (f *file) Name() string {
+ return f.name
+}
+
+func (f *file) Read(b []byte) (int, error) {
+ n, err := f.ReadAt(b, f.position)
+ f.position += int64(n)
+
+ if err == io.EOF && n != 0 {
+ err = nil
+ }
+
+ return n, err
+}
+
+func (f *file) ReadAt(b []byte, off int64) (int, error) {
+ if f.isClosed {
+ return 0, os.ErrClosed
+ }
+
+ if !isReadAndWrite(f.flag) && !isReadOnly(f.flag) {
+ return 0, errors.New("read not supported")
+ }
+
+ n, err := f.content.ReadAt(b, off)
+
+ return n, err
+}
+
+func (f *file) Seek(offset int64, whence int) (int64, error) {
+ if f.isClosed {
+ return 0, os.ErrClosed
+ }
+
+ switch whence {
+ case io.SeekCurrent:
+ f.position += offset
+ case io.SeekStart:
+ f.position = offset
+ case io.SeekEnd:
+ f.position = int64(f.content.Len()) + offset
+ }
+
+ return f.position, nil
+}
+
+func (f *file) Write(p []byte) (int, error) {
+ if f.isClosed {
+ return 0, os.ErrClosed
+ }
+
+ if !isReadAndWrite(f.flag) && !isWriteOnly(f.flag) {
+ return 0, errors.New("write not supported")
+ }
+
+ n, err := f.content.WriteAt(p, f.position)
+ f.position += int64(n)
+
+ return n, err
+}
+
+func (f *file) Close() error {
+ if f.isClosed {
+ return os.ErrClosed
+ }
+
+ f.isClosed = true
+ return nil
+}
+
+func (f *file) Truncate(size int64) error {
+ if size < int64(len(f.content.bytes)) {
+ f.content.bytes = f.content.bytes[:size]
+ } else if more := int(size) - len(f.content.bytes); more > 0 {
+ f.content.bytes = append(f.content.bytes, make([]byte, more)...)
+ }
+
+ return nil
+}
+
+func (f *file) Duplicate(filename string, mode os.FileMode, flag int) billy.File {
+ new := &file{
+ name: filename,
+ content: f.content,
+ mode: mode,
+ flag: flag,
+ }
+
+ if isTruncate(flag) {
+ new.content.Truncate()
+ }
+
+ if isAppend(flag) {
+ new.position = int64(new.content.Len())
+ }
+
+ return new
+}
+
+func (f *file) Stat() (os.FileInfo, error) {
+ return &fileInfo{
+ name: f.Name(),
+ mode: f.mode,
+ size: f.content.Len(),
+ }, nil
+}
+
+// Lock is a no-op in memfs.
+func (f *file) Lock() error {
+ return nil
+}
+
+// Unlock is a no-op in memfs.
+func (f *file) Unlock() error {
+ return nil
+}
+
+type fileInfo struct {
+ name string
+ size int
+ mode os.FileMode
+}
+
+func (fi *fileInfo) Name() string {
+ return fi.name
+}
+
+func (fi *fileInfo) Size() int64 {
+ return int64(fi.size)
+}
+
+func (fi *fileInfo) Mode() os.FileMode {
+ return fi.mode
+}
+
+func (*fileInfo) ModTime() time.Time {
+ return time.Now()
+}
+
+func (fi *fileInfo) IsDir() bool {
+ return fi.mode.IsDir()
+}
+
+func (*fileInfo) Sys() interface{} {
+ return nil
+}
+
+func (c *content) Truncate() {
+ c.bytes = make([]byte, 0)
+}
+
+func (c *content) Len() int {
+ return len(c.bytes)
+}
+
+func isCreate(flag int) bool {
+ return flag&os.O_CREATE != 0
+}
+
+func isExclusive(flag int) bool {
+ return flag&os.O_EXCL != 0
+}
+
+func isAppend(flag int) bool {
+ return flag&os.O_APPEND != 0
+}
+
+func isTruncate(flag int) bool {
+ return flag&os.O_TRUNC != 0
+}
+
+func isReadAndWrite(flag int) bool {
+ return flag&os.O_RDWR != 0
+}
+
+func isReadOnly(flag int) bool {
+ return flag == os.O_RDONLY
+}
+
+func isWriteOnly(flag int) bool {
+ return flag&os.O_WRONLY != 0
+}
+
+func isSymlink(m os.FileMode) bool {
+ return m&os.ModeSymlink != 0
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/memfs/storage.go b/vendor/github.com/go-git/go-billy/v5/memfs/storage.go
new file mode 100644
index 00000000..e3c4e38b
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/memfs/storage.go
@@ -0,0 +1,238 @@
+package memfs
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "sync"
+)
+
+type storage struct {
+ files map[string]*file
+ children map[string]map[string]*file
+}
+
+func newStorage() *storage {
+ return &storage{
+ files: make(map[string]*file, 0),
+ children: make(map[string]map[string]*file, 0),
+ }
+}
+
+func (s *storage) Has(path string) bool {
+ path = clean(path)
+
+ _, ok := s.files[path]
+ return ok
+}
+
+func (s *storage) New(path string, mode os.FileMode, flag int) (*file, error) {
+ path = clean(path)
+ if s.Has(path) {
+ if !s.MustGet(path).mode.IsDir() {
+ return nil, fmt.Errorf("file already exists %q", path)
+ }
+
+ return nil, nil
+ }
+
+ name := filepath.Base(path)
+
+ f := &file{
+ name: name,
+ content: &content{name: name},
+ mode: mode,
+ flag: flag,
+ }
+
+ s.files[path] = f
+ s.createParent(path, mode, f)
+ return f, nil
+}
+
+func (s *storage) createParent(path string, mode os.FileMode, f *file) error {
+ base := filepath.Dir(path)
+ base = clean(base)
+ if f.Name() == string(separator) {
+ return nil
+ }
+
+ if _, err := s.New(base, mode.Perm()|os.ModeDir, 0); err != nil {
+ return err
+ }
+
+ if _, ok := s.children[base]; !ok {
+ s.children[base] = make(map[string]*file, 0)
+ }
+
+ s.children[base][f.Name()] = f
+ return nil
+}
+
+func (s *storage) Children(path string) []*file {
+ path = clean(path)
+
+ l := make([]*file, 0)
+ for _, f := range s.children[path] {
+ l = append(l, f)
+ }
+
+ return l
+}
+
+func (s *storage) MustGet(path string) *file {
+ f, ok := s.Get(path)
+ if !ok {
+ panic(fmt.Errorf("couldn't find %q", path))
+ }
+
+ return f
+}
+
+func (s *storage) Get(path string) (*file, bool) {
+ path = clean(path)
+ if !s.Has(path) {
+ return nil, false
+ }
+
+ file, ok := s.files[path]
+ return file, ok
+}
+
+func (s *storage) Rename(from, to string) error {
+ from = clean(from)
+ to = clean(to)
+
+ if !s.Has(from) {
+ return os.ErrNotExist
+ }
+
+ move := [][2]string{{from, to}}
+
+ for pathFrom := range s.files {
+ if pathFrom == from || !filepath.HasPrefix(pathFrom, from) {
+ continue
+ }
+
+ rel, _ := filepath.Rel(from, pathFrom)
+ pathTo := filepath.Join(to, rel)
+
+ move = append(move, [2]string{pathFrom, pathTo})
+ }
+
+ for _, ops := range move {
+ from := ops[0]
+ to := ops[1]
+
+ if err := s.move(from, to); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (s *storage) move(from, to string) error {
+ s.files[to] = s.files[from]
+ s.files[to].name = filepath.Base(to)
+ s.children[to] = s.children[from]
+
+ defer func() {
+ delete(s.children, from)
+ delete(s.files, from)
+ delete(s.children[filepath.Dir(from)], filepath.Base(from))
+ }()
+
+ return s.createParent(to, 0644, s.files[to])
+}
+
+func (s *storage) Remove(path string) error {
+ path = clean(path)
+
+ f, has := s.Get(path)
+ if !has {
+ return os.ErrNotExist
+ }
+
+ if f.mode.IsDir() && len(s.children[path]) != 0 {
+ return fmt.Errorf("dir: %s contains files", path)
+ }
+
+ base, file := filepath.Split(path)
+ base = filepath.Clean(base)
+
+ delete(s.children[base], file)
+ delete(s.files, path)
+ return nil
+}
+
+func clean(path string) string {
+ return filepath.Clean(filepath.FromSlash(path))
+}
+
+type content struct {
+ name string
+ bytes []byte
+
+ m sync.RWMutex
+}
+
+func (c *content) WriteAt(p []byte, off int64) (int, error) {
+ if off < 0 {
+ return 0, &os.PathError{
+ Op: "writeat",
+ Path: c.name,
+ Err: errors.New("negative offset"),
+ }
+ }
+
+ c.m.Lock()
+ prev := len(c.bytes)
+
+ diff := int(off) - prev
+ if diff > 0 {
+ c.bytes = append(c.bytes, make([]byte, diff)...)
+ }
+
+ c.bytes = append(c.bytes[:off], p...)
+ if len(c.bytes) < prev {
+ c.bytes = c.bytes[:prev]
+ }
+ c.m.Unlock()
+
+ return len(p), nil
+}
+
+func (c *content) ReadAt(b []byte, off int64) (n int, err error) {
+ if off < 0 {
+ return 0, &os.PathError{
+ Op: "readat",
+ Path: c.name,
+ Err: errors.New("negative offset"),
+ }
+ }
+
+ c.m.RLock()
+ size := int64(len(c.bytes))
+ if off >= size {
+ c.m.RUnlock()
+ return 0, io.EOF
+ }
+
+ l := int64(len(b))
+ if off+l > size {
+ l = size - off
+ }
+
+ btr := c.bytes[off : off+l]
+ n = copy(b, btr)
+
+ if len(btr) < len(b) {
+ err = io.EOF
+ }
+ c.m.RUnlock()
+
+ return
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os.go b/vendor/github.com/go-git/go-billy/v5/osfs/os.go
new file mode 100644
index 00000000..a7fe79f2
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os.go
@@ -0,0 +1,127 @@
+//go:build !js
+// +build !js
+
+// Package osfs provides a billy filesystem for the OS.
+package osfs
+
+import (
+ "fmt"
+ "io/fs"
+ "os"
+ "sync"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+const (
+ defaultDirectoryMode = 0o755
+ defaultCreateMode = 0o666
+)
+
+// Default Filesystem representing the root of the os filesystem.
+var Default = &ChrootOS{}
+
+// New returns a new OS filesystem.
+// By default paths are deduplicated, but still enforced
+// under baseDir. For more info refer to WithDeduplicatePath.
+func New(baseDir string, opts ...Option) billy.Filesystem {
+ o := &options{
+ deduplicatePath: true,
+ }
+ for _, opt := range opts {
+ opt(o)
+ }
+
+ if o.Type == BoundOSFS {
+ return newBoundOS(baseDir, o.deduplicatePath)
+ }
+
+ return newChrootOS(baseDir)
+}
+
+// WithBoundOS returns the option of using a Bound filesystem OS.
+func WithBoundOS() Option {
+ return func(o *options) {
+ o.Type = BoundOSFS
+ }
+}
+
+// WithChrootOS returns the option of using a Chroot filesystem OS.
+func WithChrootOS() Option {
+ return func(o *options) {
+ o.Type = ChrootOSFS
+ }
+}
+
+// WithDeduplicatePath toggles the deduplication of the base dir in the path.
+// This occurs when absolute links are being used.
+// Assuming base dir /base/dir and an absolute symlink /base/dir/target:
+//
+// With DeduplicatePath (default): /base/dir/target
+// Without DeduplicatePath: /base/dir/base/dir/target
+//
+// This option is only used by the BoundOS OS type.
+func WithDeduplicatePath(enabled bool) Option {
+ return func(o *options) {
+ o.deduplicatePath = enabled
+ }
+}
+
+type options struct {
+ Type
+ deduplicatePath bool
+}
+
+type Type int
+
+const (
+ ChrootOSFS Type = iota
+ BoundOSFS
+)
+
+func readDir(dir string) ([]os.FileInfo, error) {
+ entries, err := os.ReadDir(dir)
+ if err != nil {
+ return nil, err
+ }
+ infos := make([]fs.FileInfo, 0, len(entries))
+ for _, entry := range entries {
+ fi, err := entry.Info()
+ if err != nil {
+ return nil, err
+ }
+ infos = append(infos, fi)
+ }
+ return infos, nil
+}
+
+func tempFile(dir, prefix string) (billy.File, error) {
+ f, err := os.CreateTemp(dir, prefix)
+ if err != nil {
+ return nil, err
+ }
+ return &file{File: f}, nil
+}
+
+func openFile(fn string, flag int, perm os.FileMode, createDir func(string) error) (billy.File, error) {
+ if flag&os.O_CREATE != 0 {
+ if createDir == nil {
+ return nil, fmt.Errorf("createDir func cannot be nil if file needs to be opened in create mode")
+ }
+ if err := createDir(fn); err != nil {
+ return nil, err
+ }
+ }
+
+ f, err := os.OpenFile(fn, flag, perm)
+ if err != nil {
+ return nil, err
+ }
+ return &file{File: f}, err
+}
+
+// file is a wrapper for an os.File which adds support for file locking.
+type file struct {
+ *os.File
+ m sync.Mutex
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_bound.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_bound.go
new file mode 100644
index 00000000..b4b6dbc0
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_bound.go
@@ -0,0 +1,261 @@
+//go:build !js
+// +build !js
+
+/*
+ Copyright 2022 The Flux 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 osfs
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ securejoin "github.com/cyphar/filepath-securejoin"
+ "github.com/go-git/go-billy/v5"
+)
+
+// BoundOS is a fs implementation based on the OS filesystem which is bound to
+// a base dir.
+// Prefer this fs implementation over ChrootOS.
+//
+// Behaviours of note:
+// 1. Read and write operations can only be directed to files which descends
+// from the base dir.
+// 2. Symlinks don't have their targets modified, and therefore can point
+// to locations outside the base dir or to non-existent paths.
+// 3. Readlink and Lstat ensures that the link file is located within the base
+// dir, evaluating any symlinks that file or base dir may contain.
+type BoundOS struct {
+ baseDir string
+ deduplicatePath bool
+}
+
+func newBoundOS(d string, deduplicatePath bool) billy.Filesystem {
+ return &BoundOS{baseDir: d, deduplicatePath: deduplicatePath}
+}
+
+func (fs *BoundOS) Create(filename string) (billy.File, error) {
+ return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, defaultCreateMode)
+}
+
+func (fs *BoundOS) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
+ fn, err := fs.abs(filename)
+ if err != nil {
+ return nil, err
+ }
+ return openFile(fn, flag, perm, fs.createDir)
+}
+
+func (fs *BoundOS) ReadDir(path string) ([]os.FileInfo, error) {
+ dir, err := fs.abs(path)
+ if err != nil {
+ return nil, err
+ }
+
+ return readDir(dir)
+}
+
+func (fs *BoundOS) Rename(from, to string) error {
+ f, err := fs.abs(from)
+ if err != nil {
+ return err
+ }
+ t, err := fs.abs(to)
+ if err != nil {
+ return err
+ }
+
+ // MkdirAll for target name.
+ if err := fs.createDir(t); err != nil {
+ return err
+ }
+
+ return os.Rename(f, t)
+}
+
+func (fs *BoundOS) MkdirAll(path string, perm os.FileMode) error {
+ dir, err := fs.abs(path)
+ if err != nil {
+ return err
+ }
+ return os.MkdirAll(dir, perm)
+}
+
+func (fs *BoundOS) Open(filename string) (billy.File, error) {
+ return fs.OpenFile(filename, os.O_RDONLY, 0)
+}
+
+func (fs *BoundOS) Stat(filename string) (os.FileInfo, error) {
+ filename, err := fs.abs(filename)
+ if err != nil {
+ return nil, err
+ }
+ return os.Stat(filename)
+}
+
+func (fs *BoundOS) Remove(filename string) error {
+ fn, err := fs.abs(filename)
+ if err != nil {
+ return err
+ }
+ return os.Remove(fn)
+}
+
+// TempFile creates a temporary file. If dir is empty, the file
+// will be created within the OS Temporary dir. If dir is provided
+// it must descend from the current base dir.
+func (fs *BoundOS) TempFile(dir, prefix string) (billy.File, error) {
+ if dir != "" {
+ var err error
+ dir, err = fs.abs(dir)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return tempFile(dir, prefix)
+}
+
+func (fs *BoundOS) Join(elem ...string) string {
+ return filepath.Join(elem...)
+}
+
+func (fs *BoundOS) RemoveAll(path string) error {
+ dir, err := fs.abs(path)
+ if err != nil {
+ return err
+ }
+ return os.RemoveAll(dir)
+}
+
+func (fs *BoundOS) Symlink(target, link string) error {
+ ln, err := fs.abs(link)
+ if err != nil {
+ return err
+ }
+ // MkdirAll for containing dir.
+ if err := fs.createDir(ln); err != nil {
+ return err
+ }
+ return os.Symlink(target, ln)
+}
+
+func (fs *BoundOS) Lstat(filename string) (os.FileInfo, error) {
+ filename = filepath.Clean(filename)
+ if !filepath.IsAbs(filename) {
+ filename = filepath.Join(fs.baseDir, filename)
+ }
+ if ok, err := fs.insideBaseDirEval(filename); !ok {
+ return nil, err
+ }
+ return os.Lstat(filename)
+}
+
+func (fs *BoundOS) Readlink(link string) (string, error) {
+ if !filepath.IsAbs(link) {
+ link = filepath.Clean(filepath.Join(fs.baseDir, link))
+ }
+ if ok, err := fs.insideBaseDirEval(link); !ok {
+ return "", err
+ }
+ return os.Readlink(link)
+}
+
+// Chroot returns a new OS filesystem, with the base dir set to the
+// result of joining the provided path with the underlying base dir.
+func (fs *BoundOS) Chroot(path string) (billy.Filesystem, error) {
+ joined, err := securejoin.SecureJoin(fs.baseDir, path)
+ if err != nil {
+ return nil, err
+ }
+ return New(joined), nil
+}
+
+// Root returns the current base dir of the billy.Filesystem.
+// This is required in order for this implementation to be a drop-in
+// replacement for other upstream implementations (e.g. memory and osfs).
+func (fs *BoundOS) Root() string {
+ return fs.baseDir
+}
+
+func (fs *BoundOS) createDir(fullpath string) error {
+ dir := filepath.Dir(fullpath)
+ if dir != "." {
+ if err := os.MkdirAll(dir, defaultDirectoryMode); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// abs transforms filename to an absolute path, taking into account the base dir.
+// Relative paths won't be allowed to ascend the base dir, so `../file` will become
+// `/working-dir/file`.
+//
+// Note that if filename is a symlink, the returned address will be the target of the
+// symlink.
+func (fs *BoundOS) abs(filename string) (string, error) {
+ if filename == fs.baseDir {
+ filename = string(filepath.Separator)
+ }
+
+ path, err := securejoin.SecureJoin(fs.baseDir, filename)
+ if err != nil {
+ return "", nil
+ }
+
+ if fs.deduplicatePath {
+ vol := filepath.VolumeName(fs.baseDir)
+ dup := filepath.Join(fs.baseDir, fs.baseDir[len(vol):])
+ if strings.HasPrefix(path, dup+string(filepath.Separator)) {
+ return fs.abs(path[len(dup):])
+ }
+ }
+ return path, nil
+}
+
+// insideBaseDir checks whether filename is located within
+// the fs.baseDir.
+func (fs *BoundOS) insideBaseDir(filename string) (bool, error) {
+ if filename == fs.baseDir {
+ return true, nil
+ }
+ if !strings.HasPrefix(filename, fs.baseDir+string(filepath.Separator)) {
+ return false, fmt.Errorf("path outside base dir")
+ }
+ return true, nil
+}
+
+// insideBaseDirEval checks whether filename is contained within
+// a dir that is within the fs.baseDir, by first evaluating any symlinks
+// that either filename or fs.baseDir may contain.
+func (fs *BoundOS) insideBaseDirEval(filename string) (bool, error) {
+ dir, err := filepath.EvalSymlinks(filepath.Dir(filename))
+ if dir == "" || os.IsNotExist(err) {
+ dir = filepath.Dir(filename)
+ }
+ wd, err := filepath.EvalSymlinks(fs.baseDir)
+ if wd == "" || os.IsNotExist(err) {
+ wd = fs.baseDir
+ }
+ if filename != wd && dir != wd && !strings.HasPrefix(dir, wd+string(filepath.Separator)) {
+ return false, fmt.Errorf("path outside base dir")
+ }
+ return true, nil
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_chroot.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_chroot.go
new file mode 100644
index 00000000..fd65e773
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_chroot.go
@@ -0,0 +1,112 @@
+//go:build !js
+// +build !js
+
+package osfs
+
+import (
+ "os"
+ "path/filepath"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/helper/chroot"
+)
+
+// ChrootOS is a legacy filesystem based on a "soft chroot" of the os filesystem.
+// Although this is still the default os filesystem, consider using BoundOS instead.
+//
+// Behaviours of note:
+// 1. A "soft chroot" translates the base dir to "/" for the purposes of the
+// fs abstraction.
+// 2. Symlinks targets may be modified to be kept within the chroot bounds.
+// 3. Some file modes does not pass-through the fs abstraction.
+// 4. The combination of 1 and 2 may cause go-git to think that a Git repository
+// is dirty, when in fact it isn't.
+type ChrootOS struct{}
+
+func newChrootOS(baseDir string) billy.Filesystem {
+ return chroot.New(&ChrootOS{}, baseDir)
+}
+
+func (fs *ChrootOS) Create(filename string) (billy.File, error) {
+ return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, defaultCreateMode)
+}
+
+func (fs *ChrootOS) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
+ return openFile(filename, flag, perm, fs.createDir)
+}
+
+func (fs *ChrootOS) createDir(fullpath string) error {
+ dir := filepath.Dir(fullpath)
+ if dir != "." {
+ if err := os.MkdirAll(dir, defaultDirectoryMode); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (fs *ChrootOS) ReadDir(dir string) ([]os.FileInfo, error) {
+ return readDir(dir)
+}
+
+func (fs *ChrootOS) Rename(from, to string) error {
+ if err := fs.createDir(to); err != nil {
+ return err
+ }
+
+ return rename(from, to)
+}
+
+func (fs *ChrootOS) MkdirAll(path string, perm os.FileMode) error {
+ return os.MkdirAll(path, defaultDirectoryMode)
+}
+
+func (fs *ChrootOS) Open(filename string) (billy.File, error) {
+ return fs.OpenFile(filename, os.O_RDONLY, 0)
+}
+
+func (fs *ChrootOS) Stat(filename string) (os.FileInfo, error) {
+ return os.Stat(filename)
+}
+
+func (fs *ChrootOS) Remove(filename string) error {
+ return os.Remove(filename)
+}
+
+func (fs *ChrootOS) TempFile(dir, prefix string) (billy.File, error) {
+ if err := fs.createDir(dir + string(os.PathSeparator)); err != nil {
+ return nil, err
+ }
+
+ return tempFile(dir, prefix)
+}
+
+func (fs *ChrootOS) Join(elem ...string) string {
+ return filepath.Join(elem...)
+}
+
+func (fs *ChrootOS) RemoveAll(path string) error {
+ return os.RemoveAll(filepath.Clean(path))
+}
+
+func (fs *ChrootOS) Lstat(filename string) (os.FileInfo, error) {
+ return os.Lstat(filepath.Clean(filename))
+}
+
+func (fs *ChrootOS) Symlink(target, link string) error {
+ if err := fs.createDir(link); err != nil {
+ return err
+ }
+
+ return os.Symlink(target, link)
+}
+
+func (fs *ChrootOS) Readlink(link string) (string, error) {
+ return os.Readlink(link)
+}
+
+// Capabilities implements the Capable interface.
+func (fs *ChrootOS) Capabilities() billy.Capability {
+ return billy.DefaultCapabilities
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_js.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_js.go
new file mode 100644
index 00000000..2e58aa5c
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_js.go
@@ -0,0 +1,25 @@
+//go:build js
+// +build js
+
+package osfs
+
+import (
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/helper/chroot"
+ "github.com/go-git/go-billy/v5/memfs"
+)
+
+// globalMemFs is the global memory fs
+var globalMemFs = memfs.New()
+
+// Default Filesystem representing the root of in-memory filesystem for a
+// js/wasm environment.
+var Default = memfs.New()
+
+// New returns a new OS filesystem.
+func New(baseDir string, _ ...Option) billy.Filesystem {
+ return chroot.New(Default, Default.Join("/", baseDir))
+}
+
+type options struct {
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_options.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_options.go
new file mode 100644
index 00000000..2f235c6d
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_options.go
@@ -0,0 +1,3 @@
+package osfs
+
+type Option func(*options)
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_plan9.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_plan9.go
new file mode 100644
index 00000000..84020b52
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_plan9.go
@@ -0,0 +1,91 @@
+//go:build plan9
+// +build plan9
+
+package osfs
+
+import (
+ "io"
+ "os"
+ "path/filepath"
+ "syscall"
+)
+
+func (f *file) Lock() error {
+ // Plan 9 uses a mode bit instead of explicit lock/unlock syscalls.
+ //
+ // Per http://man.cat-v.org/plan_9/5/stat: “Exclusive use files may be open
+ // for I/O by only one fid at a time across all clients of the server. If a
+ // second open is attempted, it draws an error.”
+ //
+ // There is no obvious way to implement this function using the exclusive use bit.
+ // See https://golang.org/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
+ // for how file locking is done by the go tool on Plan 9.
+ return nil
+}
+
+func (f *file) Unlock() error {
+ return nil
+}
+
+func rename(from, to string) error {
+ // If from and to are in different directories, copy the file
+ // since Plan 9 does not support cross-directory rename.
+ if filepath.Dir(from) != filepath.Dir(to) {
+ fi, err := os.Stat(from)
+ if err != nil {
+ return &os.LinkError{"rename", from, to, err}
+ }
+ if fi.Mode().IsDir() {
+ return &os.LinkError{"rename", from, to, syscall.EISDIR}
+ }
+ fromFile, err := os.Open(from)
+ if err != nil {
+ return &os.LinkError{"rename", from, to, err}
+ }
+ toFile, err := os.OpenFile(to, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, fi.Mode())
+ if err != nil {
+ return &os.LinkError{"rename", from, to, err}
+ }
+ _, err = io.Copy(toFile, fromFile)
+ if err != nil {
+ return &os.LinkError{"rename", from, to, err}
+ }
+
+ // Copy mtime and mode from original file.
+ // We need only one syscall if we avoid os.Chmod and os.Chtimes.
+ dir := fi.Sys().(*syscall.Dir)
+ var d syscall.Dir
+ d.Null()
+ d.Mtime = dir.Mtime
+ d.Mode = dir.Mode
+ if err = dirwstat(to, &d); err != nil {
+ return &os.LinkError{"rename", from, to, err}
+ }
+
+ // Remove original file.
+ err = os.Remove(from)
+ if err != nil {
+ return &os.LinkError{"rename", from, to, err}
+ }
+ return nil
+ }
+ return os.Rename(from, to)
+}
+
+func dirwstat(name string, d *syscall.Dir) error {
+ var buf [syscall.STATFIXLEN]byte
+
+ n, err := d.Marshal(buf[:])
+ if err != nil {
+ return &os.PathError{"dirwstat", name, err}
+ }
+ if err = syscall.Wstat(name, buf[:n]); err != nil {
+ return &os.PathError{"dirwstat", name, err}
+ }
+ return nil
+}
+
+func umask(new int) func() {
+ return func() {
+ }
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_posix.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_posix.go
new file mode 100644
index 00000000..d834a114
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_posix.go
@@ -0,0 +1,38 @@
+//go:build !plan9 && !windows && !js
+// +build !plan9,!windows,!js
+
+package osfs
+
+import (
+ "os"
+ "syscall"
+
+ "golang.org/x/sys/unix"
+)
+
+func (f *file) Lock() error {
+ f.m.Lock()
+ defer f.m.Unlock()
+
+ return unix.Flock(int(f.File.Fd()), unix.LOCK_EX)
+}
+
+func (f *file) Unlock() error {
+ f.m.Lock()
+ defer f.m.Unlock()
+
+ return unix.Flock(int(f.File.Fd()), unix.LOCK_UN)
+}
+
+func rename(from, to string) error {
+ return os.Rename(from, to)
+}
+
+// umask sets umask to a new value, and returns a func which allows the
+// caller to reset it back to what it was originally.
+func umask(new int) func() {
+ old := syscall.Umask(new)
+ return func() {
+ syscall.Umask(old)
+ }
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/osfs/os_windows.go b/vendor/github.com/go-git/go-billy/v5/osfs/os_windows.go
new file mode 100644
index 00000000..e54df748
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/osfs/os_windows.go
@@ -0,0 +1,58 @@
+//go:build windows
+// +build windows
+
+package osfs
+
+import (
+ "os"
+ "runtime"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var (
+ kernel32DLL = windows.NewLazySystemDLL("kernel32.dll")
+ lockFileExProc = kernel32DLL.NewProc("LockFileEx")
+ unlockFileProc = kernel32DLL.NewProc("UnlockFile")
+)
+
+const (
+ lockfileExclusiveLock = 0x2
+)
+
+func (f *file) Lock() error {
+ f.m.Lock()
+ defer f.m.Unlock()
+
+ var overlapped windows.Overlapped
+ // err is always non-nil as per sys/windows semantics.
+ ret, _, err := lockFileExProc.Call(f.File.Fd(), lockfileExclusiveLock, 0, 0xFFFFFFFF, 0,
+ uintptr(unsafe.Pointer(&overlapped)))
+ runtime.KeepAlive(&overlapped)
+ if ret == 0 {
+ return err
+ }
+ return nil
+}
+
+func (f *file) Unlock() error {
+ f.m.Lock()
+ defer f.m.Unlock()
+
+ // err is always non-nil as per sys/windows semantics.
+ ret, _, err := unlockFileProc.Call(f.File.Fd(), 0, 0, 0xFFFFFFFF, 0)
+ if ret == 0 {
+ return err
+ }
+ return nil
+}
+
+func rename(from, to string) error {
+ return os.Rename(from, to)
+}
+
+func umask(new int) func() {
+ return func() {
+ }
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/util/glob.go b/vendor/github.com/go-git/go-billy/v5/util/glob.go
new file mode 100644
index 00000000..f7cb1de8
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/util/glob.go
@@ -0,0 +1,111 @@
+package util
+
+import (
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+// Glob returns the names of all files matching pattern or nil
+// if there is no matching file. The syntax of patterns is the same
+// as in Match. The pattern may describe hierarchical names such as
+// /usr/*/bin/ed (assuming the Separator is '/').
+//
+// Glob ignores file system errors such as I/O errors reading directories.
+// The only possible returned error is ErrBadPattern, when pattern
+// is malformed.
+//
+// Function originally from https://golang.org/src/path/filepath/match_test.go
+func Glob(fs billy.Filesystem, pattern string) (matches []string, err error) {
+ if !hasMeta(pattern) {
+ if _, err = fs.Lstat(pattern); err != nil {
+ return nil, nil
+ }
+ return []string{pattern}, nil
+ }
+
+ dir, file := filepath.Split(pattern)
+ // Prevent infinite recursion. See issue 15879.
+ if dir == pattern {
+ return nil, filepath.ErrBadPattern
+ }
+
+ var m []string
+ m, err = Glob(fs, cleanGlobPath(dir))
+ if err != nil {
+ return
+ }
+ for _, d := range m {
+ matches, err = glob(fs, d, file, matches)
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+// cleanGlobPath prepares path for glob matching.
+func cleanGlobPath(path string) string {
+ switch path {
+ case "":
+ return "."
+ case string(filepath.Separator):
+ // do nothing to the path
+ return path
+ default:
+ return path[0 : len(path)-1] // chop off trailing separator
+ }
+}
+
+// glob searches for files matching pattern in the directory dir
+// and appends them to matches. If the directory cannot be
+// opened, it returns the existing matches. New matches are
+// added in lexicographical order.
+func glob(fs billy.Filesystem, dir, pattern string, matches []string) (m []string, e error) {
+ m = matches
+ fi, err := fs.Stat(dir)
+ if err != nil {
+ return
+ }
+
+ if !fi.IsDir() {
+ return
+ }
+
+ names, _ := readdirnames(fs, dir)
+ sort.Strings(names)
+
+ for _, n := range names {
+ matched, err := filepath.Match(pattern, n)
+ if err != nil {
+ return m, err
+ }
+ if matched {
+ m = append(m, filepath.Join(dir, n))
+ }
+ }
+ return
+}
+
+// hasMeta reports whether path contains any of the magic characters
+// recognized by Match.
+func hasMeta(path string) bool {
+ // TODO(niemeyer): Should other magic characters be added here?
+ return strings.ContainsAny(path, "*?[")
+}
+
+func readdirnames(fs billy.Filesystem, dir string) ([]string, error) {
+ files, err := fs.ReadDir(dir)
+ if err != nil {
+ return nil, err
+ }
+
+ var names []string
+ for _, file := range files {
+ names = append(names, file.Name())
+ }
+
+ return names, nil
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/util/util.go b/vendor/github.com/go-git/go-billy/v5/util/util.go
new file mode 100644
index 00000000..5c77128c
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/util/util.go
@@ -0,0 +1,282 @@
+package util
+
+import (
+ "io"
+ "os"
+ "path/filepath"
+ "strconv"
+ "sync"
+ "time"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+// RemoveAll removes path and any children it contains. It removes everything it
+// can but returns the first error it encounters. If the path does not exist,
+// RemoveAll returns nil (no error).
+func RemoveAll(fs billy.Basic, path string) error {
+ fs, path = getUnderlyingAndPath(fs, path)
+
+ if r, ok := fs.(removerAll); ok {
+ return r.RemoveAll(path)
+ }
+
+ return removeAll(fs, path)
+}
+
+type removerAll interface {
+ RemoveAll(string) error
+}
+
+func removeAll(fs billy.Basic, path string) error {
+ // This implementation is adapted from os.RemoveAll.
+
+ // Simple case: if Remove works, we're done.
+ err := fs.Remove(path)
+ if err == nil || os.IsNotExist(err) {
+ return nil
+ }
+
+ // Otherwise, is this a directory we need to recurse into?
+ dir, serr := fs.Stat(path)
+ if serr != nil {
+ if os.IsNotExist(serr) {
+ return nil
+ }
+
+ return serr
+ }
+
+ if !dir.IsDir() {
+ // Not a directory; return the error from Remove.
+ return err
+ }
+
+ dirfs, ok := fs.(billy.Dir)
+ if !ok {
+ return billy.ErrNotSupported
+ }
+
+ // Directory.
+ fis, err := dirfs.ReadDir(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // Race. It was deleted between the Lstat and Open.
+ // Return nil per RemoveAll's docs.
+ return nil
+ }
+
+ return err
+ }
+
+ // Remove contents & return first error.
+ err = nil
+ for _, fi := range fis {
+ cpath := fs.Join(path, fi.Name())
+ err1 := removeAll(fs, cpath)
+ if err == nil {
+ err = err1
+ }
+ }
+
+ // Remove directory.
+ err1 := fs.Remove(path)
+ if err1 == nil || os.IsNotExist(err1) {
+ return nil
+ }
+
+ if err == nil {
+ err = err1
+ }
+
+ return err
+
+}
+
+// WriteFile writes data to a file named by filename in the given filesystem.
+// If the file does not exist, WriteFile creates it with permissions perm;
+// otherwise WriteFile truncates it before writing.
+func WriteFile(fs billy.Basic, filename string, data []byte, perm os.FileMode) error {
+ f, err := fs.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
+ if err != nil {
+ return err
+ }
+
+ n, err := f.Write(data)
+ if err == nil && n < len(data) {
+ err = io.ErrShortWrite
+ }
+
+ if err1 := f.Close(); err == nil {
+ err = err1
+ }
+
+ return err
+}
+
+// Random number state.
+// We generate random temporary file names so that there's a good
+// chance the file doesn't exist yet - keeps the number of tries in
+// TempFile to a minimum.
+var rand uint32
+var randmu sync.Mutex
+
+func reseed() uint32 {
+ return uint32(time.Now().UnixNano() + int64(os.Getpid()))
+}
+
+func nextSuffix() string {
+ randmu.Lock()
+ r := rand
+ if r == 0 {
+ r = reseed()
+ }
+ r = r*1664525 + 1013904223 // constants from Numerical Recipes
+ rand = r
+ randmu.Unlock()
+ return strconv.Itoa(int(1e9 + r%1e9))[1:]
+}
+
+// TempFile creates a new temporary file in the directory dir with a name
+// beginning with prefix, opens the file for reading and writing, and returns
+// the resulting *os.File. If dir is the empty string, TempFile uses the default
+// directory for temporary files (see os.TempDir). Multiple programs calling
+// TempFile simultaneously will not choose the same file. The caller can use
+// f.Name() to find the pathname of the file. It is the caller's responsibility
+// to remove the file when no longer needed.
+func TempFile(fs billy.Basic, dir, prefix string) (f billy.File, err error) {
+ // This implementation is based on stdlib ioutil.TempFile.
+ if dir == "" {
+ dir = getTempDir(fs)
+ }
+
+ nconflict := 0
+ for i := 0; i < 10000; i++ {
+ name := filepath.Join(dir, prefix+nextSuffix())
+ f, err = fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
+ if os.IsExist(err) {
+ if nconflict++; nconflict > 10 {
+ randmu.Lock()
+ rand = reseed()
+ randmu.Unlock()
+ }
+ continue
+ }
+ break
+ }
+ return
+}
+
+// TempDir creates a new temporary directory in the directory dir
+// with a name beginning with prefix and returns the path of the
+// new directory. If dir is the empty string, TempDir uses the
+// default directory for temporary files (see os.TempDir).
+// Multiple programs calling TempDir simultaneously
+// will not choose the same directory. It is the caller's responsibility
+// to remove the directory when no longer needed.
+func TempDir(fs billy.Dir, dir, prefix string) (name string, err error) {
+ // This implementation is based on stdlib ioutil.TempDir
+
+ if dir == "" {
+ dir = getTempDir(fs.(billy.Basic))
+ }
+
+ nconflict := 0
+ for i := 0; i < 10000; i++ {
+ try := filepath.Join(dir, prefix+nextSuffix())
+ err = fs.MkdirAll(try, 0700)
+ if os.IsExist(err) {
+ if nconflict++; nconflict > 10 {
+ randmu.Lock()
+ rand = reseed()
+ randmu.Unlock()
+ }
+ continue
+ }
+ if os.IsNotExist(err) {
+ if _, err := os.Stat(dir); os.IsNotExist(err) {
+ return "", err
+ }
+ }
+ if err == nil {
+ name = try
+ }
+ break
+ }
+ return
+}
+
+func getTempDir(fs billy.Basic) string {
+ ch, ok := fs.(billy.Chroot)
+ if !ok || ch.Root() == "" || ch.Root() == "/" || ch.Root() == string(filepath.Separator) {
+ return os.TempDir()
+ }
+
+ return ".tmp"
+}
+
+type underlying interface {
+ Underlying() billy.Basic
+}
+
+func getUnderlyingAndPath(fs billy.Basic, path string) (billy.Basic, string) {
+ u, ok := fs.(underlying)
+ if !ok {
+ return fs, path
+ }
+ if ch, ok := fs.(billy.Chroot); ok {
+ path = fs.Join(ch.Root(), path)
+ }
+
+ return u.Underlying(), path
+}
+
+// ReadFile reads the named file and returns the contents from the given filesystem.
+// A successful call returns err == nil, not err == EOF.
+// Because ReadFile reads the whole file, it does not treat an EOF from Read
+// as an error to be reported.
+func ReadFile(fs billy.Basic, name string) ([]byte, error) {
+ f, err := fs.Open(name)
+ if err != nil {
+ return nil, err
+ }
+
+ defer f.Close()
+
+ var size int
+ if info, err := fs.Stat(name); err == nil {
+ size64 := info.Size()
+ if int64(int(size64)) == size64 {
+ size = int(size64)
+ }
+ }
+
+ size++ // one byte for final read at EOF
+ // If a file claims a small size, read at least 512 bytes.
+ // In particular, files in Linux's /proc claim size 0 but
+ // then do not work right if read in small pieces,
+ // so an initial read of 1 byte would not work correctly.
+
+ if size < 512 {
+ size = 512
+ }
+
+ data := make([]byte, 0, size)
+ for {
+ if len(data) >= cap(data) {
+ d := append(data[:cap(data)], 0)
+ data = d[:len(data)]
+ }
+
+ n, err := f.Read(data[len(data):cap(data)])
+ data = data[:len(data)+n]
+
+ if err != nil {
+ if err == io.EOF {
+ err = nil
+ }
+
+ return data, err
+ }
+ }
+}
diff --git a/vendor/github.com/go-git/go-billy/v5/util/walk.go b/vendor/github.com/go-git/go-billy/v5/util/walk.go
new file mode 100644
index 00000000..1531bcaa
--- /dev/null
+++ b/vendor/github.com/go-git/go-billy/v5/util/walk.go
@@ -0,0 +1,72 @@
+package util
+
+import (
+ "os"
+ "path/filepath"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+// walk recursively descends path, calling walkFn
+// adapted from https://golang.org/src/path/filepath/path.go
+func walk(fs billy.Filesystem, path string, info os.FileInfo, walkFn filepath.WalkFunc) error {
+ if !info.IsDir() {
+ return walkFn(path, info, nil)
+ }
+
+ names, err := readdirnames(fs, path)
+ err1 := walkFn(path, info, err)
+ // If err != nil, walk can't walk into this directory.
+ // err1 != nil means walkFn want walk to skip this directory or stop walking.
+ // Therefore, if one of err and err1 isn't nil, walk will return.
+ if err != nil || err1 != nil {
+ // The caller's behavior is controlled by the return value, which is decided
+ // by walkFn. walkFn may ignore err and return nil.
+ // If walkFn returns SkipDir, it will be handled by the caller.
+ // So walk should return whatever walkFn returns.
+ return err1
+ }
+
+ for _, name := range names {
+ filename := filepath.Join(path, name)
+ fileInfo, err := fs.Lstat(filename)
+ if err != nil {
+ if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
+ return err
+ }
+ } else {
+ err = walk(fs, filename, fileInfo, walkFn)
+ if err != nil {
+ if !fileInfo.IsDir() || err != filepath.SkipDir {
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// Walk walks the file tree rooted at root, calling fn for each file or
+// directory in the tree, including root. All errors that arise visiting files
+// and directories are filtered by fn: see the WalkFunc documentation for
+// details.
+//
+// The files are walked in lexical order, which makes the output deterministic
+// but requires Walk to read an entire directory into memory before proceeding
+// to walk that directory. Walk does not follow symbolic links.
+//
+// Function adapted from https://github.com/golang/go/blob/3b770f2ccb1fa6fecc22ea822a19447b10b70c5c/src/path/filepath/path.go#L500
+func Walk(fs billy.Filesystem, root string, walkFn filepath.WalkFunc) error {
+ info, err := fs.Lstat(root)
+ if err != nil {
+ err = walkFn(root, nil, err)
+ } else {
+ err = walk(fs, root, info, walkFn)
+ }
+
+ if err == filepath.SkipDir {
+ return nil
+ }
+
+ return err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/.gitignore b/vendor/github.com/go-git/go-git/v5/.gitignore
new file mode 100644
index 00000000..b7f2c580
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/.gitignore
@@ -0,0 +1,7 @@
+coverage.out
+*~
+coverage.txt
+profile.out
+.tmp/
+.git-dist/
+.vscode
diff --git a/vendor/github.com/go-git/go-git/v5/CODE_OF_CONDUCT.md b/vendor/github.com/go-git/go-git/v5/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..a689fa3c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/CODE_OF_CONDUCT.md
@@ -0,0 +1,74 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of experience,
+education, socio-economic status, nationality, personal appearance, race,
+religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at conduct@sourced.tech. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
diff --git a/vendor/github.com/go-git/go-git/v5/COMPATIBILITY.md b/vendor/github.com/go-git/go-git/v5/COMPATIBILITY.md
new file mode 100644
index 00000000..ff0c22c8
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/COMPATIBILITY.md
@@ -0,0 +1,233 @@
+# Supported Features
+
+Here is a non-comprehensive table of git commands and features and their
+compatibility status with go-git.
+
+## Getting and creating repositories
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| ------- | ------------------------------------------------------------------------------------------------------------------ | ------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `init` | | ✅ | | |
+| `init` | `--bare` | ✅ | | |
+| `init` | `--template`
`--separate-git-dir`
`--shared` | ❌ | | |
+| `clone` | | ✅ | | - [PlainClone](_examples/clone/main.go) |
+| `clone` | Authentication:
- none
- access token
- username + password
- ssh | ✅ | | - [clone ssh](_examples/clone/auth/ssh/main.go)
- [clone access token](_examples/clone/auth/basic/access_token/main.go)
- [clone user + password](_examples/clone/auth/basic/username_password/main.go) |
+| `clone` | `--progress`
`--single-branch`
`--depth`
`--origin`
`--recurse-submodules`
`--shared` | ✅ | | - [recurse submodules](_examples/clone/main.go)
- [progress](_examples/progress/main.go) |
+
+## Basic snapshotting
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| -------- | ----------- | ------ | -------------------------------------------------------- | ------------------------------------ |
+| `add` | | ✅ | Plain add is supported. Any other flags aren't supported | |
+| `status` | | ✅ | | |
+| `commit` | | ✅ | | - [commit](_examples/commit/main.go) |
+| `reset` | | ✅ | | |
+| `rm` | | ✅ | | |
+| `mv` | | ✅ | | |
+
+## Branching and merging
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| ----------- | ----------- | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------- |
+| `branch` | | ✅ | | - [branch](_examples/branch/main.go) |
+| `checkout` | | ✅ | Basic usages of checkout are supported. | - [checkout](_examples/checkout/main.go) |
+| `merge` | | ⚠️ (partial) | Fast-forward only | |
+| `mergetool` | | ❌ | | |
+| `stash` | | ❌ | | |
+| `tag` | | ✅ | | - [tag](_examples/tag/main.go)
- [tag create and push](_examples/tag-create-push/main.go) |
+
+## Sharing and updating projects
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| ----------- | ----------- | ------ | ----------------------------------------------------------------------- | ------------------------------------------ |
+| `fetch` | | ✅ | | |
+| `pull` | | ✅ | Only supports merges where the merge can be resolved as a fast-forward. | - [pull](_examples/pull/main.go) |
+| `push` | | ✅ | | - [push](_examples/push/main.go) |
+| `remote` | | ✅ | | - [remotes](_examples/remotes/main.go) |
+| `submodule` | | ✅ | | - [submodule](_examples/submodule/main.go) |
+| `submodule` | deinit | ❌ | | |
+
+## Inspection and comparison
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| ---------- | ----------- | --------- | ----- | ------------------------------ |
+| `show` | | ✅ | | |
+| `log` | | ✅ | | - [log](_examples/log/main.go) |
+| `shortlog` | | (see log) | | |
+| `describe` | | ❌ | | |
+
+## Patching
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| ------------- | ----------- | ------ | ---------------------------------------------------- | -------- |
+| `apply` | | ❌ | | |
+| `cherry-pick` | | ❌ | | |
+| `diff` | | ✅ | Patch object with UnifiedDiff output representation. | |
+| `rebase` | | ❌ | | |
+| `revert` | | ❌ | | |
+
+## Debugging
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| -------- | ----------- | ------ | ----- | ---------------------------------- |
+| `bisect` | | ❌ | | |
+| `blame` | | ✅ | | - [blame](_examples/blame/main.go) |
+| `grep` | | ✅ | | |
+
+## Email
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| -------------- | ----------- | ------ | ----- | -------- |
+| `am` | | ❌ | | |
+| `apply` | | ❌ | | |
+| `format-patch` | | ❌ | | |
+| `send-email` | | ❌ | | |
+| `request-pull` | | ❌ | | |
+
+## External systems
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| ------------- | ----------- | ------ | ----- | -------- |
+| `svn` | | ❌ | | |
+| `fast-import` | | ❌ | | |
+| `lfs` | | ❌ | | |
+
+## Administration
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| --------------- | ----------- | ------ | ----- | -------- |
+| `clean` | | ✅ | | |
+| `gc` | | ❌ | | |
+| `fsck` | | ❌ | | |
+| `reflog` | | ❌ | | |
+| `filter-branch` | | ❌ | | |
+| `instaweb` | | ❌ | | |
+| `archive` | | ❌ | | |
+| `bundle` | | ❌ | | |
+| `prune` | | ❌ | | |
+| `repack` | | ❌ | | |
+
+## Server admin
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| -------------------- | ----------- | ------ | ----- | ----------------------------------------- |
+| `daemon` | | ❌ | | |
+| `update-server-info` | | ✅ | | [cli](./cli/go-git/update_server_info.go) |
+
+## Advanced
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| ---------- | ----------- | ----------- | ----- | -------- |
+| `notes` | | ❌ | | |
+| `replace` | | ❌ | | |
+| `worktree` | | ❌ | | |
+| `annotate` | | (see blame) | | |
+
+## GPG
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| ------------------- | ----------- | ------ | ----- | -------- |
+| `git-verify-commit` | | ✅ | | |
+| `git-verify-tag` | | ✅ | | |
+
+## Plumbing commands
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| --------------- | ------------------------------------- | ------------ | --------------------------------------------------- | -------------------------------------------- |
+| `cat-file` | | ✅ | | |
+| `check-ignore` | | ❌ | | |
+| `commit-tree` | | ❌ | | |
+| `count-objects` | | ❌ | | |
+| `diff-index` | | ❌ | | |
+| `for-each-ref` | | ✅ | | |
+| `hash-object` | | ✅ | | |
+| `ls-files` | | ✅ | | |
+| `ls-remote` | | ✅ | | - [ls-remote](_examples/ls-remote/main.go) |
+| `merge-base` | `--independent`
`--is-ancestor` | ⚠️ (partial) | Calculates the merge-base only between two commits. | - [merge-base](_examples/merge_base/main.go) |
+| `merge-base` | `--fork-point`
`--octopus` | ❌ | | |
+| `read-tree` | | ❌ | | |
+| `rev-list` | | ✅ | | |
+| `rev-parse` | | ❌ | | |
+| `show-ref` | | ✅ | | |
+| `symbolic-ref` | | ✅ | | |
+| `update-index` | | ❌ | | |
+| `update-ref` | | ❌ | | |
+| `verify-pack` | | ❌ | | |
+| `write-tree` | | ❌ | | |
+
+## Indexes and Git Protocols
+
+| Feature | Version | Status | Notes |
+| -------------------- | ------------------------------------------------------------------------------- | ------ | ----- |
+| index | [v1](https://github.com/git/git/blob/master/Documentation/gitformat-index.txt) | ❌ | |
+| index | [v2](https://github.com/git/git/blob/master/Documentation/gitformat-index.txt) | ✅ | |
+| index | [v3](https://github.com/git/git/blob/master/Documentation/gitformat-index.txt) | ❌ | |
+| pack-protocol | [v1](https://github.com/git/git/blob/master/Documentation/gitprotocol-pack.txt) | ✅ | |
+| pack-protocol | [v2](https://github.com/git/git/blob/master/Documentation/gitprotocol-v2.txt) | ❌ | |
+| multi-pack-index | [v1](https://github.com/git/git/blob/master/Documentation/gitformat-pack.txt) | ❌ | |
+| pack-\*.rev files | [v1](https://github.com/git/git/blob/master/Documentation/gitformat-pack.txt) | ❌ | |
+| pack-\*.mtimes files | [v1](https://github.com/git/git/blob/master/Documentation/gitformat-pack.txt) | ❌ | |
+| cruft packs | | ❌ | |
+
+## Capabilities
+
+| Feature | Status | Notes |
+| ------------------------------ | ------------ | ----- |
+| `multi_ack` | ❌ | |
+| `multi_ack_detailed` | ❌ | |
+| `no-done` | ❌ | |
+| `thin-pack` | ❌ | |
+| `side-band` | ⚠️ (partial) | |
+| `side-band-64k` | ⚠️ (partial) | |
+| `ofs-delta` | ✅ | |
+| `agent` | ✅ | |
+| `object-format` | ❌ | |
+| `symref` | ✅ | |
+| `shallow` | ✅ | |
+| `deepen-since` | ✅ | |
+| `deepen-not` | ❌ | |
+| `deepen-relative` | ❌ | |
+| `no-progress` | ✅ | |
+| `include-tag` | ✅ | |
+| `report-status` | ✅ | |
+| `report-status-v2` | ❌ | |
+| `delete-refs` | ✅ | |
+| `quiet` | ❌ | |
+| `atomic` | ✅ | |
+| `push-options` | ✅ | |
+| `allow-tip-sha1-in-want` | ✅ | |
+| `allow-reachable-sha1-in-want` | ❌ | |
+| `push-cert=` | ❌ | |
+| `filter` | ❌ | |
+| `session-id=` | ❌ | |
+
+## Transport Schemes
+
+| Scheme | Status | Notes | Examples |
+| -------------------- | ------------ | ---------------------------------------------------------------------- | ---------------------------------------------- |
+| `http(s)://` (dumb) | ❌ | | |
+| `http(s)://` (smart) | ✅ | | |
+| `git://` | ✅ | | |
+| `ssh://` | ✅ | | |
+| `file://` | ⚠️ (partial) | Warning: this is not pure Golang. This shells out to the `git` binary. | |
+| Custom | ✅ | All existing schemes can be replaced by custom implementations. | - [custom_http](_examples/custom_http/main.go) |
+
+## SHA256
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| -------- | ----------- | ------ | ---------------------------------- | ------------------------------------ |
+| `init` | | ✅ | Requires building with tag sha256. | - [init](_examples/sha256/main.go) |
+| `commit` | | ✅ | Requires building with tag sha256. | - [commit](_examples/sha256/main.go) |
+| `pull` | | ❌ | | |
+| `fetch` | | ❌ | | |
+| `push` | | ❌ | | |
+
+## Other features
+
+| Feature | Sub-feature | Status | Notes | Examples |
+| --------------- | --------------------------- | ------ | ---------------------------------------------- | -------- |
+| `config` | `--local` | ✅ | Read and write per-repository (`.git/config`). | |
+| `config` | `--global`
`--system` | ✅ | Read-only. | |
+| `gitignore` | | ✅ | | |
+| `gitattributes` | | ✅ | | |
+| `git-worktree` | | ❌ | Multiple worktrees are not supported. | |
diff --git a/vendor/github.com/go-git/go-git/v5/CONTRIBUTING.md b/vendor/github.com/go-git/go-git/v5/CONTRIBUTING.md
new file mode 100644
index 00000000..fce25328
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/CONTRIBUTING.md
@@ -0,0 +1,46 @@
+# Contributing Guidelines
+
+source{d} go-git project is [Apache 2.0 licensed](LICENSE) and accepts
+contributions via GitHub pull requests. This document outlines some of the
+conventions on development workflow, commit message formatting, contact points,
+and other resources to make it easier to get your contribution accepted.
+
+## Support Channels
+
+The official support channels, for both users and contributors, are:
+
+- [StackOverflow go-git tag](https://stackoverflow.com/questions/tagged/go-git) for user questions.
+- GitHub [Issues](https://github.com/src-d/go-git/issues)* for bug reports and feature requests.
+
+*Before opening a new issue or submitting a new pull request, it's helpful to
+search the project - it's likely that another user has already reported the
+issue you're facing, or it's a known issue that we're already aware of.
+
+
+## How to Contribute
+
+Pull Requests (PRs) are the main and exclusive way to contribute to the official go-git project.
+In order for a PR to be accepted it needs to pass a list of requirements:
+
+- You should be able to run the same query using `git`. We don't accept features that are not implemented in the official git implementation.
+- The expected behavior must match the [official git implementation](https://github.com/git/git).
+- The actual behavior must be correctly explained with natural language and providing a minimum working example in Go that reproduces it.
+- All PRs must be written in idiomatic Go, formatted according to [gofmt](https://golang.org/cmd/gofmt/), and without any warnings from [go lint](https://github.com/golang/lint) nor [go vet](https://golang.org/cmd/vet/).
+- They should in general include tests, and those shall pass.
+- If the PR is a bug fix, it has to include a suite of unit tests for the new functionality.
+- If the PR is a new feature, it has to come with a suite of unit tests, that tests the new functionality.
+- In any case, all the PRs have to pass the personal evaluation of at least one of the maintainers of go-git.
+
+### Format of the commit message
+
+Every commit message should describe what was changed, under which context and, if applicable, the GitHub issue it relates to:
+
+```
+plumbing: packp, Skip argument validations for unknown capabilities. Fixes #623
+```
+
+The format can be described more formally as follows:
+
+```
+: , . [Fixes #]
+```
diff --git a/vendor/github.com/go-git/go-git/v5/EXTENDING.md b/vendor/github.com/go-git/go-git/v5/EXTENDING.md
new file mode 100644
index 00000000..a2778e34
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/EXTENDING.md
@@ -0,0 +1,78 @@
+# Extending go-git
+
+`go-git` was built in a highly extensible manner, which enables some of its functionalities to be changed or extended without the need of changing its codebase. Here are the key extensibility features:
+
+## Dot Git Storers
+
+Dot git storers are the components responsible for storing the Git internal files, including objects and references.
+
+The built-in storer implementations include [memory](storage/memory) and [filesystem](storage/filesystem). The `memory` storer stores all the data in memory, and its use look like this:
+
+```go
+ r, err := git.Init(memory.NewStorage(), nil)
+```
+
+The `filesystem` storer stores the data in the OS filesystem, and can be used as follows:
+
+```go
+ r, err := git.Init(filesystem.NewStorage(osfs.New("/tmp/foo")), nil)
+```
+
+New implementations can be created by implementing the [storage.Storer interface](storage/storer.go#L16).
+
+## Filesystem
+
+Git repository worktrees are managed using a filesystem abstraction based on [go-billy](https://github.com/go-git/go-billy). The Git operations will take place against the specific filesystem implementation. Initialising a repository in Memory can be done as follows:
+
+```go
+ fs := memfs.New()
+ r, err := git.Init(memory.NewStorage(), fs)
+```
+
+The same operation can be done against the OS filesystem:
+
+```go
+ fs := osfs.New("/tmp/foo")
+ r, err := git.Init(memory.NewStorage(), fs)
+```
+
+New filesystems (e.g. cloud based storage) could be created by implementing `go-billy`'s [Filesystem interface](https://github.com/go-git/go-billy/blob/326c59f064021b821a55371d57794fbfb86d4cb3/fs.go#L52).
+
+## Transport Schemes
+
+Git supports various transport schemes, including `http`, `https`, `ssh`, `git`, `file`. `go-git` defines the [transport.Transport interface](plumbing/transport/common.go#L48) to represent them.
+
+The built-in implementations can be replaced by calling `client.InstallProtocol`.
+
+An example of changing the built-in `https` implementation to skip TLS could look like this:
+
+```go
+ customClient := &http.Client{
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ },
+ }
+
+ client.InstallProtocol("https", githttp.NewClient(customClient))
+```
+
+Some internal implementations enables code reuse amongst the different transport implementations. Some of these may be made public in the future (e.g. `plumbing/transport/internal/common`).
+
+## Cache
+
+Several different operations across `go-git` lean on caching of objects in order to achieve optimal performance. The caching functionality is defined by the [cache.Object interface](plumbing/cache/common.go#L17).
+
+Two built-in implementations are `cache.ObjectLRU` and `cache.BufferLRU`. However, the caching functionality can be customized by implementing the interface `cache.Object` interface.
+
+## Hash
+
+`go-git` uses the `crypto.Hash` interface to represent hash functions. The built-in implementations are `github.com/pjbgf/sha1cd` for SHA1 and Go's `crypto/SHA256`.
+
+The default hash functions can be changed by calling `hash.RegisterHash`.
+```go
+ func init() {
+ hash.RegisterHash(crypto.SHA1, sha1.New)
+ }
+```
+
+New `SHA1` or `SHA256` hash functions that implement the `hash.RegisterHash` interface can be registered by calling `RegisterHash`.
diff --git a/vendor/github.com/go-git/go-git/v5/LICENSE b/vendor/github.com/go-git/go-git/v5/LICENSE
new file mode 100644
index 00000000..8aa3d854
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ 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 "{}"
+ 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
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2018 Sourced Technologies, S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/go-git/go-git/v5/Makefile b/vendor/github.com/go-git/go-git/v5/Makefile
new file mode 100644
index 00000000..3d5b54f7
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/Makefile
@@ -0,0 +1,54 @@
+# General
+WORKDIR = $(PWD)
+
+# Go parameters
+GOCMD = go
+GOTEST = $(GOCMD) test
+
+# Git config
+GIT_VERSION ?=
+GIT_DIST_PATH ?= $(PWD)/.git-dist
+GIT_REPOSITORY = http://github.com/git/git.git
+
+# Coverage
+COVERAGE_REPORT = coverage.out
+COVERAGE_MODE = count
+
+build-git:
+ @if [ -f $(GIT_DIST_PATH)/git ]; then \
+ echo "nothing to do, using cache $(GIT_DIST_PATH)"; \
+ else \
+ git clone $(GIT_REPOSITORY) -b $(GIT_VERSION) --depth 1 --single-branch $(GIT_DIST_PATH); \
+ cd $(GIT_DIST_PATH); \
+ make configure; \
+ ./configure; \
+ make all; \
+ fi
+
+test:
+ @echo "running against `git version`"; \
+ $(GOTEST) -race ./...
+ $(GOTEST) -v _examples/common_test.go _examples/common.go --examples
+
+TEMP_REPO := $(shell mktemp)
+test-sha256:
+ $(GOCMD) run -tags sha256 _examples/sha256/main.go $(TEMP_REPO)
+ cd $(TEMP_REPO) && git fsck
+ rm -rf $(TEMP_REPO)
+
+test-coverage:
+ @echo "running against `git version`"; \
+ echo "" > $(COVERAGE_REPORT); \
+ $(GOTEST) -coverprofile=$(COVERAGE_REPORT) -coverpkg=./... -covermode=$(COVERAGE_MODE) ./...
+
+clean:
+ rm -rf $(GIT_DIST_PATH)
+
+fuzz:
+ @go test -fuzz=FuzzParser $(PWD)/internal/revision
+ @go test -fuzz=FuzzDecoder $(PWD)/plumbing/format/config
+ @go test -fuzz=FuzzPatchDelta $(PWD)/plumbing/format/packfile
+ @go test -fuzz=FuzzParseSignedBytes $(PWD)/plumbing/object
+ @go test -fuzz=FuzzDecode $(PWD)/plumbing/object
+ @go test -fuzz=FuzzDecoder $(PWD)/plumbing/protocol/packp
+ @go test -fuzz=FuzzNewEndpoint $(PWD)/plumbing/transport
diff --git a/vendor/github.com/go-git/go-git/v5/README.md b/vendor/github.com/go-git/go-git/v5/README.md
new file mode 100644
index 00000000..ff0c9b72
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/README.md
@@ -0,0 +1,131 @@
+![go-git logo](https://cdn.rawgit.com/src-d/artwork/02036484/go-git/files/go-git-github-readme-header.png)
+[![GoDoc](https://godoc.org/github.com/go-git/go-git/v5?status.svg)](https://pkg.go.dev/github.com/go-git/go-git/v5) [![Build Status](https://github.com/go-git/go-git/workflows/Test/badge.svg)](https://github.com/go-git/go-git/actions) [![Go Report Card](https://goreportcard.com/badge/github.com/go-git/go-git)](https://goreportcard.com/report/github.com/go-git/go-git)
+
+*go-git* is a highly extensible git implementation library written in **pure Go**.
+
+It can be used to manipulate git repositories at low level *(plumbing)* or high level *(porcelain)*, through an idiomatic Go API. It also supports several types of storage, such as in-memory filesystems, or custom implementations, thanks to the [`Storer`](https://pkg.go.dev/github.com/go-git/go-git/v5/plumbing/storer) interface.
+
+It's being actively developed since 2015 and is being used extensively by [Keybase](https://keybase.io/blog/encrypted-git-for-everyone), [Gitea](https://gitea.io/en-us/) or [Pulumi](https://github.com/search?q=org%3Apulumi+go-git&type=Code), and by many other libraries and tools.
+
+Project Status
+--------------
+
+After the legal issues with the [`src-d`](https://github.com/src-d) organization, the lack of update for four months and the requirement to make a hard fork, the project is **now back to normality**.
+
+The project is currently actively maintained by individual contributors, including several of the original authors, but also backed by a new company, [gitsight](https://github.com/gitsight), where `go-git` is a critical component used at scale.
+
+
+Comparison with git
+-------------------
+
+*go-git* aims to be fully compatible with [git](https://github.com/git/git), all the *porcelain* operations are implemented to work exactly as *git* does.
+
+*git* is a humongous project with years of development by thousands of contributors, making it challenging for *go-git* to implement all the features. You can find a comparison of *go-git* vs *git* in the [compatibility documentation](COMPATIBILITY.md).
+
+
+Installation
+------------
+
+The recommended way to install *go-git* is:
+
+```go
+import "github.com/go-git/go-git/v5" // with go modules enabled (GO111MODULE=on or outside GOPATH)
+import "github.com/go-git/go-git" // with go modules disabled
+```
+
+
+Examples
+--------
+
+> Please note that the `CheckIfError` and `Info` functions used in the examples are from the [examples package](https://github.com/go-git/go-git/blob/master/_examples/common.go#L19) just to be used in the examples.
+
+
+### Basic example
+
+A basic example that mimics the standard `git clone` command
+
+```go
+// Clone the given repository to the given directory
+Info("git clone https://github.com/go-git/go-git")
+
+_, err := git.PlainClone("/tmp/foo", false, &git.CloneOptions{
+ URL: "https://github.com/go-git/go-git",
+ Progress: os.Stdout,
+})
+
+CheckIfError(err)
+```
+
+Outputs:
+```
+Counting objects: 4924, done.
+Compressing objects: 100% (1333/1333), done.
+Total 4924 (delta 530), reused 6 (delta 6), pack-reused 3533
+```
+
+### In-memory example
+
+Cloning a repository into memory and printing the history of HEAD, just like `git log` does
+
+
+```go
+// Clones the given repository in memory, creating the remote, the local
+// branches and fetching the objects, exactly as:
+Info("git clone https://github.com/go-git/go-billy")
+
+r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
+ URL: "https://github.com/go-git/go-billy",
+})
+
+CheckIfError(err)
+
+// Gets the HEAD history from HEAD, just like this command:
+Info("git log")
+
+// ... retrieves the branch pointed by HEAD
+ref, err := r.Head()
+CheckIfError(err)
+
+
+// ... retrieves the commit history
+cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
+CheckIfError(err)
+
+// ... just iterates over the commits, printing it
+err = cIter.ForEach(func(c *object.Commit) error {
+ fmt.Println(c)
+ return nil
+})
+CheckIfError(err)
+```
+
+Outputs:
+```
+commit ded8054fd0c3994453e9c8aacaf48d118d42991e
+Author: Santiago M. Mola
+Date: Sat Nov 12 21:18:41 2016 +0100
+
+ index: ReadFrom/WriteTo returns IndexReadError/IndexWriteError. (#9)
+
+commit df707095626f384ce2dc1a83b30f9a21d69b9dfc
+Author: Santiago M. Mola
+Date: Fri Nov 11 13:23:22 2016 +0100
+
+ readwriter: fix bug when writing index. (#10)
+
+ When using ReadWriter on an existing siva file, absolute offset for
+ index entries was not being calculated correctly.
+...
+```
+
+You can find this [example](_examples/log/main.go) and many others in the [examples](_examples) folder.
+
+Contribute
+----------
+
+[Contributions](https://github.com/go-git/go-git/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) are more than welcome, if you are interested please take a look to
+our [Contributing Guidelines](CONTRIBUTING.md).
+
+License
+-------
+Apache License Version 2.0, see [LICENSE](LICENSE)
diff --git a/vendor/github.com/go-git/go-git/v5/SECURITY.md b/vendor/github.com/go-git/go-git/v5/SECURITY.md
new file mode 100644
index 00000000..0d2f8d03
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/SECURITY.md
@@ -0,0 +1,38 @@
+# go-git Security Policy
+
+The purpose of this security policy is to outline `go-git`'s process
+for reporting, handling and disclosing security sensitive information.
+
+## Supported Versions
+
+The project follows a version support policy where only the latest minor
+release is actively supported. Therefore, only issues that impact the latest
+minor release will be fixed. Users are encouraged to upgrade to the latest
+minor/patch release to benefit from the most up-to-date features, bug fixes,
+and security enhancements.
+
+The supported versions policy applies to both the `go-git` library and its
+associated repositories within the `go-git` org.
+
+## Reporting Security Issues
+
+Please report any security vulnerabilities or potential weaknesses in `go-git`
+privately via go-git-security@googlegroups.com. Do not publicly disclose the
+details of the vulnerability until a fix has been implemented and released.
+
+During the process the project maintainers will investigate the report, so please
+provide detailed information, including steps to reproduce, affected versions, and any mitigations if known.
+
+The project maintainers will acknowledge the receipt of the report and work with
+the reporter to validate and address the issue.
+
+Please note that `go-git` does not have any bounty programs, and therefore do
+not provide financial compensation for disclosures.
+
+## Security Disclosure Process
+
+The project maintainers will make every effort to promptly address security issues.
+
+Once a security vulnerability is fixed, a security advisory will be published to notify users and provide appropriate mitigation measures.
+
+All `go-git` advisories can be found at https://github.com/go-git/go-git/security/advisories.
diff --git a/vendor/github.com/go-git/go-git/v5/blame.go b/vendor/github.com/go-git/go-git/v5/blame.go
new file mode 100644
index 00000000..2a877dcd
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/blame.go
@@ -0,0 +1,590 @@
+package git
+
+import (
+ "bytes"
+ "container/heap"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+ "time"
+ "unicode/utf8"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/utils/diff"
+ "github.com/sergi/go-diff/diffmatchpatch"
+)
+
+// BlameResult represents the result of a Blame operation.
+type BlameResult struct {
+ // Path is the path of the File that we're blaming.
+ Path string
+ // Rev (Revision) is the hash of the specified Commit used to generate this result.
+ Rev plumbing.Hash
+ // Lines contains every line with its authorship.
+ Lines []*Line
+}
+
+// Blame returns a BlameResult with the information about the last author of
+// each line from file `path` at commit `c`.
+func Blame(c *object.Commit, path string) (*BlameResult, error) {
+ // The file to blame is identified by the input arguments:
+ // commit and path. commit is a Commit object obtained from a Repository. Path
+ // represents a path to a specific file contained in the repository.
+ //
+ // Blaming a file is done by walking the tree in reverse order trying to find where each line was last modified.
+ //
+ // When a diff is found it cannot immediately assume it came from that commit, as it may have come from 1 of its
+ // parents, so it will first try to resolve those diffs from its parents, if it couldn't find the change in its
+ // parents then it will assign the change to itself.
+ //
+ // When encountering 2 parents that have made the same change to a file it will choose the parent that was merged
+ // into the current branch first (this is determined by the order of the parents inside the commit).
+ //
+ // This currently works on a line by line basis, if performance becomes an issue it could be changed to work with
+ // hunks rather than lines. Then when encountering diff hunks it would need to split them where necessary.
+
+ b := new(blame)
+ b.fRev = c
+ b.path = path
+ b.q = new(priorityQueue)
+
+ file, err := b.fRev.File(path)
+ if err != nil {
+ return nil, err
+ }
+ finalLines, err := file.Lines()
+ if err != nil {
+ return nil, err
+ }
+ finalLength := len(finalLines)
+
+ needsMap := make([]lineMap, finalLength)
+ for i := range needsMap {
+ needsMap[i] = lineMap{i, i, nil, -1}
+ }
+ contents, err := file.Contents()
+ if err != nil {
+ return nil, err
+ }
+ b.q.Push(&queueItem{
+ nil,
+ nil,
+ c,
+ path,
+ contents,
+ needsMap,
+ 0,
+ false,
+ 0,
+ })
+ items := make([]*queueItem, 0)
+ for {
+ items = items[:0]
+ for {
+ if b.q.Len() == 0 {
+ return nil, errors.New("invalid state: no items left on the blame queue")
+ }
+ item := b.q.Pop()
+ items = append(items, item)
+ next := b.q.Peek()
+ if next == nil || next.Hash != item.Commit.Hash {
+ break
+ }
+ }
+ finished, err := b.addBlames(items)
+ if err != nil {
+ return nil, err
+ }
+ if finished == true {
+ break
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ b.lineToCommit = make([]*object.Commit, finalLength)
+ for i := range needsMap {
+ b.lineToCommit[i] = needsMap[i].Commit
+ }
+
+ lines, err := newLines(finalLines, b.lineToCommit)
+ if err != nil {
+ return nil, err
+ }
+
+ return &BlameResult{
+ Path: path,
+ Rev: c.Hash,
+ Lines: lines,
+ }, nil
+}
+
+// Line values represent the contents and author of a line in BlamedResult values.
+type Line struct {
+ // Author is the email address of the last author that modified the line.
+ Author string
+ // AuthorName is the name of the last author that modified the line.
+ AuthorName string
+ // Text is the original text of the line.
+ Text string
+ // Date is when the original text of the line was introduced
+ Date time.Time
+ // Hash is the commit hash that introduced the original line
+ Hash plumbing.Hash
+}
+
+func newLine(author, authorName, text string, date time.Time, hash plumbing.Hash) *Line {
+ return &Line{
+ Author: author,
+ AuthorName: authorName,
+ Text: text,
+ Hash: hash,
+ Date: date,
+ }
+}
+
+func newLines(contents []string, commits []*object.Commit) ([]*Line, error) {
+ result := make([]*Line, 0, len(contents))
+ for i := range contents {
+ result = append(result, newLine(
+ commits[i].Author.Email, commits[i].Author.Name, contents[i],
+ commits[i].Author.When, commits[i].Hash,
+ ))
+ }
+
+ return result, nil
+}
+
+// this struct is internally used by the blame function to hold its
+// inputs, outputs and state.
+type blame struct {
+ // the path of the file to blame
+ path string
+ // the commit of the final revision of the file to blame
+ fRev *object.Commit
+ // resolved lines
+ lineToCommit []*object.Commit
+ // queue of commits that need resolving
+ q *priorityQueue
+}
+
+type lineMap struct {
+ Orig, Cur int
+ Commit *object.Commit
+ FromParentNo int
+}
+
+func (b *blame) addBlames(curItems []*queueItem) (bool, error) {
+ curItem := curItems[0]
+
+ // Simple optimisation to merge paths, there is potential to go a bit further here and check for any duplicates
+ // not only if they are all the same.
+ if len(curItems) == 1 {
+ curItems = nil
+ } else if curItem.IdenticalToChild {
+ allSame := true
+ lenCurItems := len(curItems)
+ lowestParentNo := curItem.ParentNo
+ for i := 1; i < lenCurItems; i++ {
+ if !curItems[i].IdenticalToChild || curItem.Child != curItems[i].Child {
+ allSame = false
+ break
+ }
+ lowestParentNo = min(lowestParentNo, curItems[i].ParentNo)
+ }
+ if allSame {
+ curItem.Child.numParentsNeedResolving = curItem.Child.numParentsNeedResolving - lenCurItems + 1
+ curItems = nil // free the memory
+ curItem.ParentNo = lowestParentNo
+
+ // Now check if we can remove the parent completely
+ for curItem.Child.IdenticalToChild && curItem.Child.MergedChildren == nil && curItem.Child.numParentsNeedResolving == 1 {
+ oldChild := curItem.Child
+ curItem.Child = oldChild.Child
+ curItem.ParentNo = oldChild.ParentNo
+ }
+ }
+ }
+
+ // if we have more than 1 item for this commit, create a single needsMap
+ if len(curItems) > 1 {
+ curItem.MergedChildren = make([]childToNeedsMap, len(curItems))
+ for i, c := range curItems {
+ curItem.MergedChildren[i] = childToNeedsMap{c.Child, c.NeedsMap, c.IdenticalToChild, c.ParentNo}
+ }
+ newNeedsMap := make([]lineMap, 0, len(curItem.NeedsMap))
+ newNeedsMap = append(newNeedsMap, curItems[0].NeedsMap...)
+
+ for i := 1; i < len(curItems); i++ {
+ cur := curItems[i].NeedsMap
+ n := 0 // position in newNeedsMap
+ c := 0 // position in current list
+ for c < len(cur) {
+ if n == len(newNeedsMap) {
+ newNeedsMap = append(newNeedsMap, cur[c:]...)
+ break
+ } else if newNeedsMap[n].Cur == cur[c].Cur {
+ n++
+ c++
+ } else if newNeedsMap[n].Cur < cur[c].Cur {
+ n++
+ } else {
+ newNeedsMap = append(newNeedsMap, cur[c])
+ newPos := len(newNeedsMap) - 1
+ for newPos > n {
+ newNeedsMap[newPos-1], newNeedsMap[newPos] = newNeedsMap[newPos], newNeedsMap[newPos-1]
+ newPos--
+ }
+ }
+ }
+ }
+ curItem.NeedsMap = newNeedsMap
+ curItem.IdenticalToChild = false
+ curItem.Child = nil
+ curItems = nil // free the memory
+ }
+
+ parents, err := parentsContainingPath(curItem.path, curItem.Commit)
+ if err != nil {
+ return false, err
+ }
+
+ anyPushed := false
+ for parnetNo, prev := range parents {
+ currentHash, err := blobHash(curItem.path, curItem.Commit)
+ if err != nil {
+ return false, err
+ }
+ prevHash, err := blobHash(prev.Path, prev.Commit)
+ if err != nil {
+ return false, err
+ }
+ if currentHash == prevHash {
+ if len(parents) == 1 && curItem.MergedChildren == nil && curItem.IdenticalToChild {
+ // commit that has 1 parent and 1 child and is the same as both, bypass it completely
+ b.q.Push(&queueItem{
+ Child: curItem.Child,
+ Commit: prev.Commit,
+ path: prev.Path,
+ Contents: curItem.Contents,
+ NeedsMap: curItem.NeedsMap, // reuse the NeedsMap as we are throwing away this item
+ IdenticalToChild: true,
+ ParentNo: curItem.ParentNo,
+ })
+ } else {
+ b.q.Push(&queueItem{
+ Child: curItem,
+ Commit: prev.Commit,
+ path: prev.Path,
+ Contents: curItem.Contents,
+ NeedsMap: append([]lineMap(nil), curItem.NeedsMap...), // create new slice and copy
+ IdenticalToChild: true,
+ ParentNo: parnetNo,
+ })
+ curItem.numParentsNeedResolving++
+ }
+ anyPushed = true
+ continue
+ }
+
+ // get the contents of the file
+ file, err := prev.Commit.File(prev.Path)
+ if err != nil {
+ return false, err
+ }
+ prevContents, err := file.Contents()
+ if err != nil {
+ return false, err
+ }
+
+ hunks := diff.Do(prevContents, curItem.Contents)
+ prevl := -1
+ curl := -1
+ need := 0
+ getFromParent := make([]lineMap, 0)
+ out:
+ for h := range hunks {
+ hLines := countLines(hunks[h].Text)
+ for hl := 0; hl < hLines; hl++ {
+ switch {
+ case hunks[h].Type == diffmatchpatch.DiffEqual:
+ prevl++
+ curl++
+ if curl == curItem.NeedsMap[need].Cur {
+ // add to needs
+ getFromParent = append(getFromParent, lineMap{curl, prevl, nil, -1})
+ // move to next need
+ need++
+ if need >= len(curItem.NeedsMap) {
+ break out
+ }
+ }
+ case hunks[h].Type == diffmatchpatch.DiffInsert:
+ curl++
+ if curl == curItem.NeedsMap[need].Cur {
+ // the line we want is added, it may have been added here (or by another parent), skip it for now
+ need++
+ if need >= len(curItem.NeedsMap) {
+ break out
+ }
+ }
+ case hunks[h].Type == diffmatchpatch.DiffDelete:
+ prevl += hLines
+ continue out
+ default:
+ return false, errors.New("invalid state: invalid hunk Type")
+ }
+ }
+ }
+
+ if len(getFromParent) > 0 {
+ b.q.Push(&queueItem{
+ curItem,
+ nil,
+ prev.Commit,
+ prev.Path,
+ prevContents,
+ getFromParent,
+ 0,
+ false,
+ parnetNo,
+ })
+ curItem.numParentsNeedResolving++
+ anyPushed = true
+ }
+ }
+
+ curItem.Contents = "" // no longer need, free the memory
+
+ if !anyPushed {
+ return finishNeeds(curItem)
+ }
+
+ return false, nil
+}
+
+func finishNeeds(curItem *queueItem) (bool, error) {
+ // any needs left in the needsMap must have come from this revision
+ for i := range curItem.NeedsMap {
+ if curItem.NeedsMap[i].Commit == nil {
+ curItem.NeedsMap[i].Commit = curItem.Commit
+ curItem.NeedsMap[i].FromParentNo = -1
+ }
+ }
+
+ if curItem.Child == nil && curItem.MergedChildren == nil {
+ return true, nil
+ }
+
+ if curItem.MergedChildren == nil {
+ return applyNeeds(curItem.Child, curItem.NeedsMap, curItem.IdenticalToChild, curItem.ParentNo)
+ }
+
+ for _, ctn := range curItem.MergedChildren {
+ m := 0 // position in merged needs map
+ p := 0 // position in parent needs map
+ for p < len(ctn.NeedsMap) {
+ if ctn.NeedsMap[p].Cur == curItem.NeedsMap[m].Cur {
+ ctn.NeedsMap[p].Commit = curItem.NeedsMap[m].Commit
+ m++
+ p++
+ } else if ctn.NeedsMap[p].Cur < curItem.NeedsMap[m].Cur {
+ p++
+ } else {
+ m++
+ }
+ }
+ finished, err := applyNeeds(ctn.Child, ctn.NeedsMap, ctn.IdenticalToChild, ctn.ParentNo)
+ if finished || err != nil {
+ return finished, err
+ }
+ }
+
+ return false, nil
+}
+
+func applyNeeds(child *queueItem, needsMap []lineMap, identicalToChild bool, parentNo int) (bool, error) {
+ if identicalToChild {
+ for i := range child.NeedsMap {
+ l := &child.NeedsMap[i]
+ if l.Cur != needsMap[i].Cur || l.Orig != needsMap[i].Orig {
+ return false, errors.New("needsMap isn't the same? Why not??")
+ }
+ if l.Commit == nil || parentNo < l.FromParentNo {
+ l.Commit = needsMap[i].Commit
+ l.FromParentNo = parentNo
+ }
+ }
+ } else {
+ i := 0
+ out:
+ for j := range child.NeedsMap {
+ l := &child.NeedsMap[j]
+ for needsMap[i].Orig < l.Cur {
+ i++
+ if i == len(needsMap) {
+ break out
+ }
+ }
+ if l.Cur == needsMap[i].Orig {
+ if l.Commit == nil || parentNo < l.FromParentNo {
+ l.Commit = needsMap[i].Commit
+ l.FromParentNo = parentNo
+ }
+ }
+ }
+ }
+ child.numParentsNeedResolving--
+ if child.numParentsNeedResolving == 0 {
+ finished, err := finishNeeds(child)
+ if finished || err != nil {
+ return finished, err
+ }
+ }
+
+ return false, nil
+}
+
+// String prints the results of a Blame using git-blame's style.
+func (b BlameResult) String() string {
+ var buf bytes.Buffer
+
+ // max line number length
+ mlnl := len(strconv.Itoa(len(b.Lines)))
+ // max author length
+ mal := b.maxAuthorLength()
+ format := fmt.Sprintf("%%s (%%-%ds %%s %%%dd) %%s\n", mal, mlnl)
+
+ for ln := range b.Lines {
+ _, _ = fmt.Fprintf(&buf, format, b.Lines[ln].Hash.String()[:8],
+ b.Lines[ln].AuthorName, b.Lines[ln].Date.Format("2006-01-02 15:04:05 -0700"), ln+1, b.Lines[ln].Text)
+ }
+ return buf.String()
+}
+
+// utility function to calculate the number of runes needed
+// to print the longest author name in the blame of a file.
+func (b BlameResult) maxAuthorLength() int {
+ m := 0
+ for ln := range b.Lines {
+ m = max(m, utf8.RuneCountInString(b.Lines[ln].AuthorName))
+ }
+ return m
+}
+
+func min(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+
+type childToNeedsMap struct {
+ Child *queueItem
+ NeedsMap []lineMap
+ IdenticalToChild bool
+ ParentNo int
+}
+
+type queueItem struct {
+ Child *queueItem
+ MergedChildren []childToNeedsMap
+ Commit *object.Commit
+ path string
+ Contents string
+ NeedsMap []lineMap
+ numParentsNeedResolving int
+ IdenticalToChild bool
+ ParentNo int
+}
+
+type priorityQueueImp []*queueItem
+
+func (pq *priorityQueueImp) Len() int { return len(*pq) }
+func (pq *priorityQueueImp) Less(i, j int) bool {
+ return !(*pq)[i].Commit.Less((*pq)[j].Commit)
+}
+func (pq *priorityQueueImp) Swap(i, j int) { (*pq)[i], (*pq)[j] = (*pq)[j], (*pq)[i] }
+func (pq *priorityQueueImp) Push(x any) { *pq = append(*pq, x.(*queueItem)) }
+func (pq *priorityQueueImp) Pop() any {
+ n := len(*pq)
+ ret := (*pq)[n-1]
+ (*pq)[n-1] = nil // ovoid memory leak
+ *pq = (*pq)[0 : n-1]
+
+ return ret
+}
+func (pq *priorityQueueImp) Peek() *object.Commit {
+ if len(*pq) == 0 {
+ return nil
+ }
+ return (*pq)[0].Commit
+}
+
+type priorityQueue priorityQueueImp
+
+func (pq *priorityQueue) Init() { heap.Init((*priorityQueueImp)(pq)) }
+func (pq *priorityQueue) Len() int { return (*priorityQueueImp)(pq).Len() }
+func (pq *priorityQueue) Push(c *queueItem) {
+ heap.Push((*priorityQueueImp)(pq), c)
+}
+func (pq *priorityQueue) Pop() *queueItem {
+ return heap.Pop((*priorityQueueImp)(pq)).(*queueItem)
+}
+func (pq *priorityQueue) Peek() *object.Commit { return (*priorityQueueImp)(pq).Peek() }
+
+type parentCommit struct {
+ Commit *object.Commit
+ Path string
+}
+
+func parentsContainingPath(path string, c *object.Commit) ([]parentCommit, error) {
+ // TODO: benchmark this method making git.object.Commit.parent public instead of using
+ // an iterator
+ var result []parentCommit
+ iter := c.Parents()
+ for {
+ parent, err := iter.Next()
+ if err == io.EOF {
+ return result, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+ if _, err := parent.File(path); err == nil {
+ result = append(result, parentCommit{parent, path})
+ } else {
+ // look for renames
+ patch, err := parent.Patch(c)
+ if err != nil {
+ return nil, err
+ } else if patch != nil {
+ for _, fp := range patch.FilePatches() {
+ from, to := fp.Files()
+ if from != nil && to != nil && to.Path() == path {
+ result = append(result, parentCommit{parent, from.Path()})
+ break
+ }
+ }
+ }
+ }
+ }
+}
+
+func blobHash(path string, commit *object.Commit) (plumbing.Hash, error) {
+ file, err := commit.File(path)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+ return file.Hash, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/common.go b/vendor/github.com/go-git/go-git/v5/common.go
new file mode 100644
index 00000000..6174339a
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/common.go
@@ -0,0 +1,20 @@
+package git
+
+import "strings"
+
+// countLines returns the number of lines in a string à la git, this is
+// The newline character is assumed to be '\n'. The empty string
+// contains 0 lines. If the last line of the string doesn't end with a
+// newline, it will still be considered a line.
+func countLines(s string) int {
+ if s == "" {
+ return 0
+ }
+
+ nEOL := strings.Count(s, "\n")
+ if strings.HasSuffix(s, "\n") {
+ return nEOL
+ }
+
+ return nEOL + 1
+}
diff --git a/vendor/github.com/go-git/go-git/v5/config/branch.go b/vendor/github.com/go-git/go-git/v5/config/branch.go
new file mode 100644
index 00000000..db2cb499
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/config/branch.go
@@ -0,0 +1,123 @@
+package config
+
+import (
+ "errors"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ format "github.com/go-git/go-git/v5/plumbing/format/config"
+)
+
+var (
+ errBranchEmptyName = errors.New("branch config: empty name")
+ errBranchInvalidMerge = errors.New("branch config: invalid merge")
+ errBranchInvalidRebase = errors.New("branch config: rebase must be one of 'true' or 'interactive'")
+)
+
+// Branch contains information on the
+// local branches and which remote to track
+type Branch struct {
+ // Name of branch
+ Name string
+ // Remote name of remote to track
+ Remote string
+ // Merge is the local refspec for the branch
+ Merge plumbing.ReferenceName
+ // Rebase instead of merge when pulling. Valid values are
+ // "true" and "interactive". "false" is undocumented and
+ // typically represented by the non-existence of this field
+ Rebase string
+ // Description explains what the branch is for.
+ // Multi-line explanations may be used.
+ //
+ // Original git command to edit:
+ // git branch --edit-description
+ Description string
+
+ raw *format.Subsection
+}
+
+// Validate validates fields of branch
+func (b *Branch) Validate() error {
+ if b.Name == "" {
+ return errBranchEmptyName
+ }
+
+ if b.Merge != "" && !b.Merge.IsBranch() {
+ return errBranchInvalidMerge
+ }
+
+ if b.Rebase != "" &&
+ b.Rebase != "true" &&
+ b.Rebase != "interactive" &&
+ b.Rebase != "false" {
+ return errBranchInvalidRebase
+ }
+
+ return plumbing.NewBranchReferenceName(b.Name).Validate()
+}
+
+func (b *Branch) marshal() *format.Subsection {
+ if b.raw == nil {
+ b.raw = &format.Subsection{}
+ }
+
+ b.raw.Name = b.Name
+
+ if b.Remote == "" {
+ b.raw.RemoveOption(remoteSection)
+ } else {
+ b.raw.SetOption(remoteSection, b.Remote)
+ }
+
+ if b.Merge == "" {
+ b.raw.RemoveOption(mergeKey)
+ } else {
+ b.raw.SetOption(mergeKey, string(b.Merge))
+ }
+
+ if b.Rebase == "" {
+ b.raw.RemoveOption(rebaseKey)
+ } else {
+ b.raw.SetOption(rebaseKey, b.Rebase)
+ }
+
+ if b.Description == "" {
+ b.raw.RemoveOption(descriptionKey)
+ } else {
+ desc := quoteDescription(b.Description)
+ b.raw.SetOption(descriptionKey, desc)
+ }
+
+ return b.raw
+}
+
+// hack to trigger conditional quoting in the
+// plumbing/format/config/Encoder.encodeOptions
+//
+// Current Encoder implementation uses Go %q format if value contains a backslash character,
+// which is not consistent with reference git implementation.
+// git just replaces newline characters with \n, while Encoder prints them directly.
+// Until value quoting fix, we should escape description value by replacing newline characters with \n.
+func quoteDescription(desc string) string {
+ return strings.ReplaceAll(desc, "\n", `\n`)
+}
+
+func (b *Branch) unmarshal(s *format.Subsection) error {
+ b.raw = s
+
+ b.Name = b.raw.Name
+ b.Remote = b.raw.Options.Get(remoteSection)
+ b.Merge = plumbing.ReferenceName(b.raw.Options.Get(mergeKey))
+ b.Rebase = b.raw.Options.Get(rebaseKey)
+ b.Description = unquoteDescription(b.raw.Options.Get(descriptionKey))
+
+ return b.Validate()
+}
+
+// hack to enable conditional quoting in the
+// plumbing/format/config/Encoder.encodeOptions
+// goto quoteDescription for details.
+func unquoteDescription(desc string) string {
+ return strings.ReplaceAll(desc, `\n`, "\n")
+}
diff --git a/vendor/github.com/go-git/go-git/v5/config/config.go b/vendor/github.com/go-git/go-git/v5/config/config.go
new file mode 100644
index 00000000..6d41c15d
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/config/config.go
@@ -0,0 +1,696 @@
+// Package config contains the abstraction of multiple config files
+package config
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "sort"
+ "strconv"
+
+ "github.com/go-git/go-billy/v5/osfs"
+ "github.com/go-git/go-git/v5/internal/url"
+ "github.com/go-git/go-git/v5/plumbing"
+ format "github.com/go-git/go-git/v5/plumbing/format/config"
+)
+
+const (
+ // DefaultFetchRefSpec is the default refspec used for fetch.
+ DefaultFetchRefSpec = "+refs/heads/*:refs/remotes/%s/*"
+ // DefaultPushRefSpec is the default refspec used for push.
+ DefaultPushRefSpec = "refs/heads/*:refs/heads/*"
+)
+
+// ConfigStorer generic storage of Config object
+type ConfigStorer interface {
+ Config() (*Config, error)
+ SetConfig(*Config) error
+}
+
+var (
+ ErrInvalid = errors.New("config invalid key in remote or branch")
+ ErrRemoteConfigNotFound = errors.New("remote config not found")
+ ErrRemoteConfigEmptyURL = errors.New("remote config: empty URL")
+ ErrRemoteConfigEmptyName = errors.New("remote config: empty name")
+)
+
+// Scope defines the scope of a config file, such as local, global or system.
+type Scope int
+
+// Available ConfigScope's
+const (
+ LocalScope Scope = iota
+ GlobalScope
+ SystemScope
+)
+
+// Config contains the repository configuration
+// https://www.kernel.org/pub/software/scm/git/docs/git-config.html#FILES
+type Config struct {
+ Core struct {
+ // IsBare if true this repository is assumed to be bare and has no
+ // working directory associated with it.
+ IsBare bool
+ // Worktree is the path to the root of the working tree.
+ Worktree string
+ // CommentChar is the character indicating the start of a
+ // comment for commands like commit and tag
+ CommentChar string
+ // RepositoryFormatVersion identifies the repository format and layout version.
+ RepositoryFormatVersion format.RepositoryFormatVersion
+ }
+
+ User struct {
+ // Name is the personal name of the author and the committer of a commit.
+ Name string
+ // Email is the email of the author and the committer of a commit.
+ Email string
+ }
+
+ Author struct {
+ // Name is the personal name of the author of a commit.
+ Name string
+ // Email is the email of the author of a commit.
+ Email string
+ }
+
+ Committer struct {
+ // Name is the personal name of the committer of a commit.
+ Name string
+ // Email is the email of the committer of a commit.
+ Email string
+ }
+
+ Pack struct {
+ // Window controls the size of the sliding window for delta
+ // compression. The default is 10. A value of 0 turns off
+ // delta compression entirely.
+ Window uint
+ }
+
+ Init struct {
+ // DefaultBranch Allows overriding the default branch name
+ // e.g. when initializing a new repository or when cloning
+ // an empty repository.
+ DefaultBranch string
+ }
+
+ Extensions struct {
+ // ObjectFormat specifies the hash algorithm to use. The
+ // acceptable values are sha1 and sha256. If not specified,
+ // sha1 is assumed. It is an error to specify this key unless
+ // core.repositoryFormatVersion is 1.
+ //
+ // This setting must not be changed after repository initialization
+ // (e.g. clone or init).
+ ObjectFormat format.ObjectFormat
+ }
+
+ // Remotes list of repository remotes, the key of the map is the name
+ // of the remote, should equal to RemoteConfig.Name.
+ Remotes map[string]*RemoteConfig
+ // Submodules list of repository submodules, the key of the map is the name
+ // of the submodule, should equal to Submodule.Name.
+ Submodules map[string]*Submodule
+ // Branches list of branches, the key is the branch name and should
+ // equal Branch.Name
+ Branches map[string]*Branch
+ // URLs list of url rewrite rules, if repo url starts with URL.InsteadOf value, it will be replaced with the
+ // key instead.
+ URLs map[string]*URL
+ // Raw contains the raw information of a config file. The main goal is
+ // preserve the parsed information from the original format, to avoid
+ // dropping unsupported fields.
+ Raw *format.Config
+}
+
+// NewConfig returns a new empty Config.
+func NewConfig() *Config {
+ config := &Config{
+ Remotes: make(map[string]*RemoteConfig),
+ Submodules: make(map[string]*Submodule),
+ Branches: make(map[string]*Branch),
+ URLs: make(map[string]*URL),
+ Raw: format.New(),
+ }
+
+ config.Pack.Window = DefaultPackWindow
+
+ return config
+}
+
+// ReadConfig reads a config file from a io.Reader.
+func ReadConfig(r io.Reader) (*Config, error) {
+ b, err := io.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+
+ cfg := NewConfig()
+ if err = cfg.Unmarshal(b); err != nil {
+ return nil, err
+ }
+
+ return cfg, nil
+}
+
+// LoadConfig loads a config file from a given scope. The returned Config,
+// contains exclusively information from the given scope. If it couldn't find a
+// config file to the given scope, an empty one is returned.
+func LoadConfig(scope Scope) (*Config, error) {
+ if scope == LocalScope {
+ return nil, fmt.Errorf("LocalScope should be read from the a ConfigStorer")
+ }
+
+ files, err := Paths(scope)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, file := range files {
+ f, err := osfs.Default.Open(file)
+ if err != nil {
+ if os.IsNotExist(err) {
+ continue
+ }
+
+ return nil, err
+ }
+
+ defer f.Close()
+ return ReadConfig(f)
+ }
+
+ return NewConfig(), nil
+}
+
+// Paths returns the config file location for a given scope.
+func Paths(scope Scope) ([]string, error) {
+ var files []string
+ switch scope {
+ case GlobalScope:
+ xdg := os.Getenv("XDG_CONFIG_HOME")
+ if xdg != "" {
+ files = append(files, filepath.Join(xdg, "git/config"))
+ }
+
+ home, err := os.UserHomeDir()
+ if err != nil {
+ return nil, err
+ }
+
+ files = append(files,
+ filepath.Join(home, ".gitconfig"),
+ filepath.Join(home, ".config/git/config"),
+ )
+ case SystemScope:
+ files = append(files, "/etc/gitconfig")
+ }
+
+ return files, nil
+}
+
+// Validate validates the fields and sets the default values.
+func (c *Config) Validate() error {
+ for name, r := range c.Remotes {
+ if r.Name != name {
+ return ErrInvalid
+ }
+
+ if err := r.Validate(); err != nil {
+ return err
+ }
+ }
+
+ for name, b := range c.Branches {
+ if b.Name != name {
+ return ErrInvalid
+ }
+
+ if err := b.Validate(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+const (
+ remoteSection = "remote"
+ submoduleSection = "submodule"
+ branchSection = "branch"
+ coreSection = "core"
+ packSection = "pack"
+ userSection = "user"
+ authorSection = "author"
+ committerSection = "committer"
+ initSection = "init"
+ urlSection = "url"
+ extensionsSection = "extensions"
+ fetchKey = "fetch"
+ urlKey = "url"
+ bareKey = "bare"
+ worktreeKey = "worktree"
+ commentCharKey = "commentChar"
+ windowKey = "window"
+ mergeKey = "merge"
+ rebaseKey = "rebase"
+ nameKey = "name"
+ emailKey = "email"
+ descriptionKey = "description"
+ defaultBranchKey = "defaultBranch"
+ repositoryFormatVersionKey = "repositoryformatversion"
+ objectFormat = "objectformat"
+ mirrorKey = "mirror"
+
+ // DefaultPackWindow holds the number of previous objects used to
+ // generate deltas. The value 10 is the same used by git command.
+ DefaultPackWindow = uint(10)
+)
+
+// Unmarshal parses a git-config file and stores it.
+func (c *Config) Unmarshal(b []byte) error {
+ r := bytes.NewBuffer(b)
+ d := format.NewDecoder(r)
+
+ c.Raw = format.New()
+ if err := d.Decode(c.Raw); err != nil {
+ return err
+ }
+
+ c.unmarshalCore()
+ c.unmarshalUser()
+ c.unmarshalInit()
+ if err := c.unmarshalPack(); err != nil {
+ return err
+ }
+ unmarshalSubmodules(c.Raw, c.Submodules)
+
+ if err := c.unmarshalBranches(); err != nil {
+ return err
+ }
+
+ if err := c.unmarshalURLs(); err != nil {
+ return err
+ }
+
+ return c.unmarshalRemotes()
+}
+
+func (c *Config) unmarshalCore() {
+ s := c.Raw.Section(coreSection)
+ if s.Options.Get(bareKey) == "true" {
+ c.Core.IsBare = true
+ }
+
+ c.Core.Worktree = s.Options.Get(worktreeKey)
+ c.Core.CommentChar = s.Options.Get(commentCharKey)
+}
+
+func (c *Config) unmarshalUser() {
+ s := c.Raw.Section(userSection)
+ c.User.Name = s.Options.Get(nameKey)
+ c.User.Email = s.Options.Get(emailKey)
+
+ s = c.Raw.Section(authorSection)
+ c.Author.Name = s.Options.Get(nameKey)
+ c.Author.Email = s.Options.Get(emailKey)
+
+ s = c.Raw.Section(committerSection)
+ c.Committer.Name = s.Options.Get(nameKey)
+ c.Committer.Email = s.Options.Get(emailKey)
+}
+
+func (c *Config) unmarshalPack() error {
+ s := c.Raw.Section(packSection)
+ window := s.Options.Get(windowKey)
+ if window == "" {
+ c.Pack.Window = DefaultPackWindow
+ } else {
+ winUint, err := strconv.ParseUint(window, 10, 32)
+ if err != nil {
+ return err
+ }
+ c.Pack.Window = uint(winUint)
+ }
+ return nil
+}
+
+func (c *Config) unmarshalRemotes() error {
+ s := c.Raw.Section(remoteSection)
+ for _, sub := range s.Subsections {
+ r := &RemoteConfig{}
+ if err := r.unmarshal(sub); err != nil {
+ return err
+ }
+
+ c.Remotes[r.Name] = r
+ }
+
+ // Apply insteadOf url rules
+ for _, r := range c.Remotes {
+ r.applyURLRules(c.URLs)
+ }
+
+ return nil
+}
+
+func (c *Config) unmarshalURLs() error {
+ s := c.Raw.Section(urlSection)
+ for _, sub := range s.Subsections {
+ r := &URL{}
+ if err := r.unmarshal(sub); err != nil {
+ return err
+ }
+
+ c.URLs[r.Name] = r
+ }
+
+ return nil
+}
+
+func unmarshalSubmodules(fc *format.Config, submodules map[string]*Submodule) {
+ s := fc.Section(submoduleSection)
+ for _, sub := range s.Subsections {
+ m := &Submodule{}
+ m.unmarshal(sub)
+
+ if m.Validate() == ErrModuleBadPath {
+ continue
+ }
+
+ submodules[m.Name] = m
+ }
+}
+
+func (c *Config) unmarshalBranches() error {
+ bs := c.Raw.Section(branchSection)
+ for _, sub := range bs.Subsections {
+ b := &Branch{}
+
+ if err := b.unmarshal(sub); err != nil {
+ return err
+ }
+
+ c.Branches[b.Name] = b
+ }
+ return nil
+}
+
+func (c *Config) unmarshalInit() {
+ s := c.Raw.Section(initSection)
+ c.Init.DefaultBranch = s.Options.Get(defaultBranchKey)
+}
+
+// Marshal returns Config encoded as a git-config file.
+func (c *Config) Marshal() ([]byte, error) {
+ c.marshalCore()
+ c.marshalExtensions()
+ c.marshalUser()
+ c.marshalPack()
+ c.marshalRemotes()
+ c.marshalSubmodules()
+ c.marshalBranches()
+ c.marshalURLs()
+ c.marshalInit()
+
+ buf := bytes.NewBuffer(nil)
+ if err := format.NewEncoder(buf).Encode(c.Raw); err != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+}
+
+func (c *Config) marshalCore() {
+ s := c.Raw.Section(coreSection)
+ s.SetOption(bareKey, fmt.Sprintf("%t", c.Core.IsBare))
+ if string(c.Core.RepositoryFormatVersion) != "" {
+ s.SetOption(repositoryFormatVersionKey, string(c.Core.RepositoryFormatVersion))
+ }
+
+ if c.Core.Worktree != "" {
+ s.SetOption(worktreeKey, c.Core.Worktree)
+ }
+}
+
+func (c *Config) marshalExtensions() {
+ // Extensions are only supported on Version 1, therefore
+ // ignore them otherwise.
+ if c.Core.RepositoryFormatVersion == format.Version_1 {
+ s := c.Raw.Section(extensionsSection)
+ s.SetOption(objectFormat, string(c.Extensions.ObjectFormat))
+ }
+}
+
+func (c *Config) marshalUser() {
+ s := c.Raw.Section(userSection)
+ if c.User.Name != "" {
+ s.SetOption(nameKey, c.User.Name)
+ }
+
+ if c.User.Email != "" {
+ s.SetOption(emailKey, c.User.Email)
+ }
+
+ s = c.Raw.Section(authorSection)
+ if c.Author.Name != "" {
+ s.SetOption(nameKey, c.Author.Name)
+ }
+
+ if c.Author.Email != "" {
+ s.SetOption(emailKey, c.Author.Email)
+ }
+
+ s = c.Raw.Section(committerSection)
+ if c.Committer.Name != "" {
+ s.SetOption(nameKey, c.Committer.Name)
+ }
+
+ if c.Committer.Email != "" {
+ s.SetOption(emailKey, c.Committer.Email)
+ }
+}
+
+func (c *Config) marshalPack() {
+ s := c.Raw.Section(packSection)
+ if c.Pack.Window != DefaultPackWindow {
+ s.SetOption(windowKey, fmt.Sprintf("%d", c.Pack.Window))
+ }
+}
+
+func (c *Config) marshalRemotes() {
+ s := c.Raw.Section(remoteSection)
+ newSubsections := make(format.Subsections, 0, len(c.Remotes))
+ added := make(map[string]bool)
+ for _, subsection := range s.Subsections {
+ if remote, ok := c.Remotes[subsection.Name]; ok {
+ newSubsections = append(newSubsections, remote.marshal())
+ added[subsection.Name] = true
+ }
+ }
+
+ remoteNames := make([]string, 0, len(c.Remotes))
+ for name := range c.Remotes {
+ remoteNames = append(remoteNames, name)
+ }
+
+ sort.Strings(remoteNames)
+
+ for _, name := range remoteNames {
+ if !added[name] {
+ newSubsections = append(newSubsections, c.Remotes[name].marshal())
+ }
+ }
+
+ s.Subsections = newSubsections
+}
+
+func (c *Config) marshalSubmodules() {
+ s := c.Raw.Section(submoduleSection)
+ s.Subsections = make(format.Subsections, len(c.Submodules))
+
+ var i int
+ for _, r := range c.Submodules {
+ section := r.marshal()
+ // the submodule section at config is a subset of the .gitmodule file
+ // we should remove the non-valid options for the config file.
+ section.RemoveOption(pathKey)
+ s.Subsections[i] = section
+ i++
+ }
+}
+
+func (c *Config) marshalBranches() {
+ s := c.Raw.Section(branchSection)
+ newSubsections := make(format.Subsections, 0, len(c.Branches))
+ added := make(map[string]bool)
+ for _, subsection := range s.Subsections {
+ if branch, ok := c.Branches[subsection.Name]; ok {
+ newSubsections = append(newSubsections, branch.marshal())
+ added[subsection.Name] = true
+ }
+ }
+
+ branchNames := make([]string, 0, len(c.Branches))
+ for name := range c.Branches {
+ branchNames = append(branchNames, name)
+ }
+
+ sort.Strings(branchNames)
+
+ for _, name := range branchNames {
+ if !added[name] {
+ newSubsections = append(newSubsections, c.Branches[name].marshal())
+ }
+ }
+
+ s.Subsections = newSubsections
+}
+
+func (c *Config) marshalURLs() {
+ s := c.Raw.Section(urlSection)
+ s.Subsections = make(format.Subsections, len(c.URLs))
+
+ var i int
+ for _, r := range c.URLs {
+ section := r.marshal()
+ // the submodule section at config is a subset of the .gitmodule file
+ // we should remove the non-valid options for the config file.
+ s.Subsections[i] = section
+ i++
+ }
+}
+
+func (c *Config) marshalInit() {
+ s := c.Raw.Section(initSection)
+ if c.Init.DefaultBranch != "" {
+ s.SetOption(defaultBranchKey, c.Init.DefaultBranch)
+ }
+}
+
+// RemoteConfig contains the configuration for a given remote repository.
+type RemoteConfig struct {
+ // Name of the remote
+ Name string
+ // URLs the URLs of a remote repository. It must be non-empty. Fetch will
+ // always use the first URL, while push will use all of them.
+ URLs []string
+ // Mirror indicates that the repository is a mirror of remote.
+ Mirror bool
+
+ // insteadOfRulesApplied have urls been modified
+ insteadOfRulesApplied bool
+ // originalURLs are the urls before applying insteadOf rules
+ originalURLs []string
+
+ // Fetch the default set of "refspec" for fetch operation
+ Fetch []RefSpec
+
+ // raw representation of the subsection, filled by marshal or unmarshal are
+ // called
+ raw *format.Subsection
+}
+
+// Validate validates the fields and sets the default values.
+func (c *RemoteConfig) Validate() error {
+ if c.Name == "" {
+ return ErrRemoteConfigEmptyName
+ }
+
+ if len(c.URLs) == 0 {
+ return ErrRemoteConfigEmptyURL
+ }
+
+ for _, r := range c.Fetch {
+ if err := r.Validate(); err != nil {
+ return err
+ }
+ }
+
+ if len(c.Fetch) == 0 {
+ c.Fetch = []RefSpec{RefSpec(fmt.Sprintf(DefaultFetchRefSpec, c.Name))}
+ }
+
+ return plumbing.NewRemoteHEADReferenceName(c.Name).Validate()
+}
+
+func (c *RemoteConfig) unmarshal(s *format.Subsection) error {
+ c.raw = s
+
+ fetch := []RefSpec{}
+ for _, f := range c.raw.Options.GetAll(fetchKey) {
+ rs := RefSpec(f)
+ if err := rs.Validate(); err != nil {
+ return err
+ }
+
+ fetch = append(fetch, rs)
+ }
+
+ c.Name = c.raw.Name
+ c.URLs = append([]string(nil), c.raw.Options.GetAll(urlKey)...)
+ c.Fetch = fetch
+ c.Mirror = c.raw.Options.Get(mirrorKey) == "true"
+
+ return nil
+}
+
+func (c *RemoteConfig) marshal() *format.Subsection {
+ if c.raw == nil {
+ c.raw = &format.Subsection{}
+ }
+
+ c.raw.Name = c.Name
+ if len(c.URLs) == 0 {
+ c.raw.RemoveOption(urlKey)
+ } else {
+ urls := c.URLs
+ if c.insteadOfRulesApplied {
+ urls = c.originalURLs
+ }
+
+ c.raw.SetOption(urlKey, urls...)
+ }
+
+ if len(c.Fetch) == 0 {
+ c.raw.RemoveOption(fetchKey)
+ } else {
+ var values []string
+ for _, rs := range c.Fetch {
+ values = append(values, rs.String())
+ }
+
+ c.raw.SetOption(fetchKey, values...)
+ }
+
+ if c.Mirror {
+ c.raw.SetOption(mirrorKey, strconv.FormatBool(c.Mirror))
+ }
+
+ return c.raw
+}
+
+func (c *RemoteConfig) IsFirstURLLocal() bool {
+ return url.IsLocalEndpoint(c.URLs[0])
+}
+
+func (c *RemoteConfig) applyURLRules(urlRules map[string]*URL) {
+ // save original urls
+ originalURLs := make([]string, len(c.URLs))
+ copy(originalURLs, c.URLs)
+
+ for i, url := range c.URLs {
+ if matchingURLRule := findLongestInsteadOfMatch(url, urlRules); matchingURLRule != nil {
+ c.URLs[i] = matchingURLRule.ApplyInsteadOf(c.URLs[i])
+ c.insteadOfRulesApplied = true
+ }
+ }
+
+ if c.insteadOfRulesApplied {
+ c.originalURLs = originalURLs
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/config/modules.go b/vendor/github.com/go-git/go-git/v5/config/modules.go
new file mode 100644
index 00000000..1c10aa35
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/config/modules.go
@@ -0,0 +1,139 @@
+package config
+
+import (
+ "bytes"
+ "errors"
+ "regexp"
+
+ format "github.com/go-git/go-git/v5/plumbing/format/config"
+)
+
+var (
+ ErrModuleEmptyURL = errors.New("module config: empty URL")
+ ErrModuleEmptyPath = errors.New("module config: empty path")
+ ErrModuleBadPath = errors.New("submodule has an invalid path")
+)
+
+var (
+ // Matches module paths with dotdot ".." components.
+ dotdotPath = regexp.MustCompile(`(^|[/\\])\.\.([/\\]|$)`)
+)
+
+// Modules defines the submodules properties, represents a .gitmodules file
+// https://www.kernel.org/pub/software/scm/git/docs/gitmodules.html
+type Modules struct {
+ // Submodules is a map of submodules being the key the name of the submodule.
+ Submodules map[string]*Submodule
+
+ raw *format.Config
+}
+
+// NewModules returns a new empty Modules
+func NewModules() *Modules {
+ return &Modules{
+ Submodules: make(map[string]*Submodule),
+ raw: format.New(),
+ }
+}
+
+const (
+ pathKey = "path"
+ branchKey = "branch"
+)
+
+// Unmarshal parses a git-config file and stores it.
+func (m *Modules) Unmarshal(b []byte) error {
+ r := bytes.NewBuffer(b)
+ d := format.NewDecoder(r)
+
+ m.raw = format.New()
+ if err := d.Decode(m.raw); err != nil {
+ return err
+ }
+
+ unmarshalSubmodules(m.raw, m.Submodules)
+ return nil
+}
+
+// Marshal returns Modules encoded as a git-config file.
+func (m *Modules) Marshal() ([]byte, error) {
+ s := m.raw.Section(submoduleSection)
+ s.Subsections = make(format.Subsections, len(m.Submodules))
+
+ var i int
+ for _, r := range m.Submodules {
+ s.Subsections[i] = r.marshal()
+ i++
+ }
+
+ buf := bytes.NewBuffer(nil)
+ if err := format.NewEncoder(buf).Encode(m.raw); err != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+}
+
+// Submodule defines a submodule.
+type Submodule struct {
+ // Name module name
+ Name string
+ // Path defines the path, relative to the top-level directory of the Git
+ // working tree.
+ Path string
+ // URL defines a URL from which the submodule repository can be cloned.
+ URL string
+ // Branch is a remote branch name for tracking updates in the upstream
+ // submodule. Optional value.
+ Branch string
+
+ // raw representation of the subsection, filled by marshal or unmarshal are
+ // called.
+ raw *format.Subsection
+}
+
+// Validate validates the fields and sets the default values.
+func (m *Submodule) Validate() error {
+ if m.Path == "" {
+ return ErrModuleEmptyPath
+ }
+
+ if m.URL == "" {
+ return ErrModuleEmptyURL
+ }
+
+ if dotdotPath.MatchString(m.Path) {
+ return ErrModuleBadPath
+ }
+
+ return nil
+}
+
+func (m *Submodule) unmarshal(s *format.Subsection) {
+ m.raw = s
+
+ m.Name = m.raw.Name
+ m.Path = m.raw.Option(pathKey)
+ m.URL = m.raw.Option(urlKey)
+ m.Branch = m.raw.Option(branchKey)
+}
+
+func (m *Submodule) marshal() *format.Subsection {
+ if m.raw == nil {
+ m.raw = &format.Subsection{}
+ }
+
+ m.raw.Name = m.Name
+ if m.raw.Name == "" {
+ m.raw.Name = m.Path
+ }
+
+ m.raw.SetOption(pathKey, m.Path)
+ m.raw.SetOption(urlKey, m.URL)
+
+ if m.Branch != "" {
+ m.raw.SetOption(branchKey, m.Branch)
+ }
+
+ return m.raw
+}
diff --git a/vendor/github.com/go-git/go-git/v5/config/refspec.go b/vendor/github.com/go-git/go-git/v5/config/refspec.go
new file mode 100644
index 00000000..e2cf8c97
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/config/refspec.go
@@ -0,0 +1,155 @@
+package config
+
+import (
+ "errors"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+const (
+ refSpecWildcard = "*"
+ refSpecForce = "+"
+ refSpecSeparator = ":"
+)
+
+var (
+ ErrRefSpecMalformedSeparator = errors.New("malformed refspec, separators are wrong")
+ ErrRefSpecMalformedWildcard = errors.New("malformed refspec, mismatched number of wildcards")
+)
+
+// RefSpec is a mapping from local branches to remote references.
+// The format of the refspec is an optional +, followed by :, where
+// is the pattern for references on the remote side and is where
+// those references will be written locally. The + tells Git to update the
+// reference even if it isn’t a fast-forward.
+// eg.: "+refs/heads/*:refs/remotes/origin/*"
+//
+// https://git-scm.com/book/en/v2/Git-Internals-The-Refspec
+type RefSpec string
+
+// Validate validates the RefSpec
+func (s RefSpec) Validate() error {
+ spec := string(s)
+ if strings.Count(spec, refSpecSeparator) != 1 {
+ return ErrRefSpecMalformedSeparator
+ }
+
+ sep := strings.Index(spec, refSpecSeparator)
+ if sep == len(spec)-1 {
+ return ErrRefSpecMalformedSeparator
+ }
+
+ ws := strings.Count(spec[0:sep], refSpecWildcard)
+ wd := strings.Count(spec[sep+1:], refSpecWildcard)
+ if ws == wd && ws < 2 && wd < 2 {
+ return nil
+ }
+
+ return ErrRefSpecMalformedWildcard
+}
+
+// IsForceUpdate returns if update is allowed in non fast-forward merges.
+func (s RefSpec) IsForceUpdate() bool {
+ return s[0] == refSpecForce[0]
+}
+
+// IsDelete returns true if the refspec indicates a delete (empty src).
+func (s RefSpec) IsDelete() bool {
+ return s[0] == refSpecSeparator[0]
+}
+
+// IsExactSHA1 returns true if the source is a SHA1 hash.
+func (s RefSpec) IsExactSHA1() bool {
+ return plumbing.IsHash(s.Src())
+}
+
+// Src returns the src side.
+func (s RefSpec) Src() string {
+ spec := string(s)
+
+ var start int
+ if s.IsForceUpdate() {
+ start = 1
+ } else {
+ start = 0
+ }
+
+ end := strings.Index(spec, refSpecSeparator)
+ return spec[start:end]
+}
+
+// Match match the given plumbing.ReferenceName against the source.
+func (s RefSpec) Match(n plumbing.ReferenceName) bool {
+ if !s.IsWildcard() {
+ return s.matchExact(n)
+ }
+
+ return s.matchGlob(n)
+}
+
+// IsWildcard returns true if the RefSpec contains a wildcard.
+func (s RefSpec) IsWildcard() bool {
+ return strings.Contains(string(s), refSpecWildcard)
+}
+
+func (s RefSpec) matchExact(n plumbing.ReferenceName) bool {
+ return s.Src() == n.String()
+}
+
+func (s RefSpec) matchGlob(n plumbing.ReferenceName) bool {
+ src := s.Src()
+ name := n.String()
+ wildcard := strings.Index(src, refSpecWildcard)
+
+ var prefix, suffix string
+ prefix = src[0:wildcard]
+ if len(src) > wildcard+1 {
+ suffix = src[wildcard+1:]
+ }
+
+ return len(name) >= len(prefix)+len(suffix) &&
+ strings.HasPrefix(name, prefix) &&
+ strings.HasSuffix(name, suffix)
+}
+
+// Dst returns the destination for the given remote reference.
+func (s RefSpec) Dst(n plumbing.ReferenceName) plumbing.ReferenceName {
+ spec := string(s)
+ start := strings.Index(spec, refSpecSeparator) + 1
+ dst := spec[start:]
+ src := s.Src()
+
+ if !s.IsWildcard() {
+ return plumbing.ReferenceName(dst)
+ }
+
+ name := n.String()
+ ws := strings.Index(src, refSpecWildcard)
+ wd := strings.Index(dst, refSpecWildcard)
+ match := name[ws : len(name)-(len(src)-(ws+1))]
+
+ return plumbing.ReferenceName(dst[0:wd] + match + dst[wd+1:])
+}
+
+func (s RefSpec) Reverse() RefSpec {
+ spec := string(s)
+ separator := strings.Index(spec, refSpecSeparator)
+
+ return RefSpec(spec[separator+1:] + refSpecSeparator + spec[:separator])
+}
+
+func (s RefSpec) String() string {
+ return string(s)
+}
+
+// MatchAny returns true if any of the RefSpec match with the given ReferenceName.
+func MatchAny(l []RefSpec, n plumbing.ReferenceName) bool {
+ for _, r := range l {
+ if r.Match(n) {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/vendor/github.com/go-git/go-git/v5/config/url.go b/vendor/github.com/go-git/go-git/v5/config/url.go
new file mode 100644
index 00000000..114d6b26
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/config/url.go
@@ -0,0 +1,81 @@
+package config
+
+import (
+ "errors"
+ "strings"
+
+ format "github.com/go-git/go-git/v5/plumbing/format/config"
+)
+
+var (
+ errURLEmptyInsteadOf = errors.New("url config: empty insteadOf")
+)
+
+// Url defines Url rewrite rules
+type URL struct {
+ // Name new base url
+ Name string
+ // Any URL that starts with this value will be rewritten to start, instead, with .
+ // When more than one insteadOf strings match a given URL, the longest match is used.
+ InsteadOf string
+
+ // raw representation of the subsection, filled by marshal or unmarshal are
+ // called.
+ raw *format.Subsection
+}
+
+// Validate validates fields of branch
+func (b *URL) Validate() error {
+ if b.InsteadOf == "" {
+ return errURLEmptyInsteadOf
+ }
+
+ return nil
+}
+
+const (
+ insteadOfKey = "insteadOf"
+)
+
+func (u *URL) unmarshal(s *format.Subsection) error {
+ u.raw = s
+
+ u.Name = s.Name
+ u.InsteadOf = u.raw.Option(insteadOfKey)
+ return nil
+}
+
+func (u *URL) marshal() *format.Subsection {
+ if u.raw == nil {
+ u.raw = &format.Subsection{}
+ }
+
+ u.raw.Name = u.Name
+ u.raw.SetOption(insteadOfKey, u.InsteadOf)
+
+ return u.raw
+}
+
+func findLongestInsteadOfMatch(remoteURL string, urls map[string]*URL) *URL {
+ var longestMatch *URL
+ for _, u := range urls {
+ if !strings.HasPrefix(remoteURL, u.InsteadOf) {
+ continue
+ }
+
+ // according to spec if there is more than one match, take the logest
+ if longestMatch == nil || len(longestMatch.InsteadOf) < len(u.InsteadOf) {
+ longestMatch = u
+ }
+ }
+
+ return longestMatch
+}
+
+func (u *URL) ApplyInsteadOf(url string) string {
+ if !strings.HasPrefix(url, u.InsteadOf) {
+ return url
+ }
+
+ return u.Name + url[len(u.InsteadOf):]
+}
diff --git a/vendor/github.com/go-git/go-git/v5/doc.go b/vendor/github.com/go-git/go-git/v5/doc.go
new file mode 100644
index 00000000..3d817fe9
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/doc.go
@@ -0,0 +1,10 @@
+// A highly extensible git implementation in pure Go.
+//
+// go-git aims to reach the completeness of libgit2 or jgit, nowadays covers the
+// majority of the plumbing read operations and some of the main write
+// operations, but lacks the main porcelain operations such as merges.
+//
+// It is highly extensible, we have been following the open/close principle in
+// its design to facilitate extensions, mainly focusing the efforts on the
+// persistence of the objects.
+package git
diff --git a/vendor/github.com/go-git/go-git/v5/internal/path_util/path_util.go b/vendor/github.com/go-git/go-git/v5/internal/path_util/path_util.go
new file mode 100644
index 00000000..48e4a3d0
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/internal/path_util/path_util.go
@@ -0,0 +1,29 @@
+package path_util
+
+import (
+ "os"
+ "os/user"
+ "strings"
+)
+
+func ReplaceTildeWithHome(path string) (string, error) {
+ if strings.HasPrefix(path, "~") {
+ firstSlash := strings.Index(path, "/")
+ if firstSlash == 1 {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ return path, err
+ }
+ return strings.Replace(path, "~", home, 1), nil
+ } else if firstSlash > 1 {
+ username := path[1:firstSlash]
+ userAccount, err := user.Lookup(username)
+ if err != nil {
+ return path, err
+ }
+ return strings.Replace(path, path[:firstSlash], userAccount.HomeDir, 1), nil
+ }
+ }
+
+ return path, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/internal/revision/parser.go b/vendor/github.com/go-git/go-git/v5/internal/revision/parser.go
new file mode 100644
index 00000000..8a2a7190
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/internal/revision/parser.go
@@ -0,0 +1,626 @@
+// Package revision extracts git revision from string
+// More information about revision : https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
+package revision
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "regexp"
+ "strconv"
+ "time"
+)
+
+// ErrInvalidRevision is emitted if string doesn't match valid revision
+type ErrInvalidRevision struct {
+ s string
+}
+
+func (e *ErrInvalidRevision) Error() string {
+ return "Revision invalid : " + e.s
+}
+
+// Revisioner represents a revision component.
+// A revision is made of multiple revision components
+// obtained after parsing a revision string,
+// for instance revision "master~" will be converted in
+// two revision components Ref and TildePath
+type Revisioner interface {
+}
+
+// Ref represents a reference name : HEAD, master,
+type Ref string
+
+// TildePath represents ~, ~{n}
+type TildePath struct {
+ Depth int
+}
+
+// CaretPath represents ^, ^{n}
+type CaretPath struct {
+ Depth int
+}
+
+// CaretReg represents ^{/foo bar}
+type CaretReg struct {
+ Regexp *regexp.Regexp
+ Negate bool
+}
+
+// CaretType represents ^{commit}
+type CaretType struct {
+ ObjectType string
+}
+
+// AtReflog represents @{n}
+type AtReflog struct {
+ Depth int
+}
+
+// AtCheckout represents @{-n}
+type AtCheckout struct {
+ Depth int
+}
+
+// AtUpstream represents @{upstream}, @{u}
+type AtUpstream struct {
+ BranchName string
+}
+
+// AtPush represents @{push}
+type AtPush struct {
+ BranchName string
+}
+
+// AtDate represents @{"2006-01-02T15:04:05Z"}
+type AtDate struct {
+ Date time.Time
+}
+
+// ColonReg represents :/foo bar
+type ColonReg struct {
+ Regexp *regexp.Regexp
+ Negate bool
+}
+
+// ColonPath represents :./ :
+type ColonPath struct {
+ Path string
+}
+
+// ColonStagePath represents ::/
+type ColonStagePath struct {
+ Path string
+ Stage int
+}
+
+// Parser represents a parser
+// use to tokenize and transform to revisioner chunks
+// a given string
+type Parser struct {
+ s *scanner
+ currentParsedChar struct {
+ tok token
+ lit string
+ }
+ unreadLastChar bool
+}
+
+// NewParserFromString returns a new instance of parser from a string.
+func NewParserFromString(s string) *Parser {
+ return NewParser(bytes.NewBufferString(s))
+}
+
+// NewParser returns a new instance of parser.
+func NewParser(r io.Reader) *Parser {
+ return &Parser{s: newScanner(r)}
+}
+
+// scan returns the next token from the underlying scanner
+// or the last scanned token if an unscan was requested
+func (p *Parser) scan() (token, string, error) {
+ if p.unreadLastChar {
+ p.unreadLastChar = false
+ return p.currentParsedChar.tok, p.currentParsedChar.lit, nil
+ }
+
+ tok, lit, err := p.s.scan()
+
+ p.currentParsedChar.tok, p.currentParsedChar.lit = tok, lit
+
+ return tok, lit, err
+}
+
+// unscan pushes the previously read token back onto the buffer.
+func (p *Parser) unscan() { p.unreadLastChar = true }
+
+// Parse explode a revision string into revisioner chunks
+func (p *Parser) Parse() ([]Revisioner, error) {
+ var rev Revisioner
+ var revs []Revisioner
+ var tok token
+ var err error
+
+ for {
+ tok, _, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch tok {
+ case at:
+ rev, err = p.parseAt()
+ case tilde:
+ rev, err = p.parseTilde()
+ case caret:
+ rev, err = p.parseCaret()
+ case colon:
+ rev, err = p.parseColon()
+ case eof:
+ err = p.validateFullRevision(&revs)
+
+ if err != nil {
+ return []Revisioner{}, err
+ }
+
+ return revs, nil
+ default:
+ p.unscan()
+ rev, err = p.parseRef()
+ }
+
+ if err != nil {
+ return []Revisioner{}, err
+ }
+
+ revs = append(revs, rev)
+ }
+}
+
+// validateFullRevision ensures all revisioner chunks make a valid revision
+func (p *Parser) validateFullRevision(chunks *[]Revisioner) error {
+ var hasReference bool
+
+ for i, chunk := range *chunks {
+ switch chunk.(type) {
+ case Ref:
+ if i == 0 {
+ hasReference = true
+ } else {
+ return &ErrInvalidRevision{`reference must be defined once at the beginning`}
+ }
+ case AtDate:
+ if len(*chunks) == 1 || hasReference && len(*chunks) == 2 {
+ return nil
+ }
+
+ return &ErrInvalidRevision{`"@" statement is not valid, could be : @{}, @{}`}
+ case AtReflog:
+ if len(*chunks) == 1 || hasReference && len(*chunks) == 2 {
+ return nil
+ }
+
+ return &ErrInvalidRevision{`"@" statement is not valid, could be : @{}, @{}`}
+ case AtCheckout:
+ if len(*chunks) == 1 {
+ return nil
+ }
+
+ return &ErrInvalidRevision{`"@" statement is not valid, could be : @{-}`}
+ case AtUpstream:
+ if len(*chunks) == 1 || hasReference && len(*chunks) == 2 {
+ return nil
+ }
+
+ return &ErrInvalidRevision{`"@" statement is not valid, could be : @{upstream}, @{upstream}, @{u}, @{u}`}
+ case AtPush:
+ if len(*chunks) == 1 || hasReference && len(*chunks) == 2 {
+ return nil
+ }
+
+ return &ErrInvalidRevision{`"@" statement is not valid, could be : @{push}, @{push}`}
+ case TildePath, CaretPath, CaretReg:
+ if !hasReference {
+ return &ErrInvalidRevision{`"~" or "^" statement must have a reference defined at the beginning`}
+ }
+ case ColonReg:
+ if len(*chunks) == 1 {
+ return nil
+ }
+
+ return &ErrInvalidRevision{`":" statement is not valid, could be : :/`}
+ case ColonPath:
+ if i == len(*chunks)-1 && hasReference || len(*chunks) == 1 {
+ return nil
+ }
+
+ return &ErrInvalidRevision{`":" statement is not valid, could be : :`}
+ case ColonStagePath:
+ if len(*chunks) == 1 {
+ return nil
+ }
+
+ return &ErrInvalidRevision{`":" statement is not valid, could be : ::`}
+ }
+ }
+
+ return nil
+}
+
+// parseAt extract @ statements
+func (p *Parser) parseAt() (Revisioner, error) {
+ var tok, nextTok token
+ var lit, nextLit string
+ var err error
+
+ tok, _, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ if tok != obrace {
+ p.unscan()
+
+ return Ref("HEAD"), nil
+ }
+
+ tok, lit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ nextTok, nextLit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch {
+ case tok == word && (lit == "u" || lit == "upstream") && nextTok == cbrace:
+ return AtUpstream{}, nil
+ case tok == word && lit == "push" && nextTok == cbrace:
+ return AtPush{}, nil
+ case tok == number && nextTok == cbrace:
+ n, _ := strconv.Atoi(lit)
+
+ return AtReflog{n}, nil
+ case tok == minus && nextTok == number:
+ n, _ := strconv.Atoi(nextLit)
+
+ t, _, err := p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ if t != cbrace {
+ return nil, &ErrInvalidRevision{s: `missing "}" in @{-n} structure`}
+ }
+
+ return AtCheckout{n}, nil
+ default:
+ p.unscan()
+
+ date := lit
+
+ for {
+ tok, lit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch {
+ case tok == cbrace:
+ t, err := time.Parse("2006-01-02T15:04:05Z", date)
+
+ if err != nil {
+ return nil, &ErrInvalidRevision{fmt.Sprintf(`wrong date "%s" must fit ISO-8601 format : 2006-01-02T15:04:05Z`, date)}
+ }
+
+ return AtDate{t}, nil
+ case tok == eof:
+ return nil, &ErrInvalidRevision{s: `missing "}" in @{} structure`}
+ default:
+ date += lit
+ }
+ }
+ }
+}
+
+// parseTilde extract ~ statements
+func (p *Parser) parseTilde() (Revisioner, error) {
+ var tok token
+ var lit string
+ var err error
+
+ tok, lit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch {
+ case tok == number:
+ n, _ := strconv.Atoi(lit)
+
+ return TildePath{n}, nil
+ default:
+ p.unscan()
+ return TildePath{1}, nil
+ }
+}
+
+// parseCaret extract ^ statements
+func (p *Parser) parseCaret() (Revisioner, error) {
+ var tok token
+ var lit string
+ var err error
+
+ tok, lit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch {
+ case tok == obrace:
+ r, err := p.parseCaretBraces()
+
+ if err != nil {
+ return nil, err
+ }
+
+ return r, nil
+ case tok == number:
+ n, _ := strconv.Atoi(lit)
+
+ if n > 2 {
+ return nil, &ErrInvalidRevision{fmt.Sprintf(`"%s" found must be 0, 1 or 2 after "^"`, lit)}
+ }
+
+ return CaretPath{n}, nil
+ default:
+ p.unscan()
+ return CaretPath{1}, nil
+ }
+}
+
+// parseCaretBraces extract ^{} statements
+func (p *Parser) parseCaretBraces() (Revisioner, error) {
+ var tok, nextTok token
+ var lit, _ string
+ start := true
+ var re string
+ var negate bool
+ var err error
+
+ for {
+ tok, lit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ nextTok, _, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch {
+ case tok == word && nextTok == cbrace && (lit == "commit" || lit == "tree" || lit == "blob" || lit == "tag" || lit == "object"):
+ return CaretType{lit}, nil
+ case re == "" && tok == cbrace:
+ return CaretType{"tag"}, nil
+ case re == "" && tok == emark && nextTok == emark:
+ re += lit
+ case re == "" && tok == emark && nextTok == minus:
+ negate = true
+ case re == "" && tok == emark:
+ return nil, &ErrInvalidRevision{s: `revision suffix brace component sequences starting with "/!" others than those defined are reserved`}
+ case re == "" && tok == slash:
+ p.unscan()
+ case tok != slash && start:
+ return nil, &ErrInvalidRevision{fmt.Sprintf(`"%s" is not a valid revision suffix brace component`, lit)}
+ case tok == eof:
+ return nil, &ErrInvalidRevision{s: `missing "}" in ^{} structure`}
+ case tok != cbrace:
+ p.unscan()
+ re += lit
+ case tok == cbrace:
+ p.unscan()
+
+ reg, err := regexp.Compile(re)
+
+ if err != nil {
+ return CaretReg{}, &ErrInvalidRevision{fmt.Sprintf(`revision suffix brace component, %s`, err.Error())}
+ }
+
+ return CaretReg{reg, negate}, nil
+ }
+
+ start = false
+ }
+}
+
+// parseColon extract : statements
+func (p *Parser) parseColon() (Revisioner, error) {
+ var tok token
+ var err error
+
+ tok, _, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch tok {
+ case slash:
+ return p.parseColonSlash()
+ default:
+ p.unscan()
+ return p.parseColonDefault()
+ }
+}
+
+// parseColonSlash extract :/ statements
+func (p *Parser) parseColonSlash() (Revisioner, error) {
+ var tok, nextTok token
+ var lit string
+ var re string
+ var negate bool
+ var err error
+
+ for {
+ tok, lit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ nextTok, _, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch {
+ case tok == emark && nextTok == emark:
+ re += lit
+ case re == "" && tok == emark && nextTok == minus:
+ negate = true
+ case re == "" && tok == emark:
+ return nil, &ErrInvalidRevision{s: `revision suffix brace component sequences starting with "/!" others than those defined are reserved`}
+ case tok == eof:
+ p.unscan()
+ reg, err := regexp.Compile(re)
+
+ if err != nil {
+ return ColonReg{}, &ErrInvalidRevision{fmt.Sprintf(`revision suffix brace component, %s`, err.Error())}
+ }
+
+ return ColonReg{reg, negate}, nil
+ default:
+ p.unscan()
+ re += lit
+ }
+ }
+}
+
+// parseColonDefault extract : statements
+func (p *Parser) parseColonDefault() (Revisioner, error) {
+ var tok token
+ var lit string
+ var path string
+ var stage int
+ var err error
+ var n = -1
+
+ tok, lit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ nextTok, _, err := p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ if tok == number && nextTok == colon {
+ n, _ = strconv.Atoi(lit)
+ }
+
+ switch n {
+ case 0, 1, 2, 3:
+ stage = n
+ default:
+ path += lit
+ p.unscan()
+ }
+
+ for {
+ tok, lit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch {
+ case tok == eof && n == -1:
+ return ColonPath{path}, nil
+ case tok == eof:
+ return ColonStagePath{path, stage}, nil
+ default:
+ path += lit
+ }
+ }
+}
+
+// parseRef extract reference name
+func (p *Parser) parseRef() (Revisioner, error) {
+ var tok, prevTok token
+ var lit, buf string
+ var endOfRef bool
+ var err error
+
+ for {
+ tok, lit, err = p.scan()
+
+ if err != nil {
+ return nil, err
+ }
+
+ switch tok {
+ case eof, at, colon, tilde, caret:
+ endOfRef = true
+ }
+
+ err := p.checkRefFormat(tok, lit, prevTok, buf, endOfRef)
+
+ if err != nil {
+ return "", err
+ }
+
+ if endOfRef {
+ p.unscan()
+ return Ref(buf), nil
+ }
+
+ buf += lit
+ prevTok = tok
+ }
+}
+
+// checkRefFormat ensure reference name follow rules defined here :
+// https://git-scm.com/docs/git-check-ref-format
+func (p *Parser) checkRefFormat(token token, literal string, previousToken token, buffer string, endOfRef bool) error {
+ switch token {
+ case aslash, space, control, qmark, asterisk, obracket:
+ return &ErrInvalidRevision{fmt.Sprintf(`must not contains "%s"`, literal)}
+ }
+
+ switch {
+ case (token == dot || token == slash) && buffer == "":
+ return &ErrInvalidRevision{fmt.Sprintf(`must not start with "%s"`, literal)}
+ case previousToken == slash && endOfRef:
+ return &ErrInvalidRevision{`must not end with "/"`}
+ case previousToken == dot && endOfRef:
+ return &ErrInvalidRevision{`must not end with "."`}
+ case token == dot && previousToken == slash:
+ return &ErrInvalidRevision{`must not contains "/."`}
+ case previousToken == dot && token == dot:
+ return &ErrInvalidRevision{`must not contains ".."`}
+ case previousToken == slash && token == slash:
+ return &ErrInvalidRevision{`must not contains consecutively "/"`}
+ case (token == slash || endOfRef) && len(buffer) > 4 && buffer[len(buffer)-5:] == ".lock":
+ return &ErrInvalidRevision{"cannot end with .lock"}
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/internal/revision/scanner.go b/vendor/github.com/go-git/go-git/v5/internal/revision/scanner.go
new file mode 100644
index 00000000..c46c21b7
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/internal/revision/scanner.go
@@ -0,0 +1,117 @@
+package revision
+
+import (
+ "bufio"
+ "io"
+ "unicode"
+)
+
+// runeCategoryValidator takes a rune as input and
+// validates it belongs to a rune category
+type runeCategoryValidator func(r rune) bool
+
+// tokenizeExpression aggregates a series of runes matching check predicate into a single
+// string and provides given tokenType as token type
+func tokenizeExpression(ch rune, tokenType token, check runeCategoryValidator, r *bufio.Reader) (token, string, error) {
+ var data []rune
+ data = append(data, ch)
+
+ for {
+ c, _, err := r.ReadRune()
+
+ if c == zeroRune {
+ break
+ }
+
+ if err != nil {
+ return tokenError, "", err
+ }
+
+ if check(c) {
+ data = append(data, c)
+ } else {
+ err := r.UnreadRune()
+
+ if err != nil {
+ return tokenError, "", err
+ }
+
+ return tokenType, string(data), nil
+ }
+ }
+
+ return tokenType, string(data), nil
+}
+
+var zeroRune = rune(0)
+
+// scanner represents a lexical scanner.
+type scanner struct {
+ r *bufio.Reader
+}
+
+// newScanner returns a new instance of scanner.
+func newScanner(r io.Reader) *scanner {
+ return &scanner{r: bufio.NewReader(r)}
+}
+
+// Scan extracts tokens and their strings counterpart
+// from the reader
+func (s *scanner) scan() (token, string, error) {
+ ch, _, err := s.r.ReadRune()
+
+ if err != nil && err != io.EOF {
+ return tokenError, "", err
+ }
+
+ switch ch {
+ case zeroRune:
+ return eof, "", nil
+ case ':':
+ return colon, string(ch), nil
+ case '~':
+ return tilde, string(ch), nil
+ case '^':
+ return caret, string(ch), nil
+ case '.':
+ return dot, string(ch), nil
+ case '/':
+ return slash, string(ch), nil
+ case '{':
+ return obrace, string(ch), nil
+ case '}':
+ return cbrace, string(ch), nil
+ case '-':
+ return minus, string(ch), nil
+ case '@':
+ return at, string(ch), nil
+ case '\\':
+ return aslash, string(ch), nil
+ case '?':
+ return qmark, string(ch), nil
+ case '*':
+ return asterisk, string(ch), nil
+ case '[':
+ return obracket, string(ch), nil
+ case '!':
+ return emark, string(ch), nil
+ }
+
+ if unicode.IsSpace(ch) {
+ return space, string(ch), nil
+ }
+
+ if unicode.IsControl(ch) {
+ return control, string(ch), nil
+ }
+
+ if unicode.IsLetter(ch) {
+ return tokenizeExpression(ch, word, unicode.IsLetter, s.r)
+ }
+
+ if unicode.IsNumber(ch) {
+ return tokenizeExpression(ch, number, unicode.IsNumber, s.r)
+ }
+
+ return tokenError, string(ch), nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/internal/revision/token.go b/vendor/github.com/go-git/go-git/v5/internal/revision/token.go
new file mode 100644
index 00000000..abc40488
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/internal/revision/token.go
@@ -0,0 +1,28 @@
+package revision
+
+// token represents a entity extracted from string parsing
+type token int
+
+const (
+ eof token = iota
+
+ aslash
+ asterisk
+ at
+ caret
+ cbrace
+ colon
+ control
+ dot
+ emark
+ minus
+ number
+ obrace
+ obracket
+ qmark
+ slash
+ space
+ tilde
+ tokenError
+ word
+)
diff --git a/vendor/github.com/go-git/go-git/v5/internal/url/url.go b/vendor/github.com/go-git/go-git/v5/internal/url/url.go
new file mode 100644
index 00000000..26624486
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/internal/url/url.go
@@ -0,0 +1,39 @@
+package url
+
+import (
+ "regexp"
+)
+
+var (
+ isSchemeRegExp = regexp.MustCompile(`^[^:]+://`)
+
+ // Ref: https://github.com/git/git/blob/master/Documentation/urls.txt#L37
+ scpLikeUrlRegExp = regexp.MustCompile(`^(?:(?P[^@]+)@)?(?P[^:\s]+):(?:(?P[0-9]{1,5}):)?(?P[^\\].*)$`)
+)
+
+// MatchesScheme returns true if the given string matches a URL-like
+// format scheme.
+func MatchesScheme(url string) bool {
+ return isSchemeRegExp.MatchString(url)
+}
+
+// MatchesScpLike returns true if the given string matches an SCP-like
+// format scheme.
+func MatchesScpLike(url string) bool {
+ return scpLikeUrlRegExp.MatchString(url)
+}
+
+// FindScpLikeComponents returns the user, host, port and path of the
+// given SCP-like URL.
+func FindScpLikeComponents(url string) (user, host, port, path string) {
+ m := scpLikeUrlRegExp.FindStringSubmatch(url)
+ return m[1], m[2], m[3], m[4]
+}
+
+// IsLocalEndpoint returns true if the given URL string specifies a
+// local file endpoint. For example, on a Linux machine,
+// `/home/user/src/go-git` would match as a local endpoint, but
+// `https://github.com/src-d/go-git` would not.
+func IsLocalEndpoint(url string) bool {
+ return !MatchesScheme(url) && !MatchesScpLike(url)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/object_walker.go b/vendor/github.com/go-git/go-git/v5/object_walker.go
new file mode 100644
index 00000000..3a537bd8
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/object_walker.go
@@ -0,0 +1,104 @@
+package git
+
+import (
+ "fmt"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/storage"
+)
+
+type objectWalker struct {
+ Storer storage.Storer
+ // seen is the set of objects seen in the repo.
+ // seen map can become huge if walking over large
+ // repos. Thus using struct{} as the value type.
+ seen map[plumbing.Hash]struct{}
+}
+
+func newObjectWalker(s storage.Storer) *objectWalker {
+ return &objectWalker{s, map[plumbing.Hash]struct{}{}}
+}
+
+// walkAllRefs walks all (hash) references from the repo.
+func (p *objectWalker) walkAllRefs() error {
+ // Walk over all the references in the repo.
+ it, err := p.Storer.IterReferences()
+ if err != nil {
+ return err
+ }
+ defer it.Close()
+ err = it.ForEach(func(ref *plumbing.Reference) error {
+ // Exit this iteration early for non-hash references.
+ if ref.Type() != plumbing.HashReference {
+ return nil
+ }
+ return p.walkObjectTree(ref.Hash())
+ })
+ return err
+}
+
+func (p *objectWalker) isSeen(hash plumbing.Hash) bool {
+ _, seen := p.seen[hash]
+ return seen
+}
+
+func (p *objectWalker) add(hash plumbing.Hash) {
+ p.seen[hash] = struct{}{}
+}
+
+// walkObjectTree walks over all objects and remembers references
+// to them in the objectWalker. This is used instead of the revlist
+// walks because memory usage is tight with huge repos.
+func (p *objectWalker) walkObjectTree(hash plumbing.Hash) error {
+ // Check if we have already seen, and mark this object
+ if p.isSeen(hash) {
+ return nil
+ }
+ p.add(hash)
+ // Fetch the object.
+ obj, err := object.GetObject(p.Storer, hash)
+ if err != nil {
+ return fmt.Errorf("getting object %s failed: %v", hash, err)
+ }
+ // Walk all children depending on object type.
+ switch obj := obj.(type) {
+ case *object.Commit:
+ err = p.walkObjectTree(obj.TreeHash)
+ if err != nil {
+ return err
+ }
+ for _, h := range obj.ParentHashes {
+ err = p.walkObjectTree(h)
+ if err != nil {
+ return err
+ }
+ }
+ case *object.Tree:
+ for i := range obj.Entries {
+ // Shortcut for blob objects:
+ // 'or' the lower bits of a mode and check that it
+ // it matches a filemode.Executable. The type information
+ // is in the higher bits, but this is the cleanest way
+ // to handle plain files with different modes.
+ // Other non-tree objects are somewhat rare, so they
+ // are not special-cased.
+ if obj.Entries[i].Mode|0755 == filemode.Executable {
+ p.add(obj.Entries[i].Hash)
+ continue
+ }
+ // Normal walk for sub-trees (and symlinks etc).
+ err = p.walkObjectTree(obj.Entries[i].Hash)
+ if err != nil {
+ return err
+ }
+ }
+ case *object.Tag:
+ return p.walkObjectTree(obj.Target)
+ default:
+ // Error out on unhandled object types.
+ return fmt.Errorf("unknown object %X %s %T", obj.ID(), obj.Type(), obj)
+ }
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/options.go b/vendor/github.com/go-git/go-git/v5/options.go
new file mode 100644
index 00000000..d7776dad
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/options.go
@@ -0,0 +1,792 @@
+package git
+
+import (
+ "errors"
+ "fmt"
+ "regexp"
+ "strings"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp"
+ "github.com/go-git/go-git/v5/config"
+ "github.com/go-git/go-git/v5/plumbing"
+ formatcfg "github.com/go-git/go-git/v5/plumbing/format/config"
+ "github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+)
+
+// SubmoduleRescursivity defines how depth will affect any submodule recursive
+// operation.
+type SubmoduleRescursivity uint
+
+const (
+ // DefaultRemoteName name of the default Remote, just like git command.
+ DefaultRemoteName = "origin"
+
+ // NoRecurseSubmodules disables the recursion for a submodule operation.
+ NoRecurseSubmodules SubmoduleRescursivity = 0
+ // DefaultSubmoduleRecursionDepth allow recursion in a submodule operation.
+ DefaultSubmoduleRecursionDepth SubmoduleRescursivity = 10
+)
+
+var (
+ ErrMissingURL = errors.New("URL field is required")
+)
+
+// CloneOptions describes how a clone should be performed.
+type CloneOptions struct {
+ // The (possibly remote) repository URL to clone from.
+ URL string
+ // Auth credentials, if required, to use with the remote repository.
+ Auth transport.AuthMethod
+ // Name of the remote to be added, by default `origin`.
+ RemoteName string
+ // Remote branch to clone.
+ ReferenceName plumbing.ReferenceName
+ // Fetch only ReferenceName if true.
+ SingleBranch bool
+ // Mirror clones the repository as a mirror.
+ //
+ // Compared to a bare clone, mirror not only maps local branches of the
+ // source to local branches of the target, it maps all refs (including
+ // remote-tracking branches, notes etc.) and sets up a refspec configuration
+ // such that all these refs are overwritten by a git remote update in the
+ // target repository.
+ Mirror bool
+ // No checkout of HEAD after clone if true.
+ NoCheckout bool
+ // Limit fetching to the specified number of commits.
+ Depth int
+ // RecurseSubmodules after the clone is created, initialize all submodules
+ // within, using their default settings. This option is ignored if the
+ // cloned repository does not have a worktree.
+ RecurseSubmodules SubmoduleRescursivity
+ // ShallowSubmodules limit cloning submodules to the 1 level of depth.
+ // It matches the git command --shallow-submodules.
+ ShallowSubmodules bool
+ // Progress is where the human readable information sent by the server is
+ // stored, if nil nothing is stored and the capability (if supported)
+ // no-progress, is sent to the server to avoid send this information.
+ Progress sideband.Progress
+ // Tags describe how the tags will be fetched from the remote repository,
+ // by default is AllTags.
+ Tags TagMode
+ // InsecureSkipTLS skips ssl verify if protocol is https
+ InsecureSkipTLS bool
+ // CABundle specify additional ca bundle with system cert pool
+ CABundle []byte
+ // ProxyOptions provides info required for connecting to a proxy.
+ ProxyOptions transport.ProxyOptions
+ // When the repository to clone is on the local machine, instead of
+ // using hard links, automatically setup .git/objects/info/alternates
+ // to share the objects with the source repository.
+ // The resulting repository starts out without any object of its own.
+ // NOTE: this is a possibly dangerous operation; do not use it unless
+ // you understand what it does.
+ //
+ // [Reference]: https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---shared
+ Shared bool
+}
+
+// MergeOptions describes how a merge should be performed.
+type MergeOptions struct {
+ // Strategy defines the merge strategy to be used.
+ Strategy MergeStrategy
+}
+
+// MergeStrategy represents the different types of merge strategies.
+type MergeStrategy int8
+
+const (
+ // FastForwardMerge represents a Git merge strategy where the current
+ // branch can be simply updated to point to the HEAD of the branch being
+ // merged. This is only possible if the history of the branch being merged
+ // is a linear descendant of the current branch, with no conflicting commits.
+ //
+ // This is the default option.
+ FastForwardMerge MergeStrategy = iota
+)
+
+// Validate validates the fields and sets the default values.
+func (o *CloneOptions) Validate() error {
+ if o.URL == "" {
+ return ErrMissingURL
+ }
+
+ if o.RemoteName == "" {
+ o.RemoteName = DefaultRemoteName
+ }
+
+ if o.ReferenceName == "" {
+ o.ReferenceName = plumbing.HEAD
+ }
+
+ if o.Tags == InvalidTagMode {
+ o.Tags = AllTags
+ }
+
+ return nil
+}
+
+// PullOptions describes how a pull should be performed.
+type PullOptions struct {
+ // Name of the remote to be pulled. If empty, uses the default.
+ RemoteName string
+ // RemoteURL overrides the remote repo address with a custom URL
+ RemoteURL string
+ // Remote branch to clone. If empty, uses HEAD.
+ ReferenceName plumbing.ReferenceName
+ // Fetch only ReferenceName if true.
+ SingleBranch bool
+ // Limit fetching to the specified number of commits.
+ Depth int
+ // Auth credentials, if required, to use with the remote repository.
+ Auth transport.AuthMethod
+ // RecurseSubmodules controls if new commits of all populated submodules
+ // should be fetched too.
+ RecurseSubmodules SubmoduleRescursivity
+ // Progress is where the human readable information sent by the server is
+ // stored, if nil nothing is stored and the capability (if supported)
+ // no-progress, is sent to the server to avoid send this information.
+ Progress sideband.Progress
+ // Force allows the pull to update a local branch even when the remote
+ // branch does not descend from it.
+ Force bool
+ // InsecureSkipTLS skips ssl verify if protocol is https
+ InsecureSkipTLS bool
+ // CABundle specify additional ca bundle with system cert pool
+ CABundle []byte
+ // ProxyOptions provides info required for connecting to a proxy.
+ ProxyOptions transport.ProxyOptions
+}
+
+// Validate validates the fields and sets the default values.
+func (o *PullOptions) Validate() error {
+ if o.RemoteName == "" {
+ o.RemoteName = DefaultRemoteName
+ }
+
+ if o.ReferenceName == "" {
+ o.ReferenceName = plumbing.HEAD
+ }
+
+ return nil
+}
+
+type TagMode int
+
+const (
+ InvalidTagMode TagMode = iota
+ // TagFollowing any tag that points into the histories being fetched is also
+ // fetched. TagFollowing requires a server with `include-tag` capability
+ // in order to fetch the annotated tags objects.
+ TagFollowing
+ // AllTags fetch all tags from the remote (i.e., fetch remote tags
+ // refs/tags/* into local tags with the same name)
+ AllTags
+ // NoTags fetch no tags from the remote at all
+ NoTags
+)
+
+// FetchOptions describes how a fetch should be performed
+type FetchOptions struct {
+ // Name of the remote to fetch from. Defaults to origin.
+ RemoteName string
+ // RemoteURL overrides the remote repo address with a custom URL
+ RemoteURL string
+ RefSpecs []config.RefSpec
+ // Depth limit fetching to the specified number of commits from the tip of
+ // each remote branch history.
+ Depth int
+ // Auth credentials, if required, to use with the remote repository.
+ Auth transport.AuthMethod
+ // Progress is where the human readable information sent by the server is
+ // stored, if nil nothing is stored and the capability (if supported)
+ // no-progress, is sent to the server to avoid send this information.
+ Progress sideband.Progress
+ // Tags describe how the tags will be fetched from the remote repository,
+ // by default is TagFollowing.
+ Tags TagMode
+ // Force allows the fetch to update a local branch even when the remote
+ // branch does not descend from it.
+ Force bool
+ // InsecureSkipTLS skips ssl verify if protocol is https
+ InsecureSkipTLS bool
+ // CABundle specify additional ca bundle with system cert pool
+ CABundle []byte
+ // ProxyOptions provides info required for connecting to a proxy.
+ ProxyOptions transport.ProxyOptions
+ // Prune specify that local refs that match given RefSpecs and that do
+ // not exist remotely will be removed.
+ Prune bool
+}
+
+// Validate validates the fields and sets the default values.
+func (o *FetchOptions) Validate() error {
+ if o.RemoteName == "" {
+ o.RemoteName = DefaultRemoteName
+ }
+
+ if o.Tags == InvalidTagMode {
+ o.Tags = TagFollowing
+ }
+
+ for _, r := range o.RefSpecs {
+ if err := r.Validate(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// PushOptions describes how a push should be performed.
+type PushOptions struct {
+ // RemoteName is the name of the remote to be pushed to.
+ RemoteName string
+ // RemoteURL overrides the remote repo address with a custom URL
+ RemoteURL string
+ // RefSpecs specify what destination ref to update with what source object.
+ //
+ // The format of a parameter is an optional plus +, followed by
+ // the source object , followed by a colon :, followed by the destination ref .
+ // The is often the name of the branch you would want to push, but it can be a SHA-1.
+ // The tells which ref on the remote side is updated with this push.
+ //
+ // A refspec with empty src can be used to delete a reference.
+ RefSpecs []config.RefSpec
+ // Auth credentials, if required, to use with the remote repository.
+ Auth transport.AuthMethod
+ // Progress is where the human readable information sent by the server is
+ // stored, if nil nothing is stored.
+ Progress sideband.Progress
+ // Prune specify that remote refs that match given RefSpecs and that do
+ // not exist locally will be removed.
+ Prune bool
+ // Force allows the push to update a remote branch even when the local
+ // branch does not descend from it.
+ Force bool
+ // InsecureSkipTLS skips ssl verify if protocol is https
+ InsecureSkipTLS bool
+ // CABundle specify additional ca bundle with system cert pool
+ CABundle []byte
+ // RequireRemoteRefs only allows a remote ref to be updated if its current
+ // value is the one specified here.
+ RequireRemoteRefs []config.RefSpec
+ // FollowTags will send any annotated tags with a commit target reachable from
+ // the refs already being pushed
+ FollowTags bool
+ // ForceWithLease allows a force push as long as the remote ref adheres to a "lease"
+ ForceWithLease *ForceWithLease
+ // PushOptions sets options to be transferred to the server during push.
+ Options map[string]string
+ // Atomic sets option to be an atomic push
+ Atomic bool
+ // ProxyOptions provides info required for connecting to a proxy.
+ ProxyOptions transport.ProxyOptions
+}
+
+// ForceWithLease sets fields on the lease
+// If neither RefName nor Hash are set, ForceWithLease protects
+// all refs in the refspec by ensuring the ref of the remote in the local repsitory
+// matches the one in the ref advertisement.
+type ForceWithLease struct {
+ // RefName, when set will protect the ref by ensuring it matches the
+ // hash in the ref advertisement.
+ RefName plumbing.ReferenceName
+ // Hash is the expected object id of RefName. The push will be rejected unless this
+ // matches the corresponding object id of RefName in the refs advertisement.
+ Hash plumbing.Hash
+}
+
+// Validate validates the fields and sets the default values.
+func (o *PushOptions) Validate() error {
+ if o.RemoteName == "" {
+ o.RemoteName = DefaultRemoteName
+ }
+
+ if len(o.RefSpecs) == 0 {
+ o.RefSpecs = []config.RefSpec{
+ config.RefSpec(config.DefaultPushRefSpec),
+ }
+ }
+
+ for _, r := range o.RefSpecs {
+ if err := r.Validate(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// SubmoduleUpdateOptions describes how a submodule update should be performed.
+type SubmoduleUpdateOptions struct {
+ // Init, if true initializes the submodules recorded in the index.
+ Init bool
+ // NoFetch tell to the update command to not fetch new objects from the
+ // remote site.
+ NoFetch bool
+ // RecurseSubmodules the update is performed not only in the submodules of
+ // the current repository but also in any nested submodules inside those
+ // submodules (and so on). Until the SubmoduleRescursivity is reached.
+ RecurseSubmodules SubmoduleRescursivity
+ // Auth credentials, if required, to use with the remote repository.
+ Auth transport.AuthMethod
+ // Depth limit fetching to the specified number of commits from the tip of
+ // each remote branch history.
+ Depth int
+}
+
+var (
+ ErrBranchHashExclusive = errors.New("Branch and Hash are mutually exclusive")
+ ErrCreateRequiresBranch = errors.New("Branch is mandatory when Create is used")
+)
+
+// CheckoutOptions describes how a checkout operation should be performed.
+type CheckoutOptions struct {
+ // Hash is the hash of a commit or tag to be checked out. If used, HEAD
+ // will be in detached mode. If Create is not used, Branch and Hash are
+ // mutually exclusive.
+ Hash plumbing.Hash
+ // Branch to be checked out, if Branch and Hash are empty is set to `master`.
+ Branch plumbing.ReferenceName
+ // Create a new branch named Branch and start it at Hash.
+ Create bool
+ // Force, if true when switching branches, proceed even if the index or the
+ // working tree differs from HEAD. This is used to throw away local changes
+ Force bool
+ // Keep, if true when switching branches, local changes (the index or the
+ // working tree changes) will be kept so that they can be committed to the
+ // target branch. Force and Keep are mutually exclusive, should not be both
+ // set to true.
+ Keep bool
+ // SparseCheckoutDirectories
+ SparseCheckoutDirectories []string
+}
+
+// Validate validates the fields and sets the default values.
+func (o *CheckoutOptions) Validate() error {
+ if !o.Create && !o.Hash.IsZero() && o.Branch != "" {
+ return ErrBranchHashExclusive
+ }
+
+ if o.Create && o.Branch == "" {
+ return ErrCreateRequiresBranch
+ }
+
+ if o.Branch == "" {
+ o.Branch = plumbing.Master
+ }
+
+ return nil
+}
+
+// ResetMode defines the mode of a reset operation.
+type ResetMode int8
+
+const (
+ // MixedReset resets the index but not the working tree (i.e., the changed
+ // files are preserved but not marked for commit) and reports what has not
+ // been updated. This is the default action.
+ MixedReset ResetMode = iota
+ // HardReset resets the index and working tree. Any changes to tracked files
+ // in the working tree are discarded.
+ HardReset
+ // MergeReset resets the index and updates the files in the working tree
+ // that are different between Commit and HEAD, but keeps those which are
+ // different between the index and working tree (i.e. which have changes
+ // which have not been added).
+ //
+ // If a file that is different between Commit and the index has unstaged
+ // changes, reset is aborted.
+ MergeReset
+ // SoftReset does not touch the index file or the working tree at all (but
+ // resets the head to , just like all modes do). This leaves all
+ // your changed files "Changes to be committed", as git status would put it.
+ SoftReset
+)
+
+// ResetOptions describes how a reset operation should be performed.
+type ResetOptions struct {
+ // Commit, if commit is present set the current branch head (HEAD) to it.
+ Commit plumbing.Hash
+ // Mode, form resets the current branch head to Commit and possibly updates
+ // the index (resetting it to the tree of Commit) and the working tree
+ // depending on Mode. If empty MixedReset is used.
+ Mode ResetMode
+}
+
+// Validate validates the fields and sets the default values.
+func (o *ResetOptions) Validate(r *Repository) error {
+ if o.Commit == plumbing.ZeroHash {
+ ref, err := r.Head()
+ if err != nil {
+ return err
+ }
+
+ o.Commit = ref.Hash()
+ } else {
+ _, err := r.CommitObject(o.Commit)
+ if err != nil {
+ return fmt.Errorf("invalid reset option: %w", err)
+ }
+ }
+
+ return nil
+}
+
+type LogOrder int8
+
+const (
+ LogOrderDefault LogOrder = iota
+ LogOrderDFS
+ LogOrderDFSPost
+ LogOrderBSF
+ LogOrderCommitterTime
+)
+
+// LogOptions describes how a log action should be performed.
+type LogOptions struct {
+ // When the From option is set the log will only contain commits
+ // reachable from it. If this option is not set, HEAD will be used as
+ // the default From.
+ From plumbing.Hash
+
+ // The default traversal algorithm is Depth-first search
+ // set Order=LogOrderCommitterTime for ordering by committer time (more compatible with `git log`)
+ // set Order=LogOrderBSF for Breadth-first search
+ Order LogOrder
+
+ // Show only those commits in which the specified file was inserted/updated.
+ // It is equivalent to running `git log -- `.
+ // this field is kept for compatibility, it can be replaced with PathFilter
+ FileName *string
+
+ // Filter commits based on the path of files that are updated
+ // takes file path as argument and should return true if the file is desired
+ // It can be used to implement `git log -- `
+ // either is a file path, or directory path, or a regexp of file/directory path
+ PathFilter func(string) bool
+
+ // Pretend as if all the refs in refs/, along with HEAD, are listed on the command line as .
+ // It is equivalent to running `git log --all`.
+ // If set on true, the From option will be ignored.
+ All bool
+
+ // Show commits more recent than a specific date.
+ // It is equivalent to running `git log --since ` or `git log --after `.
+ Since *time.Time
+
+ // Show commits older than a specific date.
+ // It is equivalent to running `git log --until ` or `git log --before `.
+ Until *time.Time
+}
+
+var (
+ ErrMissingAuthor = errors.New("author field is required")
+)
+
+// AddOptions describes how an `add` operation should be performed
+type AddOptions struct {
+ // All equivalent to `git add -A`, update the index not only where the
+ // working tree has a file matching `Path` but also where the index already
+ // has an entry. This adds, modifies, and removes index entries to match the
+ // working tree. If no `Path` nor `Glob` is given when `All` option is
+ // used, all files in the entire working tree are updated.
+ All bool
+ // Path is the exact filepath to the file or directory to be added.
+ Path string
+ // Glob adds all paths, matching pattern, to the index. If pattern matches a
+ // directory path, all directory contents are added to the index recursively.
+ Glob string
+ // SkipStatus adds the path with no status check. This option is relevant only
+ // when the `Path` option is specified and does not apply when the `All` option is used.
+ // Notice that when passing an ignored path it will be added anyway.
+ // When true it can speed up adding files to the worktree in very large repositories.
+ SkipStatus bool
+}
+
+// Validate validates the fields and sets the default values.
+func (o *AddOptions) Validate(r *Repository) error {
+ if o.Path != "" && o.Glob != "" {
+ return fmt.Errorf("fields Path and Glob are mutual exclusive")
+ }
+
+ return nil
+}
+
+// CommitOptions describes how a commit operation should be performed.
+type CommitOptions struct {
+ // All automatically stage files that have been modified and deleted, but
+ // new files you have not told Git about are not affected.
+ All bool
+ // AllowEmptyCommits enable empty commits to be created. An empty commit
+ // is when no changes to the tree were made, but a new commit message is
+ // provided. The default behavior is false, which results in ErrEmptyCommit.
+ AllowEmptyCommits bool
+ // Author is the author's signature of the commit. If Author is empty the
+ // Name and Email is read from the config, and time.Now it's used as When.
+ Author *object.Signature
+ // Committer is the committer's signature of the commit. If Committer is
+ // nil the Author signature is used.
+ Committer *object.Signature
+ // Parents are the parents commits for the new commit, by default when
+ // len(Parents) is zero, the hash of HEAD reference is used.
+ Parents []plumbing.Hash
+ // SignKey denotes a key to sign the commit with. A nil value here means the
+ // commit will not be signed. The private key must be present and already
+ // decrypted.
+ SignKey *openpgp.Entity
+ // Signer denotes a cryptographic signer to sign the commit with.
+ // A nil value here means the commit will not be signed.
+ // Takes precedence over SignKey.
+ Signer Signer
+ // Amend will create a new commit object and replace the commit that HEAD currently
+ // points to. Cannot be used with All nor Parents.
+ Amend bool
+}
+
+// Validate validates the fields and sets the default values.
+func (o *CommitOptions) Validate(r *Repository) error {
+ if o.All && o.Amend {
+ return errors.New("all and amend cannot be used together")
+ }
+
+ if o.Amend && len(o.Parents) > 0 {
+ return errors.New("parents cannot be used with amend")
+ }
+
+ if o.Author == nil {
+ if err := o.loadConfigAuthorAndCommitter(r); err != nil {
+ return err
+ }
+ }
+
+ if o.Committer == nil {
+ o.Committer = o.Author
+ }
+
+ if len(o.Parents) == 0 {
+ head, err := r.Head()
+ if err != nil && err != plumbing.ErrReferenceNotFound {
+ return err
+ }
+
+ if head != nil {
+ o.Parents = []plumbing.Hash{head.Hash()}
+ }
+ }
+
+ return nil
+}
+
+func (o *CommitOptions) loadConfigAuthorAndCommitter(r *Repository) error {
+ cfg, err := r.ConfigScoped(config.SystemScope)
+ if err != nil {
+ return err
+ }
+
+ if o.Author == nil && cfg.Author.Email != "" && cfg.Author.Name != "" {
+ o.Author = &object.Signature{
+ Name: cfg.Author.Name,
+ Email: cfg.Author.Email,
+ When: time.Now(),
+ }
+ }
+
+ if o.Committer == nil && cfg.Committer.Email != "" && cfg.Committer.Name != "" {
+ o.Committer = &object.Signature{
+ Name: cfg.Committer.Name,
+ Email: cfg.Committer.Email,
+ When: time.Now(),
+ }
+ }
+
+ if o.Author == nil && cfg.User.Email != "" && cfg.User.Name != "" {
+ o.Author = &object.Signature{
+ Name: cfg.User.Name,
+ Email: cfg.User.Email,
+ When: time.Now(),
+ }
+ }
+
+ if o.Author == nil {
+ return ErrMissingAuthor
+ }
+
+ return nil
+}
+
+var (
+ ErrMissingName = errors.New("name field is required")
+ ErrMissingTagger = errors.New("tagger field is required")
+ ErrMissingMessage = errors.New("message field is required")
+)
+
+// CreateTagOptions describes how a tag object should be created.
+type CreateTagOptions struct {
+ // Tagger defines the signature of the tag creator. If Tagger is empty the
+ // Name and Email is read from the config, and time.Now it's used as When.
+ Tagger *object.Signature
+ // Message defines the annotation of the tag. It is canonicalized during
+ // validation into the format expected by git - no leading whitespace and
+ // ending in a newline.
+ Message string
+ // SignKey denotes a key to sign the tag with. A nil value here means the tag
+ // will not be signed. The private key must be present and already decrypted.
+ SignKey *openpgp.Entity
+}
+
+// Validate validates the fields and sets the default values.
+func (o *CreateTagOptions) Validate(r *Repository, hash plumbing.Hash) error {
+ if o.Tagger == nil {
+ if err := o.loadConfigTagger(r); err != nil {
+ return err
+ }
+ }
+
+ if o.Message == "" {
+ return ErrMissingMessage
+ }
+
+ // Canonicalize the message into the expected message format.
+ o.Message = strings.TrimSpace(o.Message) + "\n"
+
+ return nil
+}
+
+func (o *CreateTagOptions) loadConfigTagger(r *Repository) error {
+ cfg, err := r.ConfigScoped(config.SystemScope)
+ if err != nil {
+ return err
+ }
+
+ if o.Tagger == nil && cfg.Author.Email != "" && cfg.Author.Name != "" {
+ o.Tagger = &object.Signature{
+ Name: cfg.Author.Name,
+ Email: cfg.Author.Email,
+ When: time.Now(),
+ }
+ }
+
+ if o.Tagger == nil && cfg.User.Email != "" && cfg.User.Name != "" {
+ o.Tagger = &object.Signature{
+ Name: cfg.User.Name,
+ Email: cfg.User.Email,
+ When: time.Now(),
+ }
+ }
+
+ if o.Tagger == nil {
+ return ErrMissingTagger
+ }
+
+ return nil
+}
+
+// ListOptions describes how a remote list should be performed.
+type ListOptions struct {
+ // Auth credentials, if required, to use with the remote repository.
+ Auth transport.AuthMethod
+ // InsecureSkipTLS skips ssl verify if protocol is https
+ InsecureSkipTLS bool
+ // CABundle specify additional ca bundle with system cert pool
+ CABundle []byte
+ // PeelingOption defines how peeled objects are handled during a
+ // remote list.
+ PeelingOption PeelingOption
+ // ProxyOptions provides info required for connecting to a proxy.
+ ProxyOptions transport.ProxyOptions
+ // Timeout specifies the timeout in seconds for list operations
+ Timeout int
+}
+
+// PeelingOption represents the different ways to handle peeled references.
+//
+// Peeled references represent the underlying object of an annotated
+// (or signed) tag. Refer to upstream documentation for more info:
+// https://github.com/git/git/blob/master/Documentation/technical/reftable.txt
+type PeelingOption uint8
+
+const (
+ // IgnorePeeled ignores all peeled reference names. This is the default behavior.
+ IgnorePeeled PeelingOption = 0
+ // OnlyPeeled returns only peeled reference names.
+ OnlyPeeled PeelingOption = 1
+ // AppendPeeled appends peeled reference names to the reference list.
+ AppendPeeled PeelingOption = 2
+)
+
+// CleanOptions describes how a clean should be performed.
+type CleanOptions struct {
+ Dir bool
+}
+
+// GrepOptions describes how a grep should be performed.
+type GrepOptions struct {
+ // Patterns are compiled Regexp objects to be matched.
+ Patterns []*regexp.Regexp
+ // InvertMatch selects non-matching lines.
+ InvertMatch bool
+ // CommitHash is the hash of the commit from which worktree should be derived.
+ CommitHash plumbing.Hash
+ // ReferenceName is the branch or tag name from which worktree should be derived.
+ ReferenceName plumbing.ReferenceName
+ // PathSpecs are compiled Regexp objects of pathspec to use in the matching.
+ PathSpecs []*regexp.Regexp
+}
+
+var (
+ ErrHashOrReference = errors.New("ambiguous options, only one of CommitHash or ReferenceName can be passed")
+)
+
+// Validate validates the fields and sets the default values.
+//
+// TODO: deprecate in favor of Validate(r *Repository) in v6.
+func (o *GrepOptions) Validate(w *Worktree) error {
+ return o.validate(w.r)
+}
+
+func (o *GrepOptions) validate(r *Repository) error {
+ if !o.CommitHash.IsZero() && o.ReferenceName != "" {
+ return ErrHashOrReference
+ }
+
+ // If none of CommitHash and ReferenceName are provided, set commit hash of
+ // the repository's head.
+ if o.CommitHash.IsZero() && o.ReferenceName == "" {
+ ref, err := r.Head()
+ if err != nil {
+ return err
+ }
+ o.CommitHash = ref.Hash()
+ }
+
+ return nil
+}
+
+// PlainOpenOptions describes how opening a plain repository should be
+// performed.
+type PlainOpenOptions struct {
+ // DetectDotGit defines whether parent directories should be
+ // walked until a .git directory or file is found.
+ DetectDotGit bool
+ // Enable .git/commondir support (see https://git-scm.com/docs/gitrepository-layout#Documentation/gitrepository-layout.txt).
+ // NOTE: This option will only work with the filesystem storage.
+ EnableDotGitCommonDir bool
+}
+
+// Validate validates the fields and sets the default values.
+func (o *PlainOpenOptions) Validate() error { return nil }
+
+type PlainInitOptions struct {
+ InitOptions
+ // Determines if the repository will have a worktree (non-bare) or not (bare).
+ Bare bool
+ ObjectFormat formatcfg.ObjectFormat
+}
+
+// Validate validates the fields and sets the default values.
+func (o *PlainInitOptions) Validate() error { return nil }
diff --git a/vendor/github.com/go-git/go-git/v5/oss-fuzz.sh b/vendor/github.com/go-git/go-git/v5/oss-fuzz.sh
new file mode 100644
index 00000000..885548f4
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/oss-fuzz.sh
@@ -0,0 +1,35 @@
+#!/bin/bash -eu
+# Copyright 2023 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+
+go mod download
+go get github.com/AdamKorcz/go-118-fuzz-build/testing
+
+if [ "$SANITIZER" != "coverage" ]; then
+ sed -i '/func (s \*DecoderSuite) TestDecode(/,/^}/ s/^/\/\//' plumbing/format/config/decoder_test.go
+ sed -n '35,$p' plumbing/format/packfile/common_test.go >> plumbing/format/packfile/delta_test.go
+ sed -n '20,53p' plumbing/object/object_test.go >> plumbing/object/tree_test.go
+ sed -i 's|func Test|// func Test|' plumbing/transport/common_test.go
+fi
+
+compile_native_go_fuzzer $(pwd)/internal/revision FuzzParser fuzz_parser
+compile_native_go_fuzzer $(pwd)/plumbing/format/config FuzzDecoder fuzz_decoder_config
+compile_native_go_fuzzer $(pwd)/plumbing/format/packfile FuzzPatchDelta fuzz_patch_delta
+compile_native_go_fuzzer $(pwd)/plumbing/object FuzzParseSignedBytes fuzz_parse_signed_bytes
+compile_native_go_fuzzer $(pwd)/plumbing/object FuzzDecode fuzz_decode
+compile_native_go_fuzzer $(pwd)/plumbing/protocol/packp FuzzDecoder fuzz_decoder_packp
+compile_native_go_fuzzer $(pwd)/plumbing/transport FuzzNewEndpoint fuzz_new_endpoint
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/cache/buffer_lru.go b/vendor/github.com/go-git/go-git/v5/plumbing/cache/buffer_lru.go
new file mode 100644
index 00000000..acaf1952
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/cache/buffer_lru.go
@@ -0,0 +1,98 @@
+package cache
+
+import (
+ "container/list"
+ "sync"
+)
+
+// BufferLRU implements an object cache with an LRU eviction policy and a
+// maximum size (measured in object size).
+type BufferLRU struct {
+ MaxSize FileSize
+
+ actualSize FileSize
+ ll *list.List
+ cache map[int64]*list.Element
+ mut sync.Mutex
+}
+
+// NewBufferLRU creates a new BufferLRU with the given maximum size. The maximum
+// size will never be exceeded.
+func NewBufferLRU(maxSize FileSize) *BufferLRU {
+ return &BufferLRU{MaxSize: maxSize}
+}
+
+// NewBufferLRUDefault creates a new BufferLRU with the default cache size.
+func NewBufferLRUDefault() *BufferLRU {
+ return &BufferLRU{MaxSize: DefaultMaxSize}
+}
+
+type buffer struct {
+ Key int64
+ Slice []byte
+}
+
+// Put puts a buffer into the cache. If the buffer is already in the cache, it
+// will be marked as used. Otherwise, it will be inserted. A buffers might
+// be evicted to make room for the new one.
+func (c *BufferLRU) Put(key int64, slice []byte) {
+ c.mut.Lock()
+ defer c.mut.Unlock()
+
+ if c.cache == nil {
+ c.actualSize = 0
+ c.cache = make(map[int64]*list.Element, 1000)
+ c.ll = list.New()
+ }
+
+ bufSize := FileSize(len(slice))
+ if ee, ok := c.cache[key]; ok {
+ oldBuf := ee.Value.(buffer)
+ // in this case bufSize is a delta: new size - old size
+ bufSize -= FileSize(len(oldBuf.Slice))
+ c.ll.MoveToFront(ee)
+ ee.Value = buffer{key, slice}
+ } else {
+ if bufSize > c.MaxSize {
+ return
+ }
+ ee := c.ll.PushFront(buffer{key, slice})
+ c.cache[key] = ee
+ }
+
+ c.actualSize += bufSize
+ for c.actualSize > c.MaxSize {
+ last := c.ll.Back()
+ lastObj := last.Value.(buffer)
+ lastSize := FileSize(len(lastObj.Slice))
+
+ c.ll.Remove(last)
+ delete(c.cache, lastObj.Key)
+ c.actualSize -= lastSize
+ }
+}
+
+// Get returns a buffer by its key. It marks the buffer as used. If the buffer
+// is not in the cache, (nil, false) will be returned.
+func (c *BufferLRU) Get(key int64) ([]byte, bool) {
+ c.mut.Lock()
+ defer c.mut.Unlock()
+
+ ee, ok := c.cache[key]
+ if !ok {
+ return nil, false
+ }
+
+ c.ll.MoveToFront(ee)
+ return ee.Value.(buffer).Slice, true
+}
+
+// Clear the content of this buffer cache.
+func (c *BufferLRU) Clear() {
+ c.mut.Lock()
+ defer c.mut.Unlock()
+
+ c.ll = nil
+ c.cache = nil
+ c.actualSize = 0
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/cache/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/cache/common.go
new file mode 100644
index 00000000..7b0d0c76
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/cache/common.go
@@ -0,0 +1,39 @@
+package cache
+
+import "github.com/go-git/go-git/v5/plumbing"
+
+const (
+ Byte FileSize = 1 << (iota * 10)
+ KiByte
+ MiByte
+ GiByte
+)
+
+type FileSize int64
+
+const DefaultMaxSize FileSize = 96 * MiByte
+
+// Object is an interface to a object cache.
+type Object interface {
+ // Put puts the given object into the cache. Whether this object will
+ // actually be put into the cache or not is implementation specific.
+ Put(o plumbing.EncodedObject)
+ // Get gets an object from the cache given its hash. The second return value
+ // is true if the object was returned, and false otherwise.
+ Get(k plumbing.Hash) (plumbing.EncodedObject, bool)
+ // Clear clears every object from the cache.
+ Clear()
+}
+
+// Buffer is an interface to a buffer cache.
+type Buffer interface {
+ // Put puts a buffer into the cache. If the buffer is already in the cache,
+ // it will be marked as used. Otherwise, it will be inserted. Buffer might
+ // be evicted to make room for the new one.
+ Put(key int64, slice []byte)
+ // Get returns a buffer by its key. It marks the buffer as used. If the
+ // buffer is not in the cache, (nil, false) will be returned.
+ Get(key int64) ([]byte, bool)
+ // Clear clears every object from the cache.
+ Clear()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/cache/object_lru.go b/vendor/github.com/go-git/go-git/v5/plumbing/cache/object_lru.go
new file mode 100644
index 00000000..c50d0d1e
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/cache/object_lru.go
@@ -0,0 +1,101 @@
+package cache
+
+import (
+ "container/list"
+ "sync"
+
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+// ObjectLRU implements an object cache with an LRU eviction policy and a
+// maximum size (measured in object size).
+type ObjectLRU struct {
+ MaxSize FileSize
+
+ actualSize FileSize
+ ll *list.List
+ cache map[interface{}]*list.Element
+ mut sync.Mutex
+}
+
+// NewObjectLRU creates a new ObjectLRU with the given maximum size. The maximum
+// size will never be exceeded.
+func NewObjectLRU(maxSize FileSize) *ObjectLRU {
+ return &ObjectLRU{MaxSize: maxSize}
+}
+
+// NewObjectLRUDefault creates a new ObjectLRU with the default cache size.
+func NewObjectLRUDefault() *ObjectLRU {
+ return &ObjectLRU{MaxSize: DefaultMaxSize}
+}
+
+// Put puts an object into the cache. If the object is already in the cache, it
+// will be marked as used. Otherwise, it will be inserted. A single object might
+// be evicted to make room for the new object.
+func (c *ObjectLRU) Put(obj plumbing.EncodedObject) {
+ c.mut.Lock()
+ defer c.mut.Unlock()
+
+ if c.cache == nil {
+ c.actualSize = 0
+ c.cache = make(map[interface{}]*list.Element, 1000)
+ c.ll = list.New()
+ }
+
+ objSize := FileSize(obj.Size())
+ key := obj.Hash()
+ if ee, ok := c.cache[key]; ok {
+ oldObj := ee.Value.(plumbing.EncodedObject)
+ // in this case objSize is a delta: new size - old size
+ objSize -= FileSize(oldObj.Size())
+ c.ll.MoveToFront(ee)
+ ee.Value = obj
+ } else {
+ if objSize > c.MaxSize {
+ return
+ }
+ ee := c.ll.PushFront(obj)
+ c.cache[key] = ee
+ }
+
+ c.actualSize += objSize
+ for c.actualSize > c.MaxSize {
+ last := c.ll.Back()
+ if last == nil {
+ c.actualSize = 0
+ break
+ }
+
+ lastObj := last.Value.(plumbing.EncodedObject)
+ lastSize := FileSize(lastObj.Size())
+
+ c.ll.Remove(last)
+ delete(c.cache, lastObj.Hash())
+ c.actualSize -= lastSize
+ }
+}
+
+// Get returns an object by its hash. It marks the object as used. If the object
+// is not in the cache, (nil, false) will be returned.
+func (c *ObjectLRU) Get(k plumbing.Hash) (plumbing.EncodedObject, bool) {
+ c.mut.Lock()
+ defer c.mut.Unlock()
+
+ ee, ok := c.cache[k]
+ if !ok {
+ return nil, false
+ }
+
+ c.ll.MoveToFront(ee)
+ return ee.Value.(plumbing.EncodedObject), true
+}
+
+// Clear the content of this object cache.
+func (c *ObjectLRU) Clear() {
+ c.mut.Lock()
+ defer c.mut.Unlock()
+
+ c.ll = nil
+ c.cache = nil
+ c.actualSize = 0
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/color/color.go b/vendor/github.com/go-git/go-git/v5/plumbing/color/color.go
new file mode 100644
index 00000000..2cd74bdc
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/color/color.go
@@ -0,0 +1,38 @@
+package color
+
+// TODO read colors from a github.com/go-git/go-git/plumbing/format/config.Config struct
+// TODO implement color parsing, see https://github.com/git/git/blob/v2.26.2/color.c
+
+// Colors. See https://github.com/git/git/blob/v2.26.2/color.h#L24-L53.
+const (
+ Normal = ""
+ Reset = "\033[m"
+ Bold = "\033[1m"
+ Red = "\033[31m"
+ Green = "\033[32m"
+ Yellow = "\033[33m"
+ Blue = "\033[34m"
+ Magenta = "\033[35m"
+ Cyan = "\033[36m"
+ BoldRed = "\033[1;31m"
+ BoldGreen = "\033[1;32m"
+ BoldYellow = "\033[1;33m"
+ BoldBlue = "\033[1;34m"
+ BoldMagenta = "\033[1;35m"
+ BoldCyan = "\033[1;36m"
+ FaintRed = "\033[2;31m"
+ FaintGreen = "\033[2;32m"
+ FaintYellow = "\033[2;33m"
+ FaintBlue = "\033[2;34m"
+ FaintMagenta = "\033[2;35m"
+ FaintCyan = "\033[2;36m"
+ BgRed = "\033[41m"
+ BgGreen = "\033[42m"
+ BgYellow = "\033[43m"
+ BgBlue = "\033[44m"
+ BgMagenta = "\033[45m"
+ BgCyan = "\033[46m"
+ Faint = "\033[2m"
+ FaintItalic = "\033[2;3m"
+ Reverse = "\033[7m"
+)
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/error.go b/vendor/github.com/go-git/go-git/v5/plumbing/error.go
new file mode 100644
index 00000000..a3ebed3f
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/error.go
@@ -0,0 +1,35 @@
+package plumbing
+
+import "fmt"
+
+type PermanentError struct {
+ Err error
+}
+
+func NewPermanentError(err error) *PermanentError {
+ if err == nil {
+ return nil
+ }
+
+ return &PermanentError{Err: err}
+}
+
+func (e *PermanentError) Error() string {
+ return fmt.Sprintf("permanent client error: %s", e.Err.Error())
+}
+
+type UnexpectedError struct {
+ Err error
+}
+
+func NewUnexpectedError(err error) *UnexpectedError {
+ if err == nil {
+ return nil
+ }
+
+ return &UnexpectedError{Err: err}
+}
+
+func (e *UnexpectedError) Error() string {
+ return fmt.Sprintf("unexpected client error: %s", e.Err.Error())
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/filemode/filemode.go b/vendor/github.com/go-git/go-git/v5/plumbing/filemode/filemode.go
new file mode 100644
index 00000000..ea1a4575
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/filemode/filemode.go
@@ -0,0 +1,188 @@
+package filemode
+
+import (
+ "encoding/binary"
+ "fmt"
+ "os"
+ "strconv"
+)
+
+// A FileMode represents the kind of tree entries used by git. It
+// resembles regular file systems modes, although FileModes are
+// considerably simpler (there are not so many), and there are some,
+// like Submodule that has no file system equivalent.
+type FileMode uint32
+
+const (
+ // Empty is used as the FileMode of tree elements when comparing
+ // trees in the following situations:
+ //
+ // - the mode of tree elements before their creation. - the mode of
+ // tree elements after their deletion. - the mode of unmerged
+ // elements when checking the index.
+ //
+ // Empty has no file system equivalent. As Empty is the zero value
+ // of FileMode, it is also returned by New and
+ // NewFromOsNewFromOSFileMode along with an error, when they fail.
+ Empty FileMode = 0
+ // Dir represent a Directory.
+ Dir FileMode = 0040000
+ // Regular represent non-executable files. Please note this is not
+ // the same as golang regular files, which include executable files.
+ Regular FileMode = 0100644
+ // Deprecated represent non-executable files with the group writable
+ // bit set. This mode was supported by the first versions of git,
+ // but it has been deprecated nowadays. This library uses them
+ // internally, so you can read old packfiles, but will treat them as
+ // Regulars when interfacing with the outside world. This is the
+ // standard git behaviour.
+ Deprecated FileMode = 0100664
+ // Executable represents executable files.
+ Executable FileMode = 0100755
+ // Symlink represents symbolic links to files.
+ Symlink FileMode = 0120000
+ // Submodule represents git submodules. This mode has no file system
+ // equivalent.
+ Submodule FileMode = 0160000
+)
+
+// New takes the octal string representation of a FileMode and returns
+// the FileMode and a nil error. If the string can not be parsed to a
+// 32 bit unsigned octal number, it returns Empty and the parsing error.
+//
+// Example: "40000" means Dir, "100644" means Regular.
+//
+// Please note this function does not check if the returned FileMode
+// is valid in git or if it is malformed. For instance, "1" will
+// return the malformed FileMode(1) and a nil error.
+func New(s string) (FileMode, error) {
+ n, err := strconv.ParseUint(s, 8, 32)
+ if err != nil {
+ return Empty, err
+ }
+
+ return FileMode(n), nil
+}
+
+// NewFromOSFileMode returns the FileMode used by git to represent
+// the provided file system modes and a nil error on success. If the
+// file system mode cannot be mapped to any valid git mode (as with
+// sockets or named pipes), it will return Empty and an error.
+//
+// Note that some git modes cannot be generated from os.FileModes, like
+// Deprecated and Submodule; while Empty will be returned, along with an
+// error, only when the method fails.
+func NewFromOSFileMode(m os.FileMode) (FileMode, error) {
+ if m.IsRegular() {
+ if isSetTemporary(m) {
+ return Empty, fmt.Errorf("no equivalent git mode for %s", m)
+ }
+ if isSetCharDevice(m) {
+ return Empty, fmt.Errorf("no equivalent git mode for %s", m)
+ }
+ if isSetUserExecutable(m) {
+ return Executable, nil
+ }
+ return Regular, nil
+ }
+
+ if m.IsDir() {
+ return Dir, nil
+ }
+
+ if isSetSymLink(m) {
+ return Symlink, nil
+ }
+
+ return Empty, fmt.Errorf("no equivalent git mode for %s", m)
+}
+
+func isSetCharDevice(m os.FileMode) bool {
+ return m&os.ModeCharDevice != 0
+}
+
+func isSetTemporary(m os.FileMode) bool {
+ return m&os.ModeTemporary != 0
+}
+
+func isSetUserExecutable(m os.FileMode) bool {
+ return m&0100 != 0
+}
+
+func isSetSymLink(m os.FileMode) bool {
+ return m&os.ModeSymlink != 0
+}
+
+// Bytes return a slice of 4 bytes with the mode in little endian
+// encoding.
+func (m FileMode) Bytes() []byte {
+ ret := make([]byte, 4)
+ binary.LittleEndian.PutUint32(ret, uint32(m))
+ return ret
+}
+
+// IsMalformed returns if the FileMode should not appear in a git packfile,
+// this is: Empty and any other mode not mentioned as a constant in this
+// package.
+func (m FileMode) IsMalformed() bool {
+ return m != Dir &&
+ m != Regular &&
+ m != Deprecated &&
+ m != Executable &&
+ m != Symlink &&
+ m != Submodule
+}
+
+// String returns the FileMode as a string in the standard git format,
+// this is, an octal number padded with ceros to 7 digits. Malformed
+// modes are printed in that same format, for easier debugging.
+//
+// Example: Regular is "0100644", Empty is "0000000".
+func (m FileMode) String() string {
+ return fmt.Sprintf("%07o", uint32(m))
+}
+
+// IsRegular returns if the FileMode represents that of a regular file,
+// this is, either Regular or Deprecated. Please note that Executable
+// are not regular even though in the UNIX tradition, they usually are:
+// See the IsFile method.
+func (m FileMode) IsRegular() bool {
+ return m == Regular ||
+ m == Deprecated
+}
+
+// IsFile returns if the FileMode represents that of a file, this is,
+// Regular, Deprecated, Executable or Link.
+func (m FileMode) IsFile() bool {
+ return m == Regular ||
+ m == Deprecated ||
+ m == Executable ||
+ m == Symlink
+}
+
+// ToOSFileMode returns the os.FileMode to be used when creating file
+// system elements with the given git mode and a nil error on success.
+//
+// When the provided mode cannot be mapped to a valid file system mode
+// (e.g. Submodule) it returns os.FileMode(0) and an error.
+//
+// The returned file mode does not take into account the umask.
+func (m FileMode) ToOSFileMode() (os.FileMode, error) {
+ switch m {
+ case Dir:
+ return os.ModePerm | os.ModeDir, nil
+ case Submodule:
+ return os.ModePerm | os.ModeDir, nil
+ case Regular:
+ return os.FileMode(0644), nil
+ // Deprecated is no longer allowed: treated as a Regular instead
+ case Deprecated:
+ return os.FileMode(0644), nil
+ case Executable:
+ return os.FileMode(0755), nil
+ case Symlink:
+ return os.ModePerm | os.ModeSymlink, nil
+ }
+
+ return os.FileMode(0), fmt.Errorf("malformed mode (%s)", m)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/common.go
new file mode 100644
index 00000000..6d689ea1
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/common.go
@@ -0,0 +1,109 @@
+package config
+
+// New creates a new config instance.
+func New() *Config {
+ return &Config{}
+}
+
+// Config contains all the sections, comments and includes from a config file.
+type Config struct {
+ Comment *Comment
+ Sections Sections
+ Includes Includes
+}
+
+// Includes is a list of Includes in a config file.
+type Includes []*Include
+
+// Include is a reference to an included config file.
+type Include struct {
+ Path string
+ Config *Config
+}
+
+// Comment string without the prefix '#' or ';'.
+type Comment string
+
+const (
+ // NoSubsection token is passed to Config.Section and Config.SetSection to
+ // represent the absence of a section.
+ NoSubsection = ""
+)
+
+// Section returns a existing section with the given name or creates a new one.
+func (c *Config) Section(name string) *Section {
+ for i := len(c.Sections) - 1; i >= 0; i-- {
+ s := c.Sections[i]
+ if s.IsName(name) {
+ return s
+ }
+ }
+
+ s := &Section{Name: name}
+ c.Sections = append(c.Sections, s)
+ return s
+}
+
+// HasSection checks if the Config has a section with the specified name.
+func (c *Config) HasSection(name string) bool {
+ for _, s := range c.Sections {
+ if s.IsName(name) {
+ return true
+ }
+ }
+ return false
+}
+
+// RemoveSection removes a section from a config file.
+func (c *Config) RemoveSection(name string) *Config {
+ result := Sections{}
+ for _, s := range c.Sections {
+ if !s.IsName(name) {
+ result = append(result, s)
+ }
+ }
+
+ c.Sections = result
+ return c
+}
+
+// RemoveSubsection remove a subsection from a config file.
+func (c *Config) RemoveSubsection(section string, subsection string) *Config {
+ for _, s := range c.Sections {
+ if s.IsName(section) {
+ result := Subsections{}
+ for _, ss := range s.Subsections {
+ if !ss.IsName(subsection) {
+ result = append(result, ss)
+ }
+ }
+ s.Subsections = result
+ }
+ }
+
+ return c
+}
+
+// AddOption adds an option to a given section and subsection. Use the
+// NoSubsection constant for the subsection argument if no subsection is wanted.
+func (c *Config) AddOption(section string, subsection string, key string, value string) *Config {
+ if subsection == "" {
+ c.Section(section).AddOption(key, value)
+ } else {
+ c.Section(section).Subsection(subsection).AddOption(key, value)
+ }
+
+ return c
+}
+
+// SetOption sets an option to a given section and subsection. Use the
+// NoSubsection constant for the subsection argument if no subsection is wanted.
+func (c *Config) SetOption(section string, subsection string, key string, value string) *Config {
+ if subsection == "" {
+ c.Section(section).SetOption(key, value)
+ } else {
+ c.Section(section).Subsection(subsection).SetOption(key, value)
+ }
+
+ return c
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/decoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/decoder.go
new file mode 100644
index 00000000..8e52d57f
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/decoder.go
@@ -0,0 +1,37 @@
+package config
+
+import (
+ "io"
+
+ "github.com/go-git/gcfg"
+)
+
+// A Decoder reads and decodes config files from an input stream.
+type Decoder struct {
+ io.Reader
+}
+
+// NewDecoder returns a new decoder that reads from r.
+func NewDecoder(r io.Reader) *Decoder {
+ return &Decoder{r}
+}
+
+// Decode reads the whole config from its input and stores it in the
+// value pointed to by config.
+func (d *Decoder) Decode(config *Config) error {
+ cb := func(s string, ss string, k string, v string, bv bool) error {
+ if ss == "" && k == "" {
+ config.Section(s)
+ return nil
+ }
+
+ if ss != "" && k == "" {
+ config.Section(s).Subsection(ss)
+ return nil
+ }
+
+ config.AddOption(s, ss, k, v)
+ return nil
+ }
+ return gcfg.ReadWithCallback(d, cb)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/doc.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/doc.go
new file mode 100644
index 00000000..3986c836
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/doc.go
@@ -0,0 +1,122 @@
+// Package config implements encoding and decoding of git config files.
+//
+// Configuration File
+// ------------------
+//
+// The Git configuration file contains a number of variables that affect
+// the Git commands' behavior. The `.git/config` file in each repository
+// is used to store the configuration for that repository, and
+// `$HOME/.gitconfig` is used to store a per-user configuration as
+// fallback values for the `.git/config` file. The file `/etc/gitconfig`
+// can be used to store a system-wide default configuration.
+//
+// The configuration variables are used by both the Git plumbing
+// and the porcelains. The variables are divided into sections, wherein
+// the fully qualified variable name of the variable itself is the last
+// dot-separated segment and the section name is everything before the last
+// dot. The variable names are case-insensitive, allow only alphanumeric
+// characters and `-`, and must start with an alphabetic character. Some
+// variables may appear multiple times; we say then that the variable is
+// multivalued.
+//
+// Syntax
+// ~~~~~~
+//
+// The syntax is fairly flexible and permissive; whitespaces are mostly
+// ignored. The '#' and ';' characters begin comments to the end of line,
+// blank lines are ignored.
+//
+// The file consists of sections and variables. A section begins with
+// the name of the section in square brackets and continues until the next
+// section begins. Section names are case-insensitive. Only alphanumeric
+// characters, `-` and `.` are allowed in section names. Each variable
+// must belong to some section, which means that there must be a section
+// header before the first setting of a variable.
+//
+// Sections can be further divided into subsections. To begin a subsection
+// put its name in double quotes, separated by space from the section name,
+// in the section header, like in the example below:
+//
+// --------
+// [section "subsection"]
+//
+// --------
+//
+// Subsection names are case sensitive and can contain any characters except
+// newline (doublequote `"` and backslash can be included by escaping them
+// as `\"` and `\\`, respectively). Section headers cannot span multiple
+// lines. Variables may belong directly to a section or to a given subsection.
+// You can have `[section]` if you have `[section "subsection"]`, but you
+// don't need to.
+//
+// There is also a deprecated `[section.subsection]` syntax. With this
+// syntax, the subsection name is converted to lower-case and is also
+// compared case sensitively. These subsection names follow the same
+// restrictions as section names.
+//
+// All the other lines (and the remainder of the line after the section
+// header) are recognized as setting variables, in the form
+// 'name = value' (or just 'name', which is a short-hand to say that
+// the variable is the boolean "true").
+// The variable names are case-insensitive, allow only alphanumeric characters
+// and `-`, and must start with an alphabetic character.
+//
+// A line that defines a value can be continued to the next line by
+// ending it with a `\`; the backquote and the end-of-line are
+// stripped. Leading whitespaces after 'name =', the remainder of the
+// line after the first comment character '#' or ';', and trailing
+// whitespaces of the line are discarded unless they are enclosed in
+// double quotes. Internal whitespaces within the value are retained
+// verbatim.
+//
+// Inside double quotes, double quote `"` and backslash `\` characters
+// must be escaped: use `\"` for `"` and `\\` for `\`.
+//
+// The following escape sequences (beside `\"` and `\\`) are recognized:
+// `\n` for newline character (NL), `\t` for horizontal tabulation (HT, TAB)
+// and `\b` for backspace (BS). Other char escape sequences (including octal
+// escape sequences) are invalid.
+//
+// Includes
+// ~~~~~~~~
+//
+// You can include one config file from another by setting the special
+// `include.path` variable to the name of the file to be included. The
+// variable takes a pathname as its value, and is subject to tilde
+// expansion.
+//
+// The included file is expanded immediately, as if its contents had been
+// found at the location of the include directive. If the value of the
+// `include.path` variable is a relative path, the path is considered to be
+// relative to the configuration file in which the include directive was
+// found. See below for examples.
+//
+//
+// Example
+// ~~~~~~~
+//
+// # Core variables
+// [core]
+// ; Don't trust file modes
+// filemode = false
+//
+// # Our diff algorithm
+// [diff]
+// external = /usr/local/bin/diff-wrapper
+// renames = true
+//
+// [branch "devel"]
+// remote = origin
+// merge = refs/heads/devel
+//
+// # Proxy settings
+// [core]
+// gitProxy="ssh" for "kernel.org"
+// gitProxy=default-proxy ; for the rest
+//
+// [include]
+// path = /path/to/foo.inc ; include by absolute path
+// path = foo ; expand "foo" relative to the current file
+// path = ~/foo ; expand "foo" in your `$HOME` directory
+//
+package config
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/encoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/encoder.go
new file mode 100644
index 00000000..de069aed
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/encoder.go
@@ -0,0 +1,82 @@
+package config
+
+import (
+ "fmt"
+ "io"
+ "strings"
+)
+
+// An Encoder writes config files to an output stream.
+type Encoder struct {
+ w io.Writer
+}
+
+var (
+ subsectionReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`)
+ valueReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`, "\n", `\n`, "\t", `\t`, "\b", `\b`)
+)
+// NewEncoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+ return &Encoder{w}
+}
+
+// Encode writes the config in git config format to the stream of the encoder.
+func (e *Encoder) Encode(cfg *Config) error {
+ for _, s := range cfg.Sections {
+ if err := e.encodeSection(s); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (e *Encoder) encodeSection(s *Section) error {
+ if len(s.Options) > 0 {
+ if err := e.printf("[%s]\n", s.Name); err != nil {
+ return err
+ }
+
+ if err := e.encodeOptions(s.Options); err != nil {
+ return err
+ }
+ }
+
+ for _, ss := range s.Subsections {
+ if err := e.encodeSubsection(s.Name, ss); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (e *Encoder) encodeSubsection(sectionName string, s *Subsection) error {
+ if err := e.printf("[%s \"%s\"]\n", sectionName, subsectionReplacer.Replace(s.Name)); err != nil {
+ return err
+ }
+
+ return e.encodeOptions(s.Options)
+}
+
+func (e *Encoder) encodeOptions(opts Options) error {
+ for _, o := range opts {
+ var value string
+ if strings.ContainsAny(o.Value, "#;\"\t\n\\") || strings.HasPrefix(o.Value, " ") || strings.HasSuffix(o.Value, " ") {
+ value = `"`+valueReplacer.Replace(o.Value)+`"`
+ } else {
+ value = o.Value
+ }
+
+ if err := e.printf("\t%s = %s\n", o.Key, value); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (e *Encoder) printf(msg string, args ...interface{}) error {
+ _, err := fmt.Fprintf(e.w, msg, args...)
+ return err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/format.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/format.go
new file mode 100644
index 00000000..4873ea92
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/format.go
@@ -0,0 +1,53 @@
+package config
+
+// RepositoryFormatVersion represents the repository format version,
+// as per defined at:
+//
+// https://git-scm.com/docs/repository-version
+type RepositoryFormatVersion string
+
+const (
+ // Version_0 is the format defined by the initial version of git,
+ // including but not limited to the format of the repository
+ // directory, the repository configuration file, and the object
+ // and ref storage.
+ //
+ // Specifying the complete behavior of git is beyond the scope
+ // of this document.
+ Version_0 = "0"
+
+ // Version_1 is identical to version 0, with the following exceptions:
+ //
+ // 1. When reading the core.repositoryformatversion variable, a git
+ // implementation which supports version 1 MUST also read any
+ // configuration keys found in the extensions section of the
+ // configuration file.
+ //
+ // 2. If a version-1 repository specifies any extensions.* keys that
+ // the running git has not implemented, the operation MUST NOT proceed.
+ // Similarly, if the value of any known key is not understood by the
+ // implementation, the operation MUST NOT proceed.
+ //
+ // Note that if no extensions are specified in the config file, then
+ // core.repositoryformatversion SHOULD be set to 0 (setting it to 1 provides
+ // no benefit, and makes the repository incompatible with older
+ // implementations of git).
+ Version_1 = "1"
+
+ // DefaultRepositoryFormatVersion holds the default repository format version.
+ DefaultRepositoryFormatVersion = Version_0
+)
+
+// ObjectFormat defines the object format.
+type ObjectFormat string
+
+const (
+ // SHA1 represents the object format used for SHA1.
+ SHA1 ObjectFormat = "sha1"
+
+ // SHA256 represents the object format used for SHA256.
+ SHA256 ObjectFormat = "sha256"
+
+ // DefaultObjectFormat holds the default object format.
+ DefaultObjectFormat = SHA1
+)
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/option.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/option.go
new file mode 100644
index 00000000..cad39481
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/option.go
@@ -0,0 +1,127 @@
+package config
+
+import (
+ "fmt"
+ "strings"
+)
+
+// Option defines a key/value entity in a config file.
+type Option struct {
+ // Key preserving original caseness.
+ // Use IsKey instead to compare key regardless of caseness.
+ Key string
+ // Original value as string, could be not normalized.
+ Value string
+}
+
+type Options []*Option
+
+// IsKey returns true if the given key matches
+// this option's key in a case-insensitive comparison.
+func (o *Option) IsKey(key string) bool {
+ return strings.EqualFold(o.Key, key)
+}
+
+func (opts Options) GoString() string {
+ var strs []string
+ for _, opt := range opts {
+ strs = append(strs, fmt.Sprintf("%#v", opt))
+ }
+
+ return strings.Join(strs, ", ")
+}
+
+// Get gets the value for the given key if set,
+// otherwise it returns the empty string.
+//
+// Note that there is no difference
+//
+// This matches git behaviour since git v1.8.1-rc1,
+// if there are multiple definitions of a key, the
+// last one wins.
+//
+// See: http://article.gmane.org/gmane.linux.kernel/1407184
+//
+// In order to get all possible values for the same key,
+// use GetAll.
+func (opts Options) Get(key string) string {
+ for i := len(opts) - 1; i >= 0; i-- {
+ o := opts[i]
+ if o.IsKey(key) {
+ return o.Value
+ }
+ }
+ return ""
+}
+
+// Has checks if an Option exist with the given key.
+func (opts Options) Has(key string) bool {
+ for _, o := range opts {
+ if o.IsKey(key) {
+ return true
+ }
+ }
+ return false
+}
+
+// GetAll returns all possible values for the same key.
+func (opts Options) GetAll(key string) []string {
+ result := []string{}
+ for _, o := range opts {
+ if o.IsKey(key) {
+ result = append(result, o.Value)
+ }
+ }
+ return result
+}
+
+func (opts Options) withoutOption(key string) Options {
+ result := Options{}
+ for _, o := range opts {
+ if !o.IsKey(key) {
+ result = append(result, o)
+ }
+ }
+ return result
+}
+
+func (opts Options) withAddedOption(key string, value string) Options {
+ return append(opts, &Option{key, value})
+}
+
+func (opts Options) withSettedOption(key string, values ...string) Options {
+ var result Options
+ var added []string
+ for _, o := range opts {
+ if !o.IsKey(key) {
+ result = append(result, o)
+ continue
+ }
+
+ if contains(values, o.Value) {
+ added = append(added, o.Value)
+ result = append(result, o)
+ continue
+ }
+ }
+
+ for _, value := range values {
+ if contains(added, value) {
+ continue
+ }
+
+ result = result.withAddedOption(key, value)
+ }
+
+ return result
+}
+
+func contains(haystack []string, needle string) bool {
+ for _, s := range haystack {
+ if s == needle {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/config/section.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/section.go
new file mode 100644
index 00000000..4625ac58
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/config/section.go
@@ -0,0 +1,181 @@
+package config
+
+import (
+ "fmt"
+ "strings"
+)
+
+// Section is the representation of a section inside git configuration files.
+// Each Section contains Options that are used by both the Git plumbing
+// and the porcelains.
+// Sections can be further divided into subsections. To begin a subsection
+// put its name in double quotes, separated by space from the section name,
+// in the section header, like in the example below:
+//
+// [section "subsection"]
+//
+// All the other lines (and the remainder of the line after the section header)
+// are recognized as option variables, in the form "name = value" (or just name,
+// which is a short-hand to say that the variable is the boolean "true").
+// The variable names are case-insensitive, allow only alphanumeric characters
+// and -, and must start with an alphabetic character:
+//
+// [section "subsection1"]
+// option1 = value1
+// option2
+// [section "subsection2"]
+// option3 = value2
+//
+type Section struct {
+ Name string
+ Options Options
+ Subsections Subsections
+}
+
+type Subsection struct {
+ Name string
+ Options Options
+}
+
+type Sections []*Section
+
+func (s Sections) GoString() string {
+ var strs []string
+ for _, ss := range s {
+ strs = append(strs, fmt.Sprintf("%#v", ss))
+ }
+
+ return strings.Join(strs, ", ")
+}
+
+type Subsections []*Subsection
+
+func (s Subsections) GoString() string {
+ var strs []string
+ for _, ss := range s {
+ strs = append(strs, fmt.Sprintf("%#v", ss))
+ }
+
+ return strings.Join(strs, ", ")
+}
+
+// IsName checks if the name provided is equals to the Section name, case insensitive.
+func (s *Section) IsName(name string) bool {
+ return strings.EqualFold(s.Name, name)
+}
+
+// Subsection returns a Subsection from the specified Section. If the
+// Subsection does not exists, new one is created and added to Section.
+func (s *Section) Subsection(name string) *Subsection {
+ for i := len(s.Subsections) - 1; i >= 0; i-- {
+ ss := s.Subsections[i]
+ if ss.IsName(name) {
+ return ss
+ }
+ }
+
+ ss := &Subsection{Name: name}
+ s.Subsections = append(s.Subsections, ss)
+ return ss
+}
+
+// HasSubsection checks if the Section has a Subsection with the specified name.
+func (s *Section) HasSubsection(name string) bool {
+ for _, ss := range s.Subsections {
+ if ss.IsName(name) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// RemoveSubsection removes a subsection from a Section.
+func (s *Section) RemoveSubsection(name string) *Section {
+ result := Subsections{}
+ for _, s := range s.Subsections {
+ if !s.IsName(name) {
+ result = append(result, s)
+ }
+ }
+
+ s.Subsections = result
+ return s
+}
+
+// Option returns the value for the specified key. Empty string is returned if
+// key does not exists.
+func (s *Section) Option(key string) string {
+ return s.Options.Get(key)
+}
+
+// OptionAll returns all possible values for an option with the specified key.
+// If the option does not exists, an empty slice will be returned.
+func (s *Section) OptionAll(key string) []string {
+ return s.Options.GetAll(key)
+}
+
+// HasOption checks if the Section has an Option with the given key.
+func (s *Section) HasOption(key string) bool {
+ return s.Options.Has(key)
+}
+
+// AddOption adds a new Option to the Section. The updated Section is returned.
+func (s *Section) AddOption(key string, value string) *Section {
+ s.Options = s.Options.withAddedOption(key, value)
+ return s
+}
+
+// SetOption adds a new Option to the Section. If the option already exists, is replaced.
+// The updated Section is returned.
+func (s *Section) SetOption(key string, value string) *Section {
+ s.Options = s.Options.withSettedOption(key, value)
+ return s
+}
+
+// Remove an option with the specified key. The updated Section is returned.
+func (s *Section) RemoveOption(key string) *Section {
+ s.Options = s.Options.withoutOption(key)
+ return s
+}
+
+// IsName checks if the name of the subsection is exactly the specified name.
+func (s *Subsection) IsName(name string) bool {
+ return s.Name == name
+}
+
+// Option returns an option with the specified key. If the option does not exists,
+// empty spring will be returned.
+func (s *Subsection) Option(key string) string {
+ return s.Options.Get(key)
+}
+
+// OptionAll returns all possible values for an option with the specified key.
+// If the option does not exists, an empty slice will be returned.
+func (s *Subsection) OptionAll(key string) []string {
+ return s.Options.GetAll(key)
+}
+
+// HasOption checks if the Subsection has an Option with the given key.
+func (s *Subsection) HasOption(key string) bool {
+ return s.Options.Has(key)
+}
+
+// AddOption adds a new Option to the Subsection. The updated Subsection is returned.
+func (s *Subsection) AddOption(key string, value string) *Subsection {
+ s.Options = s.Options.withAddedOption(key, value)
+ return s
+}
+
+// SetOption adds a new Option to the Subsection. If the option already exists, is replaced.
+// The updated Subsection is returned.
+func (s *Subsection) SetOption(key string, value ...string) *Subsection {
+ s.Options = s.Options.withSettedOption(key, value...)
+ return s
+}
+
+// RemoveOption removes the option with the specified key. The updated Subsection is returned.
+func (s *Subsection) RemoveOption(key string) *Subsection {
+ s.Options = s.Options.withoutOption(key)
+ return s
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/colorconfig.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/colorconfig.go
new file mode 100644
index 00000000..6fd41584
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/colorconfig.go
@@ -0,0 +1,97 @@
+package diff
+
+import "github.com/go-git/go-git/v5/plumbing/color"
+
+// A ColorKey is a key into a ColorConfig map and also equal to the key in the
+// diff.color subsection of the config. See
+// https://github.com/git/git/blob/v2.26.2/diff.c#L83-L106.
+type ColorKey string
+
+// ColorKeys.
+const (
+ Context ColorKey = "context"
+ Meta ColorKey = "meta"
+ Frag ColorKey = "frag"
+ Old ColorKey = "old"
+ New ColorKey = "new"
+ Commit ColorKey = "commit"
+ Whitespace ColorKey = "whitespace"
+ Func ColorKey = "func"
+ OldMoved ColorKey = "oldMoved"
+ OldMovedAlternative ColorKey = "oldMovedAlternative"
+ OldMovedDimmed ColorKey = "oldMovedDimmed"
+ OldMovedAlternativeDimmed ColorKey = "oldMovedAlternativeDimmed"
+ NewMoved ColorKey = "newMoved"
+ NewMovedAlternative ColorKey = "newMovedAlternative"
+ NewMovedDimmed ColorKey = "newMovedDimmed"
+ NewMovedAlternativeDimmed ColorKey = "newMovedAlternativeDimmed"
+ ContextDimmed ColorKey = "contextDimmed"
+ OldDimmed ColorKey = "oldDimmed"
+ NewDimmed ColorKey = "newDimmed"
+ ContextBold ColorKey = "contextBold"
+ OldBold ColorKey = "oldBold"
+ NewBold ColorKey = "newBold"
+)
+
+// A ColorConfig is a color configuration. A nil or empty ColorConfig
+// corresponds to no color.
+type ColorConfig map[ColorKey]string
+
+// A ColorConfigOption sets an option on a ColorConfig.
+type ColorConfigOption func(ColorConfig)
+
+// WithColor sets the color for key.
+func WithColor(key ColorKey, color string) ColorConfigOption {
+ return func(cc ColorConfig) {
+ cc[key] = color
+ }
+}
+
+// defaultColorConfig is the default color configuration. See
+// https://github.com/git/git/blob/v2.26.2/diff.c#L57-L81.
+var defaultColorConfig = ColorConfig{
+ Context: color.Normal,
+ Meta: color.Bold,
+ Frag: color.Cyan,
+ Old: color.Red,
+ New: color.Green,
+ Commit: color.Yellow,
+ Whitespace: color.BgRed,
+ Func: color.Normal,
+ OldMoved: color.BoldMagenta,
+ OldMovedAlternative: color.BoldBlue,
+ OldMovedDimmed: color.Faint,
+ OldMovedAlternativeDimmed: color.FaintItalic,
+ NewMoved: color.BoldCyan,
+ NewMovedAlternative: color.BoldYellow,
+ NewMovedDimmed: color.Faint,
+ NewMovedAlternativeDimmed: color.FaintItalic,
+ ContextDimmed: color.Faint,
+ OldDimmed: color.FaintRed,
+ NewDimmed: color.FaintGreen,
+ ContextBold: color.Bold,
+ OldBold: color.BoldRed,
+ NewBold: color.BoldGreen,
+}
+
+// NewColorConfig returns a new ColorConfig.
+func NewColorConfig(options ...ColorConfigOption) ColorConfig {
+ cc := make(ColorConfig)
+ for key, value := range defaultColorConfig {
+ cc[key] = value
+ }
+ for _, option := range options {
+ option(cc)
+ }
+ return cc
+}
+
+// Reset returns the ANSI escape sequence to reset the color with key set from
+// cc. If no color was set then no reset is needed so it returns the empty
+// string.
+func (cc ColorConfig) Reset(key ColorKey) string {
+ if cc[key] == "" {
+ return ""
+ }
+ return color.Reset
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/patch.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/patch.go
new file mode 100644
index 00000000..c7678b01
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/patch.go
@@ -0,0 +1,58 @@
+package diff
+
+import (
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+)
+
+// Operation defines the operation of a diff item.
+type Operation int
+
+const (
+ // Equal item represents an equals diff.
+ Equal Operation = iota
+ // Add item represents an insert diff.
+ Add
+ // Delete item represents a delete diff.
+ Delete
+)
+
+// Patch represents a collection of steps to transform several files.
+type Patch interface {
+ // FilePatches returns a slice of patches per file.
+ FilePatches() []FilePatch
+ // Message returns an optional message that can be at the top of the
+ // Patch representation.
+ Message() string
+}
+
+// FilePatch represents the necessary steps to transform one file into another.
+type FilePatch interface {
+ // IsBinary returns true if this patch is representing a binary file.
+ IsBinary() bool
+ // Files returns the from and to Files, with all the necessary metadata
+ // about them. If the patch creates a new file, "from" will be nil.
+ // If the patch deletes a file, "to" will be nil.
+ Files() (from, to File)
+ // Chunks returns a slice of ordered changes to transform "from" File into
+ // "to" File. If the file is a binary one, Chunks will be empty.
+ Chunks() []Chunk
+}
+
+// File contains all the file metadata necessary to print some patch formats.
+type File interface {
+ // Hash returns the File Hash.
+ Hash() plumbing.Hash
+ // Mode returns the FileMode.
+ Mode() filemode.FileMode
+ // Path returns the complete Path to the file, including the filename.
+ Path() string
+}
+
+// Chunk represents a portion of a file transformation into another.
+type Chunk interface {
+ // Content contains the portion of the file.
+ Content() string
+ // Type contains the Operation to do with this Chunk.
+ Type() Operation
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/unified_encoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/unified_encoder.go
new file mode 100644
index 00000000..fa605b19
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/diff/unified_encoder.go
@@ -0,0 +1,395 @@
+package diff
+
+import (
+ "fmt"
+ "io"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+// DefaultContextLines is the default number of context lines.
+const DefaultContextLines = 3
+
+var (
+ splitLinesRegexp = regexp.MustCompile(`[^\n]*(\n|$)`)
+
+ operationChar = map[Operation]byte{
+ Add: '+',
+ Delete: '-',
+ Equal: ' ',
+ }
+
+ operationColorKey = map[Operation]ColorKey{
+ Add: New,
+ Delete: Old,
+ Equal: Context,
+ }
+)
+
+// UnifiedEncoder encodes an unified diff into the provided Writer. It does not
+// support similarity index for renames or sorting hash representations.
+type UnifiedEncoder struct {
+ io.Writer
+
+ // contextLines is the count of unchanged lines that will appear surrounding
+ // a change.
+ contextLines int
+
+ // srcPrefix and dstPrefix are prepended to file paths when encoding a diff.
+ srcPrefix string
+ dstPrefix string
+
+ // colorConfig is the color configuration. The default is no color.
+ color ColorConfig
+}
+
+// NewUnifiedEncoder returns a new UnifiedEncoder that writes to w.
+func NewUnifiedEncoder(w io.Writer, contextLines int) *UnifiedEncoder {
+ return &UnifiedEncoder{
+ Writer: w,
+ srcPrefix: "a/",
+ dstPrefix: "b/",
+ contextLines: contextLines,
+ }
+}
+
+// SetColor sets e's color configuration and returns e.
+func (e *UnifiedEncoder) SetColor(colorConfig ColorConfig) *UnifiedEncoder {
+ e.color = colorConfig
+ return e
+}
+
+// SetSrcPrefix sets e's srcPrefix and returns e.
+func (e *UnifiedEncoder) SetSrcPrefix(prefix string) *UnifiedEncoder {
+ e.srcPrefix = prefix
+ return e
+}
+
+// SetDstPrefix sets e's dstPrefix and returns e.
+func (e *UnifiedEncoder) SetDstPrefix(prefix string) *UnifiedEncoder {
+ e.dstPrefix = prefix
+ return e
+}
+
+// Encode encodes patch.
+func (e *UnifiedEncoder) Encode(patch Patch) error {
+ sb := &strings.Builder{}
+
+ if message := patch.Message(); message != "" {
+ sb.WriteString(message)
+ if !strings.HasSuffix(message, "\n") {
+ sb.WriteByte('\n')
+ }
+ }
+
+ for _, filePatch := range patch.FilePatches() {
+ e.writeFilePatchHeader(sb, filePatch)
+ g := newHunksGenerator(filePatch.Chunks(), e.contextLines)
+ for _, hunk := range g.Generate() {
+ hunk.writeTo(sb, e.color)
+ }
+ }
+
+ _, err := e.Write([]byte(sb.String()))
+ return err
+}
+
+func (e *UnifiedEncoder) writeFilePatchHeader(sb *strings.Builder, filePatch FilePatch) {
+ from, to := filePatch.Files()
+ if from == nil && to == nil {
+ return
+ }
+ isBinary := filePatch.IsBinary()
+
+ var lines []string
+ switch {
+ case from != nil && to != nil:
+ hashEquals := from.Hash() == to.Hash()
+ lines = append(lines,
+ fmt.Sprintf("diff --git %s%s %s%s",
+ e.srcPrefix, from.Path(), e.dstPrefix, to.Path()),
+ )
+ if from.Mode() != to.Mode() {
+ lines = append(lines,
+ fmt.Sprintf("old mode %o", from.Mode()),
+ fmt.Sprintf("new mode %o", to.Mode()),
+ )
+ }
+ if from.Path() != to.Path() {
+ lines = append(lines,
+ fmt.Sprintf("rename from %s", from.Path()),
+ fmt.Sprintf("rename to %s", to.Path()),
+ )
+ }
+ if from.Mode() != to.Mode() && !hashEquals {
+ lines = append(lines,
+ fmt.Sprintf("index %s..%s", from.Hash(), to.Hash()),
+ )
+ } else if !hashEquals {
+ lines = append(lines,
+ fmt.Sprintf("index %s..%s %o", from.Hash(), to.Hash(), from.Mode()),
+ )
+ }
+ if !hashEquals {
+ lines = e.appendPathLines(lines, e.srcPrefix+from.Path(), e.dstPrefix+to.Path(), isBinary)
+ }
+ case from == nil:
+ lines = append(lines,
+ fmt.Sprintf("diff --git %s %s", e.srcPrefix+to.Path(), e.dstPrefix+to.Path()),
+ fmt.Sprintf("new file mode %o", to.Mode()),
+ fmt.Sprintf("index %s..%s", plumbing.ZeroHash, to.Hash()),
+ )
+ lines = e.appendPathLines(lines, "/dev/null", e.dstPrefix+to.Path(), isBinary)
+ case to == nil:
+ lines = append(lines,
+ fmt.Sprintf("diff --git %s %s", e.srcPrefix+from.Path(), e.dstPrefix+from.Path()),
+ fmt.Sprintf("deleted file mode %o", from.Mode()),
+ fmt.Sprintf("index %s..%s", from.Hash(), plumbing.ZeroHash),
+ )
+ lines = e.appendPathLines(lines, e.srcPrefix+from.Path(), "/dev/null", isBinary)
+ }
+
+ sb.WriteString(e.color[Meta])
+ sb.WriteString(lines[0])
+ for _, line := range lines[1:] {
+ sb.WriteByte('\n')
+ sb.WriteString(line)
+ }
+ sb.WriteString(e.color.Reset(Meta))
+ sb.WriteByte('\n')
+}
+
+func (e *UnifiedEncoder) appendPathLines(lines []string, fromPath, toPath string, isBinary bool) []string {
+ if isBinary {
+ return append(lines,
+ fmt.Sprintf("Binary files %s and %s differ", fromPath, toPath),
+ )
+ }
+ return append(lines,
+ fmt.Sprintf("--- %s", fromPath),
+ fmt.Sprintf("+++ %s", toPath),
+ )
+}
+
+type hunksGenerator struct {
+ fromLine, toLine int
+ ctxLines int
+ chunks []Chunk
+ current *hunk
+ hunks []*hunk
+ beforeContext, afterContext []string
+}
+
+func newHunksGenerator(chunks []Chunk, ctxLines int) *hunksGenerator {
+ return &hunksGenerator{
+ chunks: chunks,
+ ctxLines: ctxLines,
+ }
+}
+
+func (g *hunksGenerator) Generate() []*hunk {
+ for i, chunk := range g.chunks {
+ lines := splitLines(chunk.Content())
+ nLines := len(lines)
+
+ switch chunk.Type() {
+ case Equal:
+ g.fromLine += nLines
+ g.toLine += nLines
+ g.processEqualsLines(lines, i)
+ case Delete:
+ if nLines != 0 {
+ g.fromLine++
+ }
+
+ g.processHunk(i, chunk.Type())
+ g.fromLine += nLines - 1
+ g.current.AddOp(chunk.Type(), lines...)
+ case Add:
+ if nLines != 0 {
+ g.toLine++
+ }
+ g.processHunk(i, chunk.Type())
+ g.toLine += nLines - 1
+ g.current.AddOp(chunk.Type(), lines...)
+ }
+
+ if i == len(g.chunks)-1 && g.current != nil {
+ g.hunks = append(g.hunks, g.current)
+ }
+ }
+
+ return g.hunks
+}
+
+func (g *hunksGenerator) processHunk(i int, op Operation) {
+ if g.current != nil {
+ return
+ }
+
+ var ctxPrefix string
+ linesBefore := len(g.beforeContext)
+ if linesBefore > g.ctxLines {
+ ctxPrefix = g.beforeContext[linesBefore-g.ctxLines-1]
+ g.beforeContext = g.beforeContext[linesBefore-g.ctxLines:]
+ linesBefore = g.ctxLines
+ }
+
+ g.current = &hunk{ctxPrefix: strings.TrimSuffix(ctxPrefix, "\n")}
+ g.current.AddOp(Equal, g.beforeContext...)
+
+ switch op {
+ case Delete:
+ g.current.fromLine, g.current.toLine =
+ g.addLineNumbers(g.fromLine, g.toLine, linesBefore, i, Add)
+ case Add:
+ g.current.toLine, g.current.fromLine =
+ g.addLineNumbers(g.toLine, g.fromLine, linesBefore, i, Delete)
+ }
+
+ g.beforeContext = nil
+}
+
+// addLineNumbers obtains the line numbers in a new chunk.
+func (g *hunksGenerator) addLineNumbers(la, lb int, linesBefore int, i int, op Operation) (cla, clb int) {
+ cla = la - linesBefore
+ // we need to search for a reference for the next diff
+ switch {
+ case linesBefore != 0 && g.ctxLines != 0:
+ if lb > g.ctxLines {
+ clb = lb - g.ctxLines + 1
+ } else {
+ clb = 1
+ }
+ case g.ctxLines == 0:
+ clb = lb
+ case i != len(g.chunks)-1:
+ next := g.chunks[i+1]
+ if next.Type() == op || next.Type() == Equal {
+ // this diff will be into this chunk
+ clb = lb + 1
+ }
+ }
+
+ return
+}
+
+func (g *hunksGenerator) processEqualsLines(ls []string, i int) {
+ if g.current == nil {
+ g.beforeContext = append(g.beforeContext, ls...)
+ return
+ }
+
+ g.afterContext = append(g.afterContext, ls...)
+ if len(g.afterContext) <= g.ctxLines*2 && i != len(g.chunks)-1 {
+ g.current.AddOp(Equal, g.afterContext...)
+ g.afterContext = nil
+ } else {
+ ctxLines := g.ctxLines
+ if ctxLines > len(g.afterContext) {
+ ctxLines = len(g.afterContext)
+ }
+ g.current.AddOp(Equal, g.afterContext[:ctxLines]...)
+ g.hunks = append(g.hunks, g.current)
+
+ g.current = nil
+ g.beforeContext = g.afterContext[ctxLines:]
+ g.afterContext = nil
+ }
+}
+
+func splitLines(s string) []string {
+ out := splitLinesRegexp.FindAllString(s, -1)
+ if out[len(out)-1] == "" {
+ out = out[:len(out)-1]
+ }
+ return out
+}
+
+type hunk struct {
+ fromLine int
+ toLine int
+
+ fromCount int
+ toCount int
+
+ ctxPrefix string
+ ops []*op
+}
+
+func (h *hunk) writeTo(sb *strings.Builder, color ColorConfig) {
+ sb.WriteString(color[Frag])
+ sb.WriteString("@@ -")
+
+ if h.fromCount == 1 {
+ sb.WriteString(strconv.Itoa(h.fromLine))
+ } else {
+ sb.WriteString(strconv.Itoa(h.fromLine))
+ sb.WriteByte(',')
+ sb.WriteString(strconv.Itoa(h.fromCount))
+ }
+
+ sb.WriteString(" +")
+
+ if h.toCount == 1 {
+ sb.WriteString(strconv.Itoa(h.toLine))
+ } else {
+ sb.WriteString(strconv.Itoa(h.toLine))
+ sb.WriteByte(',')
+ sb.WriteString(strconv.Itoa(h.toCount))
+ }
+
+ sb.WriteString(" @@")
+ sb.WriteString(color.Reset(Frag))
+
+ if h.ctxPrefix != "" {
+ sb.WriteByte(' ')
+ sb.WriteString(color[Func])
+ sb.WriteString(h.ctxPrefix)
+ sb.WriteString(color.Reset(Func))
+ }
+
+ sb.WriteByte('\n')
+
+ for _, op := range h.ops {
+ op.writeTo(sb, color)
+ }
+}
+
+func (h *hunk) AddOp(t Operation, ss ...string) {
+ n := len(ss)
+ switch t {
+ case Add:
+ h.toCount += n
+ case Delete:
+ h.fromCount += n
+ case Equal:
+ h.toCount += n
+ h.fromCount += n
+ }
+
+ for _, s := range ss {
+ h.ops = append(h.ops, &op{s, t})
+ }
+}
+
+type op struct {
+ text string
+ t Operation
+}
+
+func (o *op) writeTo(sb *strings.Builder, color ColorConfig) {
+ colorKey := operationColorKey[o.t]
+ sb.WriteString(color[colorKey])
+ sb.WriteByte(operationChar[o.t])
+ if strings.HasSuffix(o.text, "\n") {
+ sb.WriteString(strings.TrimSuffix(o.text, "\n"))
+ } else {
+ sb.WriteString(o.text + "\n\\ No newline at end of file")
+ }
+ sb.WriteString(color.Reset(colorKey))
+ sb.WriteByte('\n')
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/dir.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/dir.go
new file mode 100644
index 00000000..aca5d0db
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/dir.go
@@ -0,0 +1,144 @@
+package gitignore
+
+import (
+ "bufio"
+ "bytes"
+ "io"
+ "os"
+ "strings"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-git/v5/internal/path_util"
+ "github.com/go-git/go-git/v5/plumbing/format/config"
+ gioutil "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+const (
+ commentPrefix = "#"
+ coreSection = "core"
+ excludesfile = "excludesfile"
+ gitDir = ".git"
+ gitignoreFile = ".gitignore"
+ gitconfigFile = ".gitconfig"
+ systemFile = "/etc/gitconfig"
+ infoExcludeFile = gitDir + "/info/exclude"
+)
+
+// readIgnoreFile reads a specific git ignore file.
+func readIgnoreFile(fs billy.Filesystem, path []string, ignoreFile string) (ps []Pattern, err error) {
+
+ ignoreFile, _ = path_util.ReplaceTildeWithHome(ignoreFile)
+
+ f, err := fs.Open(fs.Join(append(path, ignoreFile)...))
+ if err == nil {
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ s := scanner.Text()
+ if !strings.HasPrefix(s, commentPrefix) && len(strings.TrimSpace(s)) > 0 {
+ ps = append(ps, ParsePattern(s, path))
+ }
+ }
+ } else if !os.IsNotExist(err) {
+ return nil, err
+ }
+
+ return
+}
+
+// ReadPatterns reads the .git/info/exclude and then the gitignore patterns
+// recursively traversing through the directory structure. The result is in
+// the ascending order of priority (last higher).
+func ReadPatterns(fs billy.Filesystem, path []string) (ps []Pattern, err error) {
+ ps, _ = readIgnoreFile(fs, path, infoExcludeFile)
+
+ subps, _ := readIgnoreFile(fs, path, gitignoreFile)
+ ps = append(ps, subps...)
+
+ var fis []os.FileInfo
+ fis, err = fs.ReadDir(fs.Join(path...))
+ if err != nil {
+ return
+ }
+
+ for _, fi := range fis {
+ if fi.IsDir() && fi.Name() != gitDir {
+ var subps []Pattern
+ subps, err = ReadPatterns(fs, append(path, fi.Name()))
+ if err != nil {
+ return
+ }
+
+ if len(subps) > 0 {
+ ps = append(ps, subps...)
+ }
+ }
+ }
+
+ return
+}
+
+func loadPatterns(fs billy.Filesystem, path string) (ps []Pattern, err error) {
+ f, err := fs.Open(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil, nil
+ }
+ return nil, err
+ }
+
+ defer gioutil.CheckClose(f, &err)
+
+ b, err := io.ReadAll(f)
+ if err != nil {
+ return
+ }
+
+ d := config.NewDecoder(bytes.NewBuffer(b))
+
+ raw := config.New()
+ if err = d.Decode(raw); err != nil {
+ return
+ }
+
+ s := raw.Section(coreSection)
+ efo := s.Options.Get(excludesfile)
+ if efo == "" {
+ return nil, nil
+ }
+
+ ps, err = readIgnoreFile(fs, nil, efo)
+ if os.IsNotExist(err) {
+ return nil, nil
+ }
+
+ return
+}
+
+// LoadGlobalPatterns loads gitignore patterns from the gitignore file
+// declared in a user's ~/.gitconfig file. If the ~/.gitconfig file does not
+// exist the function will return nil. If the core.excludesfile property
+// is not declared, the function will return nil. If the file pointed to by
+// the core.excludesfile property does not exist, the function will return nil.
+//
+// The function assumes fs is rooted at the root filesystem.
+func LoadGlobalPatterns(fs billy.Filesystem) (ps []Pattern, err error) {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ return
+ }
+
+ return loadPatterns(fs, fs.Join(home, gitconfigFile))
+}
+
+// LoadSystemPatterns loads gitignore patterns from the gitignore file
+// declared in a system's /etc/gitconfig file. If the /etc/gitconfig file does
+// not exist the function will return nil. If the core.excludesfile property
+// is not declared, the function will return nil. If the file pointed to by
+// the core.excludesfile property does not exist, the function will return nil.
+//
+// The function assumes fs is rooted at the root filesystem.
+func LoadSystemPatterns(fs billy.Filesystem) (ps []Pattern, err error) {
+ return loadPatterns(fs, systemFile)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/doc.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/doc.go
new file mode 100644
index 00000000..eecd4bac
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/doc.go
@@ -0,0 +1,70 @@
+// Package gitignore implements matching file system paths to gitignore patterns that
+// can be automatically read from a git repository tree in the order of definition
+// priorities. It support all pattern formats as specified in the original gitignore
+// documentation, copied below:
+//
+// Pattern format
+// ==============
+//
+// - A blank line matches no files, so it can serve as a separator for readability.
+//
+// - A line starting with # serves as a comment. Put a backslash ("\") in front of
+// the first hash for patterns that begin with a hash.
+//
+// - Trailing spaces are ignored unless they are quoted with backslash ("\").
+//
+// - An optional prefix "!" which negates the pattern; any matching file excluded
+// by a previous pattern will become included again. It is not possible to
+// re-include a file if a parent directory of that file is excluded.
+// Git doesn’t list excluded directories for performance reasons, so
+// any patterns on contained files have no effect, no matter where they are
+// defined. Put a backslash ("\") in front of the first "!" for patterns
+// that begin with a literal "!", for example, "\!important!.txt".
+//
+// - If the pattern ends with a slash, it is removed for the purpose of the
+// following description, but it would only find a match with a directory.
+// In other words, foo/ will match a directory foo and paths underneath it,
+// but will not match a regular file or a symbolic link foo (this is consistent
+// with the way how pathspec works in general in Git).
+//
+// - If the pattern does not contain a slash /, Git treats it as a shell glob
+// pattern and checks for a match against the pathname relative to the location
+// of the .gitignore file (relative to the toplevel of the work tree if not
+// from a .gitignore file).
+//
+// - Otherwise, Git treats the pattern as a shell glob suitable for consumption
+// by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will
+// not match a / in the pathname. For example, "Documentation/*.html" matches
+// "Documentation/git.html" but not "Documentation/ppc/ppc.html" or
+// "tools/perf/Documentation/perf.html".
+//
+// - A leading slash matches the beginning of the pathname. For example,
+// "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
+//
+// Two consecutive asterisks ("**") in patterns matched against full pathname
+// may have special meaning:
+//
+// - A leading "**" followed by a slash means match in all directories.
+// For example, "**/foo" matches file or directory "foo" anywhere, the same as
+// pattern "foo". "**/foo/bar" matches file or directory "bar"
+// anywhere that is directly under directory "foo".
+//
+// - A trailing "/**" matches everything inside. For example, "abc/**" matches
+// all files inside directory "abc", relative to the location of the
+// .gitignore file, with infinite depth.
+//
+// - A slash followed by two consecutive asterisks then a slash matches
+// zero or more directories. For example, "a/**/b" matches "a/b", "a/x/b",
+// "a/x/y/b" and so on.
+//
+// - Other consecutive asterisks are considered invalid.
+//
+// Copyright and license
+// =====================
+//
+// Copyright (c) Oleg Sklyar, Silvertern and source{d}
+//
+// The package code was donated to source{d} to include, modify and develop
+// further as a part of the `go-git` project, release it on the license of
+// the whole project or delete it from the project.
+package gitignore
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/matcher.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/matcher.go
new file mode 100644
index 00000000..bd1e9e2d
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/matcher.go
@@ -0,0 +1,30 @@
+package gitignore
+
+// Matcher defines a global multi-pattern matcher for gitignore patterns
+type Matcher interface {
+ // Match matches patterns in the order of priorities. As soon as an inclusion or
+ // exclusion is found, not further matching is performed.
+ Match(path []string, isDir bool) bool
+}
+
+// NewMatcher constructs a new global matcher. Patterns must be given in the order of
+// increasing priority. That is most generic settings files first, then the content of
+// the repo .gitignore, then content of .gitignore down the path or the repo and then
+// the content command line arguments.
+func NewMatcher(ps []Pattern) Matcher {
+ return &matcher{ps}
+}
+
+type matcher struct {
+ patterns []Pattern
+}
+
+func (m *matcher) Match(path []string, isDir bool) bool {
+ n := len(m.patterns)
+ for i := n - 1; i >= 0; i-- {
+ if match := m.patterns[i].Match(path, isDir); match > NoMatch {
+ return match == Exclude
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/pattern.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/pattern.go
new file mode 100644
index 00000000..450b3cdf
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/gitignore/pattern.go
@@ -0,0 +1,155 @@
+package gitignore
+
+import (
+ "path/filepath"
+ "strings"
+)
+
+// MatchResult defines outcomes of a match, no match, exclusion or inclusion.
+type MatchResult int
+
+const (
+ // NoMatch defines the no match outcome of a match check
+ NoMatch MatchResult = iota
+ // Exclude defines an exclusion of a file as a result of a match check
+ Exclude
+ // Include defines an explicit inclusion of a file as a result of a match check
+ Include
+)
+
+const (
+ inclusionPrefix = "!"
+ zeroToManyDirs = "**"
+ patternDirSep = "/"
+)
+
+// Pattern defines a single gitignore pattern.
+type Pattern interface {
+ // Match matches the given path to the pattern.
+ Match(path []string, isDir bool) MatchResult
+}
+
+type pattern struct {
+ domain []string
+ pattern []string
+ inclusion bool
+ dirOnly bool
+ isGlob bool
+}
+
+// ParsePattern parses a gitignore pattern string into the Pattern structure.
+func ParsePattern(p string, domain []string) Pattern {
+ // storing domain, copy it to ensure it isn't changed externally
+ domain = append([]string(nil), domain...)
+ res := pattern{domain: domain}
+
+ if strings.HasPrefix(p, inclusionPrefix) {
+ res.inclusion = true
+ p = p[1:]
+ }
+
+ if !strings.HasSuffix(p, "\\ ") {
+ p = strings.TrimRight(p, " ")
+ }
+
+ if strings.HasSuffix(p, patternDirSep) {
+ res.dirOnly = true
+ p = p[:len(p)-1]
+ }
+
+ if strings.Contains(p, patternDirSep) {
+ res.isGlob = true
+ }
+
+ res.pattern = strings.Split(p, patternDirSep)
+ return &res
+}
+
+func (p *pattern) Match(path []string, isDir bool) MatchResult {
+ if len(path) <= len(p.domain) {
+ return NoMatch
+ }
+ for i, e := range p.domain {
+ if path[i] != e {
+ return NoMatch
+ }
+ }
+
+ path = path[len(p.domain):]
+ if p.isGlob && !p.globMatch(path, isDir) {
+ return NoMatch
+ } else if !p.isGlob && !p.simpleNameMatch(path, isDir) {
+ return NoMatch
+ }
+
+ if p.inclusion {
+ return Include
+ } else {
+ return Exclude
+ }
+}
+
+func (p *pattern) simpleNameMatch(path []string, isDir bool) bool {
+ for i, name := range path {
+ if match, err := filepath.Match(p.pattern[0], name); err != nil {
+ return false
+ } else if !match {
+ continue
+ }
+ if p.dirOnly && !isDir && i == len(path)-1 {
+ return false
+ }
+ return true
+ }
+ return false
+}
+
+func (p *pattern) globMatch(path []string, isDir bool) bool {
+ matched := false
+ canTraverse := false
+ for i, pattern := range p.pattern {
+ if pattern == "" {
+ canTraverse = false
+ continue
+ }
+ if pattern == zeroToManyDirs {
+ if i == len(p.pattern)-1 {
+ break
+ }
+ canTraverse = true
+ continue
+ }
+ if strings.Contains(pattern, zeroToManyDirs) {
+ return false
+ }
+ if len(path) == 0 {
+ return false
+ }
+ if canTraverse {
+ canTraverse = false
+ for len(path) > 0 {
+ e := path[0]
+ path = path[1:]
+ if match, err := filepath.Match(pattern, e); err != nil {
+ return false
+ } else if match {
+ matched = true
+ break
+ } else if len(path) == 0 {
+ // if nothing left then fail
+ matched = false
+ }
+ }
+ } else {
+ if match, err := filepath.Match(pattern, path[0]); err != nil || !match {
+ return false
+ }
+ matched = true
+ path = path[1:]
+ }
+ }
+ if matched && p.dirOnly && !isDir && len(path) == 0 {
+ matched = false
+ }
+ return matched
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/decoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/decoder.go
new file mode 100644
index 00000000..9afdce30
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/decoder.go
@@ -0,0 +1,178 @@
+package idxfile
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing/hash"
+ "github.com/go-git/go-git/v5/utils/binary"
+)
+
+var (
+ // ErrUnsupportedVersion is returned by Decode when the idx file version
+ // is not supported.
+ ErrUnsupportedVersion = errors.New("unsupported version")
+ // ErrMalformedIdxFile is returned by Decode when the idx file is corrupted.
+ ErrMalformedIdxFile = errors.New("malformed IDX file")
+)
+
+const (
+ fanout = 256
+ objectIDLength = hash.Size
+)
+
+// Decoder reads and decodes idx files from an input stream.
+type Decoder struct {
+ *bufio.Reader
+}
+
+// NewDecoder builds a new idx stream decoder, that reads from r.
+func NewDecoder(r io.Reader) *Decoder {
+ return &Decoder{bufio.NewReader(r)}
+}
+
+// Decode reads from the stream and decode the content into the MemoryIndex struct.
+func (d *Decoder) Decode(idx *MemoryIndex) error {
+ if err := validateHeader(d); err != nil {
+ return err
+ }
+
+ flow := []func(*MemoryIndex, io.Reader) error{
+ readVersion,
+ readFanout,
+ readObjectNames,
+ readCRC32,
+ readOffsets,
+ readChecksums,
+ }
+
+ for _, f := range flow {
+ if err := f(idx, d); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func validateHeader(r io.Reader) error {
+ var h = make([]byte, 4)
+ if _, err := io.ReadFull(r, h); err != nil {
+ return err
+ }
+
+ if !bytes.Equal(h, idxHeader) {
+ return ErrMalformedIdxFile
+ }
+
+ return nil
+}
+
+func readVersion(idx *MemoryIndex, r io.Reader) error {
+ v, err := binary.ReadUint32(r)
+ if err != nil {
+ return err
+ }
+
+ if v > VersionSupported {
+ return ErrUnsupportedVersion
+ }
+
+ idx.Version = v
+ return nil
+}
+
+func readFanout(idx *MemoryIndex, r io.Reader) error {
+ for k := 0; k < fanout; k++ {
+ n, err := binary.ReadUint32(r)
+ if err != nil {
+ return err
+ }
+
+ idx.Fanout[k] = n
+ idx.FanoutMapping[k] = noMapping
+ }
+
+ return nil
+}
+
+func readObjectNames(idx *MemoryIndex, r io.Reader) error {
+ for k := 0; k < fanout; k++ {
+ var buckets uint32
+ if k == 0 {
+ buckets = idx.Fanout[k]
+ } else {
+ buckets = idx.Fanout[k] - idx.Fanout[k-1]
+ }
+
+ if buckets == 0 {
+ continue
+ }
+
+ idx.FanoutMapping[k] = len(idx.Names)
+
+ nameLen := int(buckets * objectIDLength)
+ bin := make([]byte, nameLen)
+ if _, err := io.ReadFull(r, bin); err != nil {
+ return err
+ }
+
+ idx.Names = append(idx.Names, bin)
+ idx.Offset32 = append(idx.Offset32, make([]byte, buckets*4))
+ idx.CRC32 = append(idx.CRC32, make([]byte, buckets*4))
+ }
+
+ return nil
+}
+
+func readCRC32(idx *MemoryIndex, r io.Reader) error {
+ for k := 0; k < fanout; k++ {
+ if pos := idx.FanoutMapping[k]; pos != noMapping {
+ if _, err := io.ReadFull(r, idx.CRC32[pos]); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func readOffsets(idx *MemoryIndex, r io.Reader) error {
+ var o64cnt int
+ for k := 0; k < fanout; k++ {
+ if pos := idx.FanoutMapping[k]; pos != noMapping {
+ if _, err := io.ReadFull(r, idx.Offset32[pos]); err != nil {
+ return err
+ }
+
+ for p := 0; p < len(idx.Offset32[pos]); p += 4 {
+ if idx.Offset32[pos][p]&(byte(1)<<7) > 0 {
+ o64cnt++
+ }
+ }
+ }
+ }
+
+ if o64cnt > 0 {
+ idx.Offset64 = make([]byte, o64cnt*8)
+ if _, err := io.ReadFull(r, idx.Offset64); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func readChecksums(idx *MemoryIndex, r io.Reader) error {
+ if _, err := io.ReadFull(r, idx.PackfileChecksum[:]); err != nil {
+ return err
+ }
+
+ if _, err := io.ReadFull(r, idx.IdxChecksum[:]); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/doc.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/doc.go
new file mode 100644
index 00000000..1e628ab4
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/doc.go
@@ -0,0 +1,128 @@
+// Package idxfile implements encoding and decoding of packfile idx files.
+//
+// == Original (version 1) pack-*.idx files have the following format:
+//
+// - The header consists of 256 4-byte network byte order
+// integers. N-th entry of this table records the number of
+// objects in the corresponding pack, the first byte of whose
+// object name is less than or equal to N. This is called the
+// 'first-level fan-out' table.
+//
+// - The header is followed by sorted 24-byte entries, one entry
+// per object in the pack. Each entry is:
+//
+// 4-byte network byte order integer, recording where the
+// object is stored in the packfile as the offset from the
+// beginning.
+//
+// 20-byte object name.
+//
+// - The file is concluded with a trailer:
+//
+// A copy of the 20-byte SHA1 checksum at the end of
+// corresponding packfile.
+//
+// 20-byte SHA1-checksum of all of the above.
+//
+// Pack Idx file:
+//
+// -- +--------------------------------+
+// fanout | fanout[0] = 2 (for example) |-.
+// table +--------------------------------+ |
+// | fanout[1] | |
+// +--------------------------------+ |
+// | fanout[2] | |
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+// | fanout[255] = total objects |---.
+// -- +--------------------------------+ | |
+// main | offset | | |
+// index | object name 00XXXXXXXXXXXXXXXX | | |
+// tab +--------------------------------+ | |
+// | offset | | |
+// | object name 00XXXXXXXXXXXXXXXX | | |
+// +--------------------------------+<+ |
+// .-| offset | |
+// | | object name 01XXXXXXXXXXXXXXXX | |
+// | +--------------------------------+ |
+// | | offset | |
+// | | object name 01XXXXXXXXXXXXXXXX | |
+// | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+// | | offset | |
+// | | object name FFXXXXXXXXXXXXXXXX | |
+// --| +--------------------------------+<--+
+// trailer | | packfile checksum |
+// | +--------------------------------+
+// | | idxfile checksum |
+// | +--------------------------------+
+// .---------.
+// |
+// Pack file entry: <+
+//
+// packed object header:
+// 1-byte size extension bit (MSB)
+// type (next 3 bit)
+// size0 (lower 4-bit)
+// n-byte sizeN (as long as MSB is set, each 7-bit)
+// size0..sizeN form 4+7+7+..+7 bit integer, size0
+// is the least significant part, and sizeN is the
+// most significant part.
+// packed object data:
+// If it is not DELTA, then deflated bytes (the size above
+// is the size before compression).
+// If it is REF_DELTA, then
+// 20-byte base object name SHA1 (the size above is the
+// size of the delta data that follows).
+// delta data, deflated.
+// If it is OFS_DELTA, then
+// n-byte offset (see below) interpreted as a negative
+// offset from the type-byte of the header of the
+// ofs-delta entry (the size above is the size of
+// the delta data that follows).
+// delta data, deflated.
+//
+// offset encoding:
+// n bytes with MSB set in all but the last one.
+// The offset is then the number constructed by
+// concatenating the lower 7 bit of each byte, and
+// for n >= 2 adding 2^7 + 2^14 + ... + 2^(7*(n-1))
+// to the result.
+//
+// == Version 2 pack-*.idx files support packs larger than 4 GiB, and
+// have some other reorganizations. They have the format:
+//
+// - A 4-byte magic number '\377tOc' which is an unreasonable
+// fanout[0] value.
+//
+// - A 4-byte version number (= 2)
+//
+// - A 256-entry fan-out table just like v1.
+//
+// - A table of sorted 20-byte SHA1 object names. These are
+// packed together without offset values to reduce the cache
+// footprint of the binary search for a specific object name.
+//
+// - A table of 4-byte CRC32 values of the packed object data.
+// This is new in v2 so compressed data can be copied directly
+// from pack to pack during repacking without undetected
+// data corruption.
+//
+// - A table of 4-byte offset values (in network byte order).
+// These are usually 31-bit pack file offsets, but large
+// offsets are encoded as an index into the next table with
+// the msbit set.
+//
+// - A table of 8-byte offset entries (empty for pack files less
+// than 2 GiB). Pack files are organized with heavily used
+// objects toward the front, so most object references should
+// not need to refer to this table.
+//
+// - The same trailer as a v1 pack file:
+//
+// A copy of the 20-byte SHA1 checksum at the end of
+// corresponding packfile.
+//
+// 20-byte SHA1-checksum of all of the above.
+//
+// Source:
+// https://www.kernel.org/pub/software/scm/git/docs/v1.7.5/technical/pack-format.txt
+package idxfile
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/encoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/encoder.go
new file mode 100644
index 00000000..75147376
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/encoder.go
@@ -0,0 +1,141 @@
+package idxfile
+
+import (
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing/hash"
+ "github.com/go-git/go-git/v5/utils/binary"
+)
+
+// Encoder writes MemoryIndex structs to an output stream.
+type Encoder struct {
+ io.Writer
+ hash hash.Hash
+}
+
+// NewEncoder returns a new stream encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+ h := hash.New(hash.CryptoType)
+ mw := io.MultiWriter(w, h)
+ return &Encoder{mw, h}
+}
+
+// Encode encodes an MemoryIndex to the encoder writer.
+func (e *Encoder) Encode(idx *MemoryIndex) (int, error) {
+ flow := []func(*MemoryIndex) (int, error){
+ e.encodeHeader,
+ e.encodeFanout,
+ e.encodeHashes,
+ e.encodeCRC32,
+ e.encodeOffsets,
+ e.encodeChecksums,
+ }
+
+ sz := 0
+ for _, f := range flow {
+ i, err := f(idx)
+ sz += i
+
+ if err != nil {
+ return sz, err
+ }
+ }
+
+ return sz, nil
+}
+
+func (e *Encoder) encodeHeader(idx *MemoryIndex) (int, error) {
+ c, err := e.Write(idxHeader)
+ if err != nil {
+ return c, err
+ }
+
+ return c + 4, binary.WriteUint32(e, idx.Version)
+}
+
+func (e *Encoder) encodeFanout(idx *MemoryIndex) (int, error) {
+ for _, c := range idx.Fanout {
+ if err := binary.WriteUint32(e, c); err != nil {
+ return 0, err
+ }
+ }
+
+ return fanout * 4, nil
+}
+
+func (e *Encoder) encodeHashes(idx *MemoryIndex) (int, error) {
+ var size int
+ for k := 0; k < fanout; k++ {
+ pos := idx.FanoutMapping[k]
+ if pos == noMapping {
+ continue
+ }
+
+ n, err := e.Write(idx.Names[pos])
+ if err != nil {
+ return size, err
+ }
+ size += n
+ }
+ return size, nil
+}
+
+func (e *Encoder) encodeCRC32(idx *MemoryIndex) (int, error) {
+ var size int
+ for k := 0; k < fanout; k++ {
+ pos := idx.FanoutMapping[k]
+ if pos == noMapping {
+ continue
+ }
+
+ n, err := e.Write(idx.CRC32[pos])
+ if err != nil {
+ return size, err
+ }
+
+ size += n
+ }
+
+ return size, nil
+}
+
+func (e *Encoder) encodeOffsets(idx *MemoryIndex) (int, error) {
+ var size int
+ for k := 0; k < fanout; k++ {
+ pos := idx.FanoutMapping[k]
+ if pos == noMapping {
+ continue
+ }
+
+ n, err := e.Write(idx.Offset32[pos])
+ if err != nil {
+ return size, err
+ }
+
+ size += n
+ }
+
+ if len(idx.Offset64) > 0 {
+ n, err := e.Write(idx.Offset64)
+ if err != nil {
+ return size, err
+ }
+
+ size += n
+ }
+
+ return size, nil
+}
+
+func (e *Encoder) encodeChecksums(idx *MemoryIndex) (int, error) {
+ if _, err := e.Write(idx.PackfileChecksum[:]); err != nil {
+ return 0, err
+ }
+
+ copy(idx.IdxChecksum[:], e.hash.Sum(nil)[:hash.Size])
+ if _, err := e.Write(idx.IdxChecksum[:]); err != nil {
+ return 0, err
+ }
+
+ return hash.HexSize, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/idxfile.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/idxfile.go
new file mode 100644
index 00000000..9237a743
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/idxfile.go
@@ -0,0 +1,347 @@
+package idxfile
+
+import (
+ "bytes"
+ "io"
+ "sort"
+
+ encbin "encoding/binary"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/hash"
+)
+
+const (
+ // VersionSupported is the only idx version supported.
+ VersionSupported = 2
+
+ noMapping = -1
+)
+
+var (
+ idxHeader = []byte{255, 't', 'O', 'c'}
+)
+
+// Index represents an index of a packfile.
+type Index interface {
+ // Contains checks whether the given hash is in the index.
+ Contains(h plumbing.Hash) (bool, error)
+ // FindOffset finds the offset in the packfile for the object with
+ // the given hash.
+ FindOffset(h plumbing.Hash) (int64, error)
+ // FindCRC32 finds the CRC32 of the object with the given hash.
+ FindCRC32(h plumbing.Hash) (uint32, error)
+ // FindHash finds the hash for the object with the given offset.
+ FindHash(o int64) (plumbing.Hash, error)
+ // Count returns the number of entries in the index.
+ Count() (int64, error)
+ // Entries returns an iterator to retrieve all index entries.
+ Entries() (EntryIter, error)
+ // EntriesByOffset returns an iterator to retrieve all index entries ordered
+ // by offset.
+ EntriesByOffset() (EntryIter, error)
+}
+
+// MemoryIndex is the in memory representation of an idx file.
+type MemoryIndex struct {
+ Version uint32
+ Fanout [256]uint32
+ // FanoutMapping maps the position in the fanout table to the position
+ // in the Names, Offset32 and CRC32 slices. This improves the memory
+ // usage by not needing an array with unnecessary empty slots.
+ FanoutMapping [256]int
+ Names [][]byte
+ Offset32 [][]byte
+ CRC32 [][]byte
+ Offset64 []byte
+ PackfileChecksum [hash.Size]byte
+ IdxChecksum [hash.Size]byte
+
+ offsetHash map[int64]plumbing.Hash
+ offsetHashIsFull bool
+}
+
+var _ Index = (*MemoryIndex)(nil)
+
+// NewMemoryIndex returns an instance of a new MemoryIndex.
+func NewMemoryIndex() *MemoryIndex {
+ return &MemoryIndex{}
+}
+
+func (idx *MemoryIndex) findHashIndex(h plumbing.Hash) (int, bool) {
+ k := idx.FanoutMapping[h[0]]
+ if k == noMapping {
+ return 0, false
+ }
+
+ if len(idx.Names) <= k {
+ return 0, false
+ }
+
+ data := idx.Names[k]
+ high := uint64(len(idx.Offset32[k])) >> 2
+ if high == 0 {
+ return 0, false
+ }
+
+ low := uint64(0)
+ for {
+ mid := (low + high) >> 1
+ offset := mid * objectIDLength
+
+ cmp := bytes.Compare(h[:], data[offset:offset+objectIDLength])
+ if cmp < 0 {
+ high = mid
+ } else if cmp == 0 {
+ return int(mid), true
+ } else {
+ low = mid + 1
+ }
+
+ if low >= high {
+ break
+ }
+ }
+
+ return 0, false
+}
+
+// Contains implements the Index interface.
+func (idx *MemoryIndex) Contains(h plumbing.Hash) (bool, error) {
+ _, ok := idx.findHashIndex(h)
+ return ok, nil
+}
+
+// FindOffset implements the Index interface.
+func (idx *MemoryIndex) FindOffset(h plumbing.Hash) (int64, error) {
+ if len(idx.FanoutMapping) <= int(h[0]) {
+ return 0, plumbing.ErrObjectNotFound
+ }
+
+ k := idx.FanoutMapping[h[0]]
+ i, ok := idx.findHashIndex(h)
+ if !ok {
+ return 0, plumbing.ErrObjectNotFound
+ }
+
+ offset := idx.getOffset(k, i)
+
+ if !idx.offsetHashIsFull {
+ // Save the offset for reverse lookup
+ if idx.offsetHash == nil {
+ idx.offsetHash = make(map[int64]plumbing.Hash)
+ }
+ idx.offsetHash[int64(offset)] = h
+ }
+
+ return int64(offset), nil
+}
+
+const isO64Mask = uint64(1) << 31
+
+func (idx *MemoryIndex) getOffset(firstLevel, secondLevel int) uint64 {
+ offset := secondLevel << 2
+ ofs := encbin.BigEndian.Uint32(idx.Offset32[firstLevel][offset : offset+4])
+
+ if (uint64(ofs) & isO64Mask) != 0 {
+ offset := 8 * (uint64(ofs) & ^isO64Mask)
+ n := encbin.BigEndian.Uint64(idx.Offset64[offset : offset+8])
+ return n
+ }
+
+ return uint64(ofs)
+}
+
+// FindCRC32 implements the Index interface.
+func (idx *MemoryIndex) FindCRC32(h plumbing.Hash) (uint32, error) {
+ k := idx.FanoutMapping[h[0]]
+ i, ok := idx.findHashIndex(h)
+ if !ok {
+ return 0, plumbing.ErrObjectNotFound
+ }
+
+ return idx.getCRC32(k, i), nil
+}
+
+func (idx *MemoryIndex) getCRC32(firstLevel, secondLevel int) uint32 {
+ offset := secondLevel << 2
+ return encbin.BigEndian.Uint32(idx.CRC32[firstLevel][offset : offset+4])
+}
+
+// FindHash implements the Index interface.
+func (idx *MemoryIndex) FindHash(o int64) (plumbing.Hash, error) {
+ var hash plumbing.Hash
+ var ok bool
+
+ if idx.offsetHash != nil {
+ if hash, ok = idx.offsetHash[o]; ok {
+ return hash, nil
+ }
+ }
+
+ // Lazily generate the reverse offset/hash map if required.
+ if !idx.offsetHashIsFull || idx.offsetHash == nil {
+ if err := idx.genOffsetHash(); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ hash, ok = idx.offsetHash[o]
+ }
+
+ if !ok {
+ return plumbing.ZeroHash, plumbing.ErrObjectNotFound
+ }
+
+ return hash, nil
+}
+
+// genOffsetHash generates the offset/hash mapping for reverse search.
+func (idx *MemoryIndex) genOffsetHash() error {
+ count, err := idx.Count()
+ if err != nil {
+ return err
+ }
+
+ idx.offsetHash = make(map[int64]plumbing.Hash, count)
+ idx.offsetHashIsFull = true
+
+ var hash plumbing.Hash
+ i := uint32(0)
+ for firstLevel, fanoutValue := range idx.Fanout {
+ mappedFirstLevel := idx.FanoutMapping[firstLevel]
+ for secondLevel := uint32(0); i < fanoutValue; i++ {
+ copy(hash[:], idx.Names[mappedFirstLevel][secondLevel*objectIDLength:])
+ offset := int64(idx.getOffset(mappedFirstLevel, int(secondLevel)))
+ idx.offsetHash[offset] = hash
+ secondLevel++
+ }
+ }
+
+ return nil
+}
+
+// Count implements the Index interface.
+func (idx *MemoryIndex) Count() (int64, error) {
+ return int64(idx.Fanout[fanout-1]), nil
+}
+
+// Entries implements the Index interface.
+func (idx *MemoryIndex) Entries() (EntryIter, error) {
+ return &idxfileEntryIter{idx, 0, 0, 0}, nil
+}
+
+// EntriesByOffset implements the Index interface.
+func (idx *MemoryIndex) EntriesByOffset() (EntryIter, error) {
+ count, err := idx.Count()
+ if err != nil {
+ return nil, err
+ }
+
+ iter := &idxfileEntryOffsetIter{
+ entries: make(entriesByOffset, count),
+ }
+
+ entries, err := idx.Entries()
+ if err != nil {
+ return nil, err
+ }
+
+ for pos := 0; int64(pos) < count; pos++ {
+ entry, err := entries.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ iter.entries[pos] = entry
+ }
+
+ sort.Sort(iter.entries)
+
+ return iter, nil
+}
+
+// EntryIter is an iterator that will return the entries in a packfile index.
+type EntryIter interface {
+ // Next returns the next entry in the packfile index.
+ Next() (*Entry, error)
+ // Close closes the iterator.
+ Close() error
+}
+
+type idxfileEntryIter struct {
+ idx *MemoryIndex
+ total int
+ firstLevel, secondLevel int
+}
+
+func (i *idxfileEntryIter) Next() (*Entry, error) {
+ for {
+ if i.firstLevel >= fanout {
+ return nil, io.EOF
+ }
+
+ if i.total >= int(i.idx.Fanout[i.firstLevel]) {
+ i.firstLevel++
+ i.secondLevel = 0
+ continue
+ }
+
+ mappedFirstLevel := i.idx.FanoutMapping[i.firstLevel]
+ entry := new(Entry)
+ copy(entry.Hash[:], i.idx.Names[mappedFirstLevel][i.secondLevel*objectIDLength:])
+ entry.Offset = i.idx.getOffset(mappedFirstLevel, i.secondLevel)
+ entry.CRC32 = i.idx.getCRC32(mappedFirstLevel, i.secondLevel)
+
+ i.secondLevel++
+ i.total++
+
+ return entry, nil
+ }
+}
+
+func (i *idxfileEntryIter) Close() error {
+ i.firstLevel = fanout
+ return nil
+}
+
+// Entry is the in memory representation of an object entry in the idx file.
+type Entry struct {
+ Hash plumbing.Hash
+ CRC32 uint32
+ Offset uint64
+}
+
+type idxfileEntryOffsetIter struct {
+ entries entriesByOffset
+ pos int
+}
+
+func (i *idxfileEntryOffsetIter) Next() (*Entry, error) {
+ if i.pos >= len(i.entries) {
+ return nil, io.EOF
+ }
+
+ entry := i.entries[i.pos]
+ i.pos++
+
+ return entry, nil
+}
+
+func (i *idxfileEntryOffsetIter) Close() error {
+ i.pos = len(i.entries) + 1
+ return nil
+}
+
+type entriesByOffset []*Entry
+
+func (o entriesByOffset) Len() int {
+ return len(o)
+}
+
+func (o entriesByOffset) Less(i int, j int) bool {
+ return o[i].Offset < o[j].Offset
+}
+
+func (o entriesByOffset) Swap(i int, j int) {
+ o[i], o[j] = o[j], o[i]
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/writer.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/writer.go
new file mode 100644
index 00000000..c4c21e16
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/idxfile/writer.go
@@ -0,0 +1,193 @@
+package idxfile
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+ "sort"
+ "sync"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/utils/binary"
+)
+
+// objects implements sort.Interface and uses hash as sorting key.
+type objects []Entry
+
+// Writer implements a packfile Observer interface and is used to generate
+// indexes.
+type Writer struct {
+ m sync.Mutex
+
+ count uint32
+ checksum plumbing.Hash
+ objects objects
+ offset64 uint32
+ finished bool
+ index *MemoryIndex
+ added map[plumbing.Hash]struct{}
+}
+
+// Index returns a previously created MemoryIndex or creates a new one if
+// needed.
+func (w *Writer) Index() (*MemoryIndex, error) {
+ w.m.Lock()
+ defer w.m.Unlock()
+
+ if w.index == nil {
+ return w.createIndex()
+ }
+
+ return w.index, nil
+}
+
+// Add appends new object data.
+func (w *Writer) Add(h plumbing.Hash, pos uint64, crc uint32) {
+ w.m.Lock()
+ defer w.m.Unlock()
+
+ if w.added == nil {
+ w.added = make(map[plumbing.Hash]struct{})
+ }
+
+ if _, ok := w.added[h]; !ok {
+ w.added[h] = struct{}{}
+ w.objects = append(w.objects, Entry{h, crc, pos})
+ }
+
+}
+
+func (w *Writer) Finished() bool {
+ return w.finished
+}
+
+// OnHeader implements packfile.Observer interface.
+func (w *Writer) OnHeader(count uint32) error {
+ w.count = count
+ w.objects = make(objects, 0, count)
+ return nil
+}
+
+// OnInflatedObjectHeader implements packfile.Observer interface.
+func (w *Writer) OnInflatedObjectHeader(t plumbing.ObjectType, objSize int64, pos int64) error {
+ return nil
+}
+
+// OnInflatedObjectContent implements packfile.Observer interface.
+func (w *Writer) OnInflatedObjectContent(h plumbing.Hash, pos int64, crc uint32, _ []byte) error {
+ w.Add(h, uint64(pos), crc)
+ return nil
+}
+
+// OnFooter implements packfile.Observer interface.
+func (w *Writer) OnFooter(h plumbing.Hash) error {
+ w.checksum = h
+ w.finished = true
+ _, err := w.createIndex()
+
+ return err
+}
+
+// creatIndex returns a filled MemoryIndex with the information filled by
+// the observer callbacks.
+func (w *Writer) createIndex() (*MemoryIndex, error) {
+ if !w.finished {
+ return nil, fmt.Errorf("the index still hasn't finished building")
+ }
+
+ idx := new(MemoryIndex)
+ w.index = idx
+
+ sort.Sort(w.objects)
+
+ // unmap all fans by default
+ for i := range idx.FanoutMapping {
+ idx.FanoutMapping[i] = noMapping
+ }
+
+ buf := new(bytes.Buffer)
+
+ last := -1
+ bucket := -1
+ for i, o := range w.objects {
+ fan := o.Hash[0]
+
+ // fill the gaps between fans
+ for j := last + 1; j < int(fan); j++ {
+ idx.Fanout[j] = uint32(i)
+ }
+
+ // update the number of objects for this position
+ idx.Fanout[fan] = uint32(i + 1)
+
+ // we move from one bucket to another, update counters and allocate
+ // memory
+ if last != int(fan) {
+ bucket++
+ idx.FanoutMapping[fan] = bucket
+ last = int(fan)
+
+ idx.Names = append(idx.Names, make([]byte, 0))
+ idx.Offset32 = append(idx.Offset32, make([]byte, 0))
+ idx.CRC32 = append(idx.CRC32, make([]byte, 0))
+ }
+
+ idx.Names[bucket] = append(idx.Names[bucket], o.Hash[:]...)
+
+ offset := o.Offset
+ if offset > math.MaxInt32 {
+ var err error
+ offset, err = w.addOffset64(offset)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ buf.Truncate(0)
+ if err := binary.WriteUint32(buf, uint32(offset)); err != nil {
+ return nil, err
+ }
+ idx.Offset32[bucket] = append(idx.Offset32[bucket], buf.Bytes()...)
+
+ buf.Truncate(0)
+ if err := binary.WriteUint32(buf, o.CRC32); err != nil {
+ return nil, err
+ }
+ idx.CRC32[bucket] = append(idx.CRC32[bucket], buf.Bytes()...)
+ }
+
+ for j := last + 1; j < 256; j++ {
+ idx.Fanout[j] = uint32(len(w.objects))
+ }
+
+ idx.Version = VersionSupported
+ idx.PackfileChecksum = w.checksum
+
+ return idx, nil
+}
+
+func (w *Writer) addOffset64(pos uint64) (uint64, error) {
+ buf := new(bytes.Buffer)
+ if err := binary.WriteUint64(buf, pos); err != nil {
+ return 0, err
+ }
+
+ w.index.Offset64 = append(w.index.Offset64, buf.Bytes()...)
+ index := uint64(w.offset64 | (1 << 31))
+ w.offset64++
+
+ return index, nil
+}
+
+func (o objects) Len() int {
+ return len(o)
+}
+
+func (o objects) Less(i int, j int) bool {
+ cmp := bytes.Compare(o[i].Hash[:], o[j].Hash[:])
+ return cmp < 0
+}
+
+func (o objects) Swap(i int, j int) {
+ o[i], o[j] = o[j], o[i]
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/decoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/decoder.go
new file mode 100644
index 00000000..6778cf74
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/decoder.go
@@ -0,0 +1,478 @@
+package index
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "io"
+
+ "strconv"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/hash"
+ "github.com/go-git/go-git/v5/utils/binary"
+)
+
+var (
+ // DecodeVersionSupported is the range of supported index versions
+ DecodeVersionSupported = struct{ Min, Max uint32 }{Min: 2, Max: 4}
+
+ // ErrMalformedSignature is returned by Decode when the index header file is
+ // malformed
+ ErrMalformedSignature = errors.New("malformed index signature file")
+ // ErrInvalidChecksum is returned by Decode if the SHA1 hash mismatch with
+ // the read content
+ ErrInvalidChecksum = errors.New("invalid checksum")
+
+ errUnknownExtension = errors.New("unknown extension")
+)
+
+const (
+ entryHeaderLength = 62
+ entryExtended = 0x4000
+ entryValid = 0x8000
+ nameMask = 0xfff
+ intentToAddMask = 1 << 13
+ skipWorkTreeMask = 1 << 14
+)
+
+// A Decoder reads and decodes index files from an input stream.
+type Decoder struct {
+ r io.Reader
+ hash hash.Hash
+ lastEntry *Entry
+
+ extReader *bufio.Reader
+}
+
+// NewDecoder returns a new decoder that reads from r.
+func NewDecoder(r io.Reader) *Decoder {
+ h := hash.New(hash.CryptoType)
+ return &Decoder{
+ r: io.TeeReader(r, h),
+ hash: h,
+ extReader: bufio.NewReader(nil),
+ }
+}
+
+// Decode reads the whole index object from its input and stores it in the
+// value pointed to by idx.
+func (d *Decoder) Decode(idx *Index) error {
+ var err error
+ idx.Version, err = validateHeader(d.r)
+ if err != nil {
+ return err
+ }
+
+ entryCount, err := binary.ReadUint32(d.r)
+ if err != nil {
+ return err
+ }
+
+ if err := d.readEntries(idx, int(entryCount)); err != nil {
+ return err
+ }
+
+ return d.readExtensions(idx)
+}
+
+func (d *Decoder) readEntries(idx *Index, count int) error {
+ for i := 0; i < count; i++ {
+ e, err := d.readEntry(idx)
+ if err != nil {
+ return err
+ }
+
+ d.lastEntry = e
+ idx.Entries = append(idx.Entries, e)
+ }
+
+ return nil
+}
+
+func (d *Decoder) readEntry(idx *Index) (*Entry, error) {
+ e := &Entry{}
+
+ var msec, mnsec, sec, nsec uint32
+ var flags uint16
+
+ flow := []interface{}{
+ &sec, &nsec,
+ &msec, &mnsec,
+ &e.Dev,
+ &e.Inode,
+ &e.Mode,
+ &e.UID,
+ &e.GID,
+ &e.Size,
+ &e.Hash,
+ &flags,
+ }
+
+ if err := binary.Read(d.r, flow...); err != nil {
+ return nil, err
+ }
+
+ read := entryHeaderLength
+
+ if sec != 0 || nsec != 0 {
+ e.CreatedAt = time.Unix(int64(sec), int64(nsec))
+ }
+
+ if msec != 0 || mnsec != 0 {
+ e.ModifiedAt = time.Unix(int64(msec), int64(mnsec))
+ }
+
+ e.Stage = Stage(flags>>12) & 0x3
+
+ if flags&entryExtended != 0 {
+ extended, err := binary.ReadUint16(d.r)
+ if err != nil {
+ return nil, err
+ }
+
+ read += 2
+ e.IntentToAdd = extended&intentToAddMask != 0
+ e.SkipWorktree = extended&skipWorkTreeMask != 0
+ }
+
+ if err := d.readEntryName(idx, e, flags); err != nil {
+ return nil, err
+ }
+
+ return e, d.padEntry(idx, e, read)
+}
+
+func (d *Decoder) readEntryName(idx *Index, e *Entry, flags uint16) error {
+ var name string
+ var err error
+
+ switch idx.Version {
+ case 2, 3:
+ len := flags & nameMask
+ name, err = d.doReadEntryName(len)
+ case 4:
+ name, err = d.doReadEntryNameV4()
+ default:
+ return ErrUnsupportedVersion
+ }
+
+ if err != nil {
+ return err
+ }
+
+ e.Name = name
+ return nil
+}
+
+func (d *Decoder) doReadEntryNameV4() (string, error) {
+ l, err := binary.ReadVariableWidthInt(d.r)
+ if err != nil {
+ return "", err
+ }
+
+ var base string
+ if d.lastEntry != nil {
+ base = d.lastEntry.Name[:len(d.lastEntry.Name)-int(l)]
+ }
+
+ name, err := binary.ReadUntil(d.r, '\x00')
+ if err != nil {
+ return "", err
+ }
+
+ return base + string(name), nil
+}
+
+func (d *Decoder) doReadEntryName(len uint16) (string, error) {
+ name := make([]byte, len)
+ _, err := io.ReadFull(d.r, name)
+
+ return string(name), err
+}
+
+// Index entries are padded out to the next 8 byte alignment
+// for historical reasons related to how C Git read the files.
+func (d *Decoder) padEntry(idx *Index, e *Entry, read int) error {
+ if idx.Version == 4 {
+ return nil
+ }
+
+ entrySize := read + len(e.Name)
+ padLen := 8 - entrySize%8
+ _, err := io.CopyN(io.Discard, d.r, int64(padLen))
+ return err
+}
+
+func (d *Decoder) readExtensions(idx *Index) error {
+ // TODO: support 'Split index' and 'Untracked cache' extensions, take in
+ // count that they are not supported by jgit or libgit
+
+ var expected []byte
+ var err error
+
+ var header [4]byte
+ for {
+ expected = d.hash.Sum(nil)
+
+ var n int
+ if n, err = io.ReadFull(d.r, header[:]); err != nil {
+ if n == 0 {
+ err = io.EOF
+ }
+
+ break
+ }
+
+ err = d.readExtension(idx, header[:])
+ if err != nil {
+ break
+ }
+ }
+
+ if err != errUnknownExtension {
+ return err
+ }
+
+ return d.readChecksum(expected, header)
+}
+
+func (d *Decoder) readExtension(idx *Index, header []byte) error {
+ switch {
+ case bytes.Equal(header, treeExtSignature):
+ r, err := d.getExtensionReader()
+ if err != nil {
+ return err
+ }
+
+ idx.Cache = &Tree{}
+ d := &treeExtensionDecoder{r}
+ if err := d.Decode(idx.Cache); err != nil {
+ return err
+ }
+ case bytes.Equal(header, resolveUndoExtSignature):
+ r, err := d.getExtensionReader()
+ if err != nil {
+ return err
+ }
+
+ idx.ResolveUndo = &ResolveUndo{}
+ d := &resolveUndoDecoder{r}
+ if err := d.Decode(idx.ResolveUndo); err != nil {
+ return err
+ }
+ case bytes.Equal(header, endOfIndexEntryExtSignature):
+ r, err := d.getExtensionReader()
+ if err != nil {
+ return err
+ }
+
+ idx.EndOfIndexEntry = &EndOfIndexEntry{}
+ d := &endOfIndexEntryDecoder{r}
+ if err := d.Decode(idx.EndOfIndexEntry); err != nil {
+ return err
+ }
+ default:
+ return errUnknownExtension
+ }
+
+ return nil
+}
+
+func (d *Decoder) getExtensionReader() (*bufio.Reader, error) {
+ len, err := binary.ReadUint32(d.r)
+ if err != nil {
+ return nil, err
+ }
+
+ d.extReader.Reset(&io.LimitedReader{R: d.r, N: int64(len)})
+ return d.extReader, nil
+}
+
+func (d *Decoder) readChecksum(expected []byte, alreadyRead [4]byte) error {
+ var h plumbing.Hash
+ copy(h[:4], alreadyRead[:])
+
+ if _, err := io.ReadFull(d.r, h[4:]); err != nil {
+ return err
+ }
+
+ if !bytes.Equal(h[:], expected) {
+ return ErrInvalidChecksum
+ }
+
+ return nil
+}
+
+func validateHeader(r io.Reader) (version uint32, err error) {
+ var s = make([]byte, 4)
+ if _, err := io.ReadFull(r, s); err != nil {
+ return 0, err
+ }
+
+ if !bytes.Equal(s, indexSignature) {
+ return 0, ErrMalformedSignature
+ }
+
+ version, err = binary.ReadUint32(r)
+ if err != nil {
+ return 0, err
+ }
+
+ if version < DecodeVersionSupported.Min || version > DecodeVersionSupported.Max {
+ return 0, ErrUnsupportedVersion
+ }
+
+ return
+}
+
+type treeExtensionDecoder struct {
+ r *bufio.Reader
+}
+
+func (d *treeExtensionDecoder) Decode(t *Tree) error {
+ for {
+ e, err := d.readEntry()
+ if err != nil {
+ if err == io.EOF {
+ return nil
+ }
+
+ return err
+ }
+
+ if e == nil {
+ continue
+ }
+
+ t.Entries = append(t.Entries, *e)
+ }
+}
+
+func (d *treeExtensionDecoder) readEntry() (*TreeEntry, error) {
+ e := &TreeEntry{}
+
+ path, err := binary.ReadUntil(d.r, '\x00')
+ if err != nil {
+ return nil, err
+ }
+
+ e.Path = string(path)
+
+ count, err := binary.ReadUntil(d.r, ' ')
+ if err != nil {
+ return nil, err
+ }
+
+ i, err := strconv.Atoi(string(count))
+ if err != nil {
+ return nil, err
+ }
+
+ // An entry can be in an invalidated state and is represented by having a
+ // negative number in the entry_count field.
+ if i == -1 {
+ return nil, nil
+ }
+
+ e.Entries = i
+ trees, err := binary.ReadUntil(d.r, '\n')
+ if err != nil {
+ return nil, err
+ }
+
+ i, err = strconv.Atoi(string(trees))
+ if err != nil {
+ return nil, err
+ }
+
+ e.Trees = i
+ _, err = io.ReadFull(d.r, e.Hash[:])
+ if err != nil {
+ return nil, err
+ }
+ return e, nil
+}
+
+type resolveUndoDecoder struct {
+ r *bufio.Reader
+}
+
+func (d *resolveUndoDecoder) Decode(ru *ResolveUndo) error {
+ for {
+ e, err := d.readEntry()
+ if err != nil {
+ if err == io.EOF {
+ return nil
+ }
+
+ return err
+ }
+
+ ru.Entries = append(ru.Entries, *e)
+ }
+}
+
+func (d *resolveUndoDecoder) readEntry() (*ResolveUndoEntry, error) {
+ e := &ResolveUndoEntry{
+ Stages: make(map[Stage]plumbing.Hash),
+ }
+
+ path, err := binary.ReadUntil(d.r, '\x00')
+ if err != nil {
+ return nil, err
+ }
+
+ e.Path = string(path)
+
+ for i := 0; i < 3; i++ {
+ if err := d.readStage(e, Stage(i+1)); err != nil {
+ return nil, err
+ }
+ }
+
+ for s := range e.Stages {
+ var hash plumbing.Hash
+ if _, err := io.ReadFull(d.r, hash[:]); err != nil {
+ return nil, err
+ }
+
+ e.Stages[s] = hash
+ }
+
+ return e, nil
+}
+
+func (d *resolveUndoDecoder) readStage(e *ResolveUndoEntry, s Stage) error {
+ ascii, err := binary.ReadUntil(d.r, '\x00')
+ if err != nil {
+ return err
+ }
+
+ stage, err := strconv.ParseInt(string(ascii), 8, 64)
+ if err != nil {
+ return err
+ }
+
+ if stage != 0 {
+ e.Stages[s] = plumbing.ZeroHash
+ }
+
+ return nil
+}
+
+type endOfIndexEntryDecoder struct {
+ r *bufio.Reader
+}
+
+func (d *endOfIndexEntryDecoder) Decode(e *EndOfIndexEntry) error {
+ var err error
+ e.Offset, err = binary.ReadUint32(d.r)
+ if err != nil {
+ return err
+ }
+
+ _, err = io.ReadFull(d.r, e.Hash[:])
+ return err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/doc.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/doc.go
new file mode 100644
index 00000000..39ae6ad5
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/doc.go
@@ -0,0 +1,360 @@
+// Package index implements encoding and decoding of index format files.
+//
+// Git index format
+// ================
+//
+// == The Git index file has the following format
+//
+// All binary numbers are in network byte order. Version 2 is described
+// here unless stated otherwise.
+//
+// - A 12-byte header consisting of
+//
+// 4-byte signature:
+// The signature is { 'D', 'I', 'R', 'C' } (stands for "dircache")
+//
+// 4-byte version number:
+// The current supported versions are 2, 3 and 4.
+//
+// 32-bit number of index entries.
+//
+// - A number of sorted index entries (see below).
+//
+// - Extensions
+//
+// Extensions are identified by signature. Optional extensions can
+// be ignored if Git does not understand them.
+//
+// Git currently supports cached tree and resolve undo extensions.
+//
+// 4-byte extension signature. If the first byte is 'A'..'Z' the
+// extension is optional and can be ignored.
+//
+// 32-bit size of the extension
+//
+// Extension data
+//
+// - 160-bit SHA-1 over the content of the index file before this
+// checksum.
+//
+// == Index entry
+//
+// Index entries are sorted in ascending order on the name field,
+// interpreted as a string of unsigned bytes (i.e. memcmp() order, no
+// localization, no special casing of directory separator '/'). Entries
+// with the same name are sorted by their stage field.
+//
+// 32-bit ctime seconds, the last time a file's metadata changed
+// this is stat(2) data
+//
+// 32-bit ctime nanosecond fractions
+// this is stat(2) data
+//
+// 32-bit mtime seconds, the last time a file's data changed
+// this is stat(2) data
+//
+// 32-bit mtime nanosecond fractions
+// this is stat(2) data
+//
+// 32-bit dev
+// this is stat(2) data
+//
+// 32-bit ino
+// this is stat(2) data
+//
+// 32-bit mode, split into (high to low bits)
+//
+// 4-bit object type
+// valid values in binary are 1000 (regular file), 1010 (symbolic link)
+// and 1110 (gitlink)
+//
+// 3-bit unused
+//
+// 9-bit unix permission. Only 0755 and 0644 are valid for regular files.
+// Symbolic links and gitlinks have value 0 in this field.
+//
+// 32-bit uid
+// this is stat(2) data
+//
+// 32-bit gid
+// this is stat(2) data
+//
+// 32-bit file size
+// This is the on-disk size from stat(2), truncated to 32-bit.
+//
+// 160-bit SHA-1 for the represented object
+//
+// A 16-bit 'flags' field split into (high to low bits)
+//
+// 1-bit assume-valid flag
+//
+// 1-bit extended flag (must be zero in version 2)
+//
+// 2-bit stage (during merge)
+//
+// 12-bit name length if the length is less than 0xFFF; otherwise 0xFFF
+// is stored in this field.
+//
+// (Version 3 or later) A 16-bit field, only applicable if the
+// "extended flag" above is 1, split into (high to low bits).
+//
+// 1-bit reserved for future
+//
+// 1-bit skip-worktree flag (used by sparse checkout)
+//
+// 1-bit intent-to-add flag (used by "git add -N")
+//
+// 13-bit unused, must be zero
+//
+// Entry path name (variable length) relative to top level directory
+// (without leading slash). '/' is used as path separator. The special
+// path components ".", ".." and ".git" (without quotes) are disallowed.
+// Trailing slash is also disallowed.
+//
+// The exact encoding is undefined, but the '.' and '/' characters
+// are encoded in 7-bit ASCII and the encoding cannot contain a NUL
+// byte (iow, this is a UNIX pathname).
+//
+// (Version 4) In version 4, the entry path name is prefix-compressed
+// relative to the path name for the previous entry (the very first
+// entry is encoded as if the path name for the previous entry is an
+// empty string). At the beginning of an entry, an integer N in the
+// variable width encoding (the same encoding as the offset is encoded
+// for OFS_DELTA pack entries; see pack-format.txt) is stored, followed
+// by a NUL-terminated string S. Removing N bytes from the end of the
+// path name for the previous entry, and replacing it with the string S
+// yields the path name for this entry.
+//
+// 1-8 nul bytes as necessary to pad the entry to a multiple of eight bytes
+// while keeping the name NUL-terminated.
+//
+// (Version 4) In version 4, the padding after the pathname does not
+// exist.
+//
+// Interpretation of index entries in split index mode is completely
+// different. See below for details.
+//
+// == Extensions
+//
+// === Cached tree
+//
+// Cached tree extension contains pre-computed hashes for trees that can
+// be derived from the index. It helps speed up tree object generation
+// from index for a new commit.
+//
+// When a path is updated in index, the path must be invalidated and
+// removed from tree cache.
+//
+// The signature for this extension is { 'T', 'R', 'E', 'E' }.
+//
+// A series of entries fill the entire extension; each of which
+// consists of:
+//
+// - NUL-terminated path component (relative to its parent directory);
+//
+// - ASCII decimal number of entries in the index that is covered by the
+// tree this entry represents (entry_count);
+//
+// - A space (ASCII 32);
+//
+// - ASCII decimal number that represents the number of subtrees this
+// tree has;
+//
+// - A newline (ASCII 10); and
+//
+// - 160-bit object name for the object that would result from writing
+// this span of index as a tree.
+//
+// An entry can be in an invalidated state and is represented by having
+// a negative number in the entry_count field. In this case, there is no
+// object name and the next entry starts immediately after the newline.
+// When writing an invalid entry, -1 should always be used as entry_count.
+//
+// The entries are written out in the top-down, depth-first order. The
+// first entry represents the root level of the repository, followed by the
+// first subtree--let's call this A--of the root level (with its name
+// relative to the root level), followed by the first subtree of A (with
+// its name relative to A), ...
+//
+// === Resolve undo
+//
+// A conflict is represented in the index as a set of higher stage entries.
+// When a conflict is resolved (e.g. with "git add path"), these higher
+// stage entries will be removed and a stage-0 entry with proper resolution
+// is added.
+//
+// When these higher stage entries are removed, they are saved in the
+// resolve undo extension, so that conflicts can be recreated (e.g. with
+// "git checkout -m"), in case users want to redo a conflict resolution
+// from scratch.
+//
+// The signature for this extension is { 'R', 'E', 'U', 'C' }.
+//
+// A series of entries fill the entire extension; each of which
+// consists of:
+//
+// - NUL-terminated pathname the entry describes (relative to the root of
+// the repository, i.e. full pathname);
+//
+// - Three NUL-terminated ASCII octal numbers, entry mode of entries in
+// stage 1 to 3 (a missing stage is represented by "0" in this field);
+// and
+//
+// - At most three 160-bit object names of the entry in stages from 1 to 3
+// (nothing is written for a missing stage).
+//
+// === Split index
+//
+// In split index mode, the majority of index entries could be stored
+// in a separate file. This extension records the changes to be made on
+// top of that to produce the final index.
+//
+// The signature for this extension is { 'l', 'i', 'n', 'k' }.
+//
+// The extension consists of:
+//
+// - 160-bit SHA-1 of the shared index file. The shared index file path
+// is $GIT_DIR/sharedindex.. If all 160 bits are zero, the
+// index does not require a shared index file.
+//
+// - An ewah-encoded delete bitmap, each bit represents an entry in the
+// shared index. If a bit is set, its corresponding entry in the
+// shared index will be removed from the final index. Note, because
+// a delete operation changes index entry positions, but we do need
+// original positions in replace phase, it's best to just mark
+// entries for removal, then do a mass deletion after replacement.
+//
+// - An ewah-encoded replace bitmap, each bit represents an entry in
+// the shared index. If a bit is set, its corresponding entry in the
+// shared index will be replaced with an entry in this index
+// file. All replaced entries are stored in sorted order in this
+// index. The first "1" bit in the replace bitmap corresponds to the
+// first index entry, the second "1" bit to the second entry and so
+// on. Replaced entries may have empty path names to save space.
+//
+// The remaining index entries after replaced ones will be added to the
+// final index. These added entries are also sorted by entry name then
+// stage.
+//
+// == Untracked cache
+//
+// Untracked cache saves the untracked file list and necessary data to
+// verify the cache. The signature for this extension is { 'U', 'N',
+// 'T', 'R' }.
+//
+// The extension starts with
+//
+// - A sequence of NUL-terminated strings, preceded by the size of the
+// sequence in variable width encoding. Each string describes the
+// environment where the cache can be used.
+//
+// - Stat data of $GIT_DIR/info/exclude. See "Index entry" section from
+// ctime field until "file size".
+//
+// - Stat data of plumbing.excludesfile
+//
+// - 32-bit dir_flags (see struct dir_struct)
+//
+// - 160-bit SHA-1 of $GIT_DIR/info/exclude. Null SHA-1 means the file
+// does not exist.
+//
+// - 160-bit SHA-1 of plumbing.excludesfile. Null SHA-1 means the file does
+// not exist.
+//
+// - NUL-terminated string of per-dir exclude file name. This usually
+// is ".gitignore".
+//
+// - The number of following directory blocks, variable width
+// encoding. If this number is zero, the extension ends here with a
+// following NUL.
+//
+// - A number of directory blocks in depth-first-search order, each
+// consists of
+//
+// - The number of untracked entries, variable width encoding.
+//
+// - The number of sub-directory blocks, variable width encoding.
+//
+// - The directory name terminated by NUL.
+//
+// - A number of untracked file/dir names terminated by NUL.
+//
+// The remaining data of each directory block is grouped by type:
+//
+// - An ewah bitmap, the n-th bit marks whether the n-th directory has
+// valid untracked cache entries.
+//
+// - An ewah bitmap, the n-th bit records "check-only" bit of
+// read_directory_recursive() for the n-th directory.
+//
+// - An ewah bitmap, the n-th bit indicates whether SHA-1 and stat data
+// is valid for the n-th directory and exists in the next data.
+//
+// - An array of stat data. The n-th data corresponds with the n-th
+// "one" bit in the previous ewah bitmap.
+//
+// - An array of SHA-1. The n-th SHA-1 corresponds with the n-th "one" bit
+// in the previous ewah bitmap.
+//
+// - One NUL.
+//
+// == File System Monitor cache
+//
+// The file system monitor cache tracks files for which the core.fsmonitor
+// hook has told us about changes. The signature for this extension is
+// { 'F', 'S', 'M', 'N' }.
+//
+// The extension starts with
+//
+// - 32-bit version number: the current supported version is 1.
+//
+// - 64-bit time: the extension data reflects all changes through the given
+// time which is stored as the nanoseconds elapsed since midnight,
+// January 1, 1970.
+//
+// - 32-bit bitmap size: the size of the CE_FSMONITOR_VALID bitmap.
+//
+// - An ewah bitmap, the n-th bit indicates whether the n-th index entry
+// is not CE_FSMONITOR_VALID.
+//
+// == End of Index Entry
+//
+// The End of Index Entry (EOIE) is used to locate the end of the variable
+// length index entries and the beginning of the extensions. Code can take
+// advantage of this to quickly locate the index extensions without having
+// to parse through all of the index entries.
+//
+// Because it must be able to be loaded before the variable length cache
+// entries and other index extensions, this extension must be written last.
+// The signature for this extension is { 'E', 'O', 'I', 'E' }.
+//
+// The extension consists of:
+//
+// - 32-bit offset to the end of the index entries
+//
+// - 160-bit SHA-1 over the extension types and their sizes (but not
+// their contents). E.g. if we have "TREE" extension that is N-bytes
+// long, "REUC" extension that is M-bytes long, followed by "EOIE",
+// then the hash would be:
+//
+// SHA-1("TREE" + +
+// "REUC" + )
+//
+// == Index Entry Offset Table
+//
+// The Index Entry Offset Table (IEOT) is used to help address the CPU
+// cost of loading the index by enabling multi-threading the process of
+// converting cache entries from the on-disk format to the in-memory format.
+// The signature for this extension is { 'I', 'E', 'O', 'T' }.
+//
+// The extension consists of:
+//
+// - 32-bit version (currently 1)
+//
+// - A number of index offset entries each consisting of:
+//
+// - 32-bit offset from the beginning of the file to the first cache entry
+// in this block of entries.
+//
+// - 32-bit count of cache entries in this blockpackage index
+package index
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/encoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/encoder.go
new file mode 100644
index 00000000..fa2d8144
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/encoder.go
@@ -0,0 +1,165 @@
+package index
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "sort"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing/hash"
+ "github.com/go-git/go-git/v5/utils/binary"
+)
+
+var (
+ // EncodeVersionSupported is the range of supported index versions
+ EncodeVersionSupported uint32 = 3
+
+ // ErrInvalidTimestamp is returned by Encode if a Index with a Entry with
+ // negative timestamp values
+ ErrInvalidTimestamp = errors.New("negative timestamps are not allowed")
+)
+
+// An Encoder writes an Index to an output stream.
+type Encoder struct {
+ w io.Writer
+ hash hash.Hash
+}
+
+// NewEncoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+ h := hash.New(hash.CryptoType)
+ mw := io.MultiWriter(w, h)
+ return &Encoder{mw, h}
+}
+
+// Encode writes the Index to the stream of the encoder.
+func (e *Encoder) Encode(idx *Index) error {
+ // TODO: support v4
+ // TODO: support extensions
+ if idx.Version > EncodeVersionSupported {
+ return ErrUnsupportedVersion
+ }
+
+ if err := e.encodeHeader(idx); err != nil {
+ return err
+ }
+
+ if err := e.encodeEntries(idx); err != nil {
+ return err
+ }
+
+ return e.encodeFooter()
+}
+
+func (e *Encoder) encodeHeader(idx *Index) error {
+ return binary.Write(e.w,
+ indexSignature,
+ idx.Version,
+ uint32(len(idx.Entries)),
+ )
+}
+
+func (e *Encoder) encodeEntries(idx *Index) error {
+ sort.Sort(byName(idx.Entries))
+
+ for _, entry := range idx.Entries {
+ if err := e.encodeEntry(entry); err != nil {
+ return err
+ }
+ entryLength := entryHeaderLength
+ if entry.IntentToAdd || entry.SkipWorktree {
+ entryLength += 2
+ }
+
+ wrote := entryLength + len(entry.Name)
+ if err := e.padEntry(wrote); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (e *Encoder) encodeEntry(entry *Entry) error {
+ sec, nsec, err := e.timeToUint32(&entry.CreatedAt)
+ if err != nil {
+ return err
+ }
+
+ msec, mnsec, err := e.timeToUint32(&entry.ModifiedAt)
+ if err != nil {
+ return err
+ }
+
+ flags := uint16(entry.Stage&0x3) << 12
+ if l := len(entry.Name); l < nameMask {
+ flags |= uint16(l)
+ } else {
+ flags |= nameMask
+ }
+
+ flow := []interface{}{
+ sec, nsec,
+ msec, mnsec,
+ entry.Dev,
+ entry.Inode,
+ entry.Mode,
+ entry.UID,
+ entry.GID,
+ entry.Size,
+ entry.Hash[:],
+ }
+
+ flagsFlow := []interface{}{flags}
+
+ if entry.IntentToAdd || entry.SkipWorktree {
+ var extendedFlags uint16
+
+ if entry.IntentToAdd {
+ extendedFlags |= intentToAddMask
+ }
+ if entry.SkipWorktree {
+ extendedFlags |= skipWorkTreeMask
+ }
+
+ flagsFlow = []interface{}{flags | entryExtended, extendedFlags}
+ }
+
+ flow = append(flow, flagsFlow...)
+
+ if err := binary.Write(e.w, flow...); err != nil {
+ return err
+ }
+
+ return binary.Write(e.w, []byte(entry.Name))
+}
+
+func (e *Encoder) timeToUint32(t *time.Time) (uint32, uint32, error) {
+ if t.IsZero() {
+ return 0, 0, nil
+ }
+
+ if t.Unix() < 0 || t.UnixNano() < 0 {
+ return 0, 0, ErrInvalidTimestamp
+ }
+
+ return uint32(t.Unix()), uint32(t.Nanosecond()), nil
+}
+
+func (e *Encoder) padEntry(wrote int) error {
+ padLen := 8 - wrote%8
+
+ _, err := e.w.Write(bytes.Repeat([]byte{'\x00'}, padLen))
+ return err
+}
+
+func (e *Encoder) encodeFooter() error {
+ return binary.Write(e.w, e.hash.Sum(nil))
+}
+
+type byName []*Entry
+
+func (l byName) Len() int { return len(l) }
+func (l byName) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
+func (l byName) Less(i, j int) bool { return l[i].Name < l[j].Name }
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/index.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/index.go
new file mode 100644
index 00000000..f4c7647d
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/index.go
@@ -0,0 +1,231 @@
+package index
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+)
+
+var (
+ // ErrUnsupportedVersion is returned by Decode when the index file version
+ // is not supported.
+ ErrUnsupportedVersion = errors.New("unsupported version")
+ // ErrEntryNotFound is returned by Index.Entry, if an entry is not found.
+ ErrEntryNotFound = errors.New("entry not found")
+
+ indexSignature = []byte{'D', 'I', 'R', 'C'}
+ treeExtSignature = []byte{'T', 'R', 'E', 'E'}
+ resolveUndoExtSignature = []byte{'R', 'E', 'U', 'C'}
+ endOfIndexEntryExtSignature = []byte{'E', 'O', 'I', 'E'}
+)
+
+// Stage during merge
+type Stage int
+
+const (
+ // Merged is the default stage, fully merged
+ Merged Stage = 1
+ // AncestorMode is the base revision
+ AncestorMode Stage = 1
+ // OurMode is the first tree revision, ours
+ OurMode Stage = 2
+ // TheirMode is the second tree revision, theirs
+ TheirMode Stage = 3
+)
+
+// Index contains the information about which objects are currently checked out
+// in the worktree, having information about the working files. Changes in
+// worktree are detected using this Index. The Index is also used during merges
+type Index struct {
+ // Version is index version
+ Version uint32
+ // Entries collection of entries represented by this Index. The order of
+ // this collection is not guaranteed
+ Entries []*Entry
+ // Cache represents the 'Cached tree' extension
+ Cache *Tree
+ // ResolveUndo represents the 'Resolve undo' extension
+ ResolveUndo *ResolveUndo
+ // EndOfIndexEntry represents the 'End of Index Entry' extension
+ EndOfIndexEntry *EndOfIndexEntry
+}
+
+// Add creates a new Entry and returns it. The caller should first check that
+// another entry with the same path does not exist.
+func (i *Index) Add(path string) *Entry {
+ e := &Entry{
+ Name: filepath.ToSlash(path),
+ }
+
+ i.Entries = append(i.Entries, e)
+ return e
+}
+
+// Entry returns the entry that match the given path, if any.
+func (i *Index) Entry(path string) (*Entry, error) {
+ path = filepath.ToSlash(path)
+ for _, e := range i.Entries {
+ if e.Name == path {
+ return e, nil
+ }
+ }
+
+ return nil, ErrEntryNotFound
+}
+
+// Remove remove the entry that match the give path and returns deleted entry.
+func (i *Index) Remove(path string) (*Entry, error) {
+ path = filepath.ToSlash(path)
+ for index, e := range i.Entries {
+ if e.Name == path {
+ i.Entries = append(i.Entries[:index], i.Entries[index+1:]...)
+ return e, nil
+ }
+ }
+
+ return nil, ErrEntryNotFound
+}
+
+// Glob returns the all entries matching pattern or nil if there is no matching
+// entry. The syntax of patterns is the same as in filepath.Glob.
+func (i *Index) Glob(pattern string) (matches []*Entry, err error) {
+ pattern = filepath.ToSlash(pattern)
+ for _, e := range i.Entries {
+ m, err := match(pattern, e.Name)
+ if err != nil {
+ return nil, err
+ }
+
+ if m {
+ matches = append(matches, e)
+ }
+ }
+
+ return
+}
+
+// String is equivalent to `git ls-files --stage --debug`
+func (i *Index) String() string {
+ buf := bytes.NewBuffer(nil)
+ for _, e := range i.Entries {
+ buf.WriteString(e.String())
+ }
+
+ return buf.String()
+}
+
+// Entry represents a single file (or stage of a file) in the cache. An entry
+// represents exactly one stage of a file. If a file path is unmerged then
+// multiple Entry instances may appear for the same path name.
+type Entry struct {
+ // Hash is the SHA1 of the represented file
+ Hash plumbing.Hash
+ // Name is the Entry path name relative to top level directory
+ Name string
+ // CreatedAt time when the tracked path was created
+ CreatedAt time.Time
+ // ModifiedAt time when the tracked path was changed
+ ModifiedAt time.Time
+ // Dev and Inode of the tracked path
+ Dev, Inode uint32
+ // Mode of the path
+ Mode filemode.FileMode
+ // UID and GID, userid and group id of the owner
+ UID, GID uint32
+ // Size is the length in bytes for regular files
+ Size uint32
+ // Stage on a merge is defines what stage is representing this entry
+ // https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging
+ Stage Stage
+ // SkipWorktree used in sparse checkouts
+ // https://git-scm.com/docs/git-read-tree#_sparse_checkout
+ SkipWorktree bool
+ // IntentToAdd record only the fact that the path will be added later
+ // https://git-scm.com/docs/git-add ("git add -N")
+ IntentToAdd bool
+}
+
+func (e Entry) String() string {
+ buf := bytes.NewBuffer(nil)
+
+ fmt.Fprintf(buf, "%06o %s %d\t%s\n", e.Mode, e.Hash, e.Stage, e.Name)
+ fmt.Fprintf(buf, " ctime: %d:%d\n", e.CreatedAt.Unix(), e.CreatedAt.Nanosecond())
+ fmt.Fprintf(buf, " mtime: %d:%d\n", e.ModifiedAt.Unix(), e.ModifiedAt.Nanosecond())
+ fmt.Fprintf(buf, " dev: %d\tino: %d\n", e.Dev, e.Inode)
+ fmt.Fprintf(buf, " uid: %d\tgid: %d\n", e.UID, e.GID)
+ fmt.Fprintf(buf, " size: %d\tflags: %x\n", e.Size, 0)
+
+ return buf.String()
+}
+
+// Tree contains pre-computed hashes for trees that can be derived from the
+// index. It helps speed up tree object generation from index for a new commit.
+type Tree struct {
+ Entries []TreeEntry
+}
+
+// TreeEntry entry of a cached Tree
+type TreeEntry struct {
+ // Path component (relative to its parent directory)
+ Path string
+ // Entries is the number of entries in the index that is covered by the tree
+ // this entry represents.
+ Entries int
+ // Trees is the number that represents the number of subtrees this tree has
+ Trees int
+ // Hash object name for the object that would result from writing this span
+ // of index as a tree.
+ Hash plumbing.Hash
+}
+
+// ResolveUndo is used when a conflict is resolved (e.g. with "git add path"),
+// these higher stage entries are removed and a stage-0 entry with proper
+// resolution is added. When these higher stage entries are removed, they are
+// saved in the resolve undo extension.
+type ResolveUndo struct {
+ Entries []ResolveUndoEntry
+}
+
+// ResolveUndoEntry contains the information about a conflict when is resolved
+type ResolveUndoEntry struct {
+ Path string
+ Stages map[Stage]plumbing.Hash
+}
+
+// EndOfIndexEntry is the End of Index Entry (EOIE) is used to locate the end of
+// the variable length index entries and the beginning of the extensions. Code
+// can take advantage of this to quickly locate the index extensions without
+// having to parse through all of the index entries.
+//
+// Because it must be able to be loaded before the variable length cache
+// entries and other index extensions, this extension must be written last.
+type EndOfIndexEntry struct {
+ // Offset to the end of the index entries
+ Offset uint32
+ // Hash is a SHA-1 over the extension types and their sizes (but not
+ // their contents).
+ Hash plumbing.Hash
+}
+
+// SkipUnless applies patterns in the form of A, A/B, A/B/C
+// to the index to prevent the files from being checked out
+func (i *Index) SkipUnless(patterns []string) {
+ for _, e := range i.Entries {
+ var include bool
+ for _, pattern := range patterns {
+ if strings.HasPrefix(e.Name, pattern) {
+ include = true
+ break
+ }
+ }
+ if !include {
+ e.SkipWorktree = true
+ }
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/index/match.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/match.go
new file mode 100644
index 00000000..2891d7d3
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/index/match.go
@@ -0,0 +1,186 @@
+package index
+
+import (
+ "path/filepath"
+ "runtime"
+ "unicode/utf8"
+)
+
+// match is filepath.Match with support to match fullpath and not only filenames
+// code from:
+// https://github.com/golang/go/blob/39852bf4cce6927e01d0136c7843f65a801738cb/src/path/filepath/match.go#L44-L224
+func match(pattern, name string) (matched bool, err error) {
+Pattern:
+ for len(pattern) > 0 {
+ var star bool
+ var chunk string
+ star, chunk, pattern = scanChunk(pattern)
+
+ // Look for match at current position.
+ t, ok, err := matchChunk(chunk, name)
+ // if we're the last chunk, make sure we've exhausted the name
+ // otherwise we'll give a false result even if we could still match
+ // using the star
+ if ok && (len(t) == 0 || len(pattern) > 0) {
+ name = t
+ continue
+ }
+ if err != nil {
+ return false, err
+ }
+ if star {
+ // Look for match skipping i+1 bytes.
+ // Cannot skip /.
+ for i := 0; i < len(name); i++ {
+ t, ok, err := matchChunk(chunk, name[i+1:])
+ if ok {
+ // if we're the last chunk, make sure we exhausted the name
+ if len(pattern) == 0 && len(t) > 0 {
+ continue
+ }
+ name = t
+ continue Pattern
+ }
+ if err != nil {
+ return false, err
+ }
+ }
+ }
+ return false, nil
+ }
+ return len(name) == 0, nil
+}
+
+// scanChunk gets the next segment of pattern, which is a non-star string
+// possibly preceded by a star.
+func scanChunk(pattern string) (star bool, chunk, rest string) {
+ for len(pattern) > 0 && pattern[0] == '*' {
+ pattern = pattern[1:]
+ star = true
+ }
+ inrange := false
+ var i int
+Scan:
+ for i = 0; i < len(pattern); i++ {
+ switch pattern[i] {
+ case '\\':
+ if runtime.GOOS != "windows" {
+ // error check handled in matchChunk: bad pattern.
+ if i+1 < len(pattern) {
+ i++
+ }
+ }
+ case '[':
+ inrange = true
+ case ']':
+ inrange = false
+ case '*':
+ if !inrange {
+ break Scan
+ }
+ }
+ }
+ return star, pattern[0:i], pattern[i:]
+}
+
+// matchChunk checks whether chunk matches the beginning of s.
+// If so, it returns the remainder of s (after the match).
+// Chunk is all single-character operators: literals, char classes, and ?.
+func matchChunk(chunk, s string) (rest string, ok bool, err error) {
+ for len(chunk) > 0 {
+ if len(s) == 0 {
+ return
+ }
+ switch chunk[0] {
+ case '[':
+ // character class
+ r, n := utf8.DecodeRuneInString(s)
+ s = s[n:]
+ chunk = chunk[1:]
+ // We can't end right after '[', we're expecting at least
+ // a closing bracket and possibly a caret.
+ if len(chunk) == 0 {
+ err = filepath.ErrBadPattern
+ return
+ }
+ // possibly negated
+ negated := chunk[0] == '^'
+ if negated {
+ chunk = chunk[1:]
+ }
+ // parse all ranges
+ match := false
+ nrange := 0
+ for {
+ if len(chunk) > 0 && chunk[0] == ']' && nrange > 0 {
+ chunk = chunk[1:]
+ break
+ }
+ var lo, hi rune
+ if lo, chunk, err = getEsc(chunk); err != nil {
+ return
+ }
+ hi = lo
+ if chunk[0] == '-' {
+ if hi, chunk, err = getEsc(chunk[1:]); err != nil {
+ return
+ }
+ }
+ if lo <= r && r <= hi {
+ match = true
+ }
+ nrange++
+ }
+ if match == negated {
+ return
+ }
+
+ case '?':
+ _, n := utf8.DecodeRuneInString(s)
+ s = s[n:]
+ chunk = chunk[1:]
+
+ case '\\':
+ if runtime.GOOS != "windows" {
+ chunk = chunk[1:]
+ if len(chunk) == 0 {
+ err = filepath.ErrBadPattern
+ return
+ }
+ }
+ fallthrough
+
+ default:
+ if chunk[0] != s[0] {
+ return
+ }
+ s = s[1:]
+ chunk = chunk[1:]
+ }
+ }
+ return s, true, nil
+}
+
+// getEsc gets a possibly-escaped character from chunk, for a character class.
+func getEsc(chunk string) (r rune, nchunk string, err error) {
+ if len(chunk) == 0 || chunk[0] == '-' || chunk[0] == ']' {
+ err = filepath.ErrBadPattern
+ return
+ }
+ if chunk[0] == '\\' && runtime.GOOS != "windows" {
+ chunk = chunk[1:]
+ if len(chunk) == 0 {
+ err = filepath.ErrBadPattern
+ return
+ }
+ }
+ r, n := utf8.DecodeRuneInString(chunk)
+ if r == utf8.RuneError && n == 1 {
+ err = filepath.ErrBadPattern
+ }
+ nchunk = chunk[n:]
+ if len(nchunk) == 0 {
+ err = filepath.ErrBadPattern
+ }
+ return
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/doc.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/doc.go
new file mode 100644
index 00000000..a7145160
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/doc.go
@@ -0,0 +1,2 @@
+// Package objfile implements encoding and decoding of object files.
+package objfile
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/reader.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/reader.go
new file mode 100644
index 00000000..d7932f4e
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/reader.go
@@ -0,0 +1,117 @@
+package objfile
+
+import (
+ "errors"
+ "io"
+ "strconv"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/packfile"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+var (
+ ErrClosed = errors.New("objfile: already closed")
+ ErrHeader = errors.New("objfile: invalid header")
+ ErrNegativeSize = errors.New("objfile: negative object size")
+)
+
+// Reader reads and decodes compressed objfile data from a provided io.Reader.
+// Reader implements io.ReadCloser. Close should be called when finished with
+// the Reader. Close will not close the underlying io.Reader.
+type Reader struct {
+ multi io.Reader
+ zlib io.Reader
+ zlibref sync.ZLibReader
+ hasher plumbing.Hasher
+}
+
+// NewReader returns a new Reader reading from r.
+func NewReader(r io.Reader) (*Reader, error) {
+ zlib, err := sync.GetZlibReader(r)
+ if err != nil {
+ return nil, packfile.ErrZLib.AddDetails(err.Error())
+ }
+
+ return &Reader{
+ zlib: zlib.Reader,
+ zlibref: zlib,
+ }, nil
+}
+
+// Header reads the type and the size of object, and prepares the reader for read
+func (r *Reader) Header() (t plumbing.ObjectType, size int64, err error) {
+ var raw []byte
+ raw, err = r.readUntil(' ')
+ if err != nil {
+ return
+ }
+
+ t, err = plumbing.ParseObjectType(string(raw))
+ if err != nil {
+ return
+ }
+
+ raw, err = r.readUntil(0)
+ if err != nil {
+ return
+ }
+
+ size, err = strconv.ParseInt(string(raw), 10, 64)
+ if err != nil {
+ err = ErrHeader
+ return
+ }
+
+ defer r.prepareForRead(t, size)
+ return
+}
+
+// readSlice reads one byte at a time from r until it encounters delim or an
+// error.
+func (r *Reader) readUntil(delim byte) ([]byte, error) {
+ var buf [1]byte
+ value := make([]byte, 0, 16)
+ for {
+ if n, err := r.zlib.Read(buf[:]); err != nil && (err != io.EOF || n == 0) {
+ if err == io.EOF {
+ return nil, ErrHeader
+ }
+ return nil, err
+ }
+
+ if buf[0] == delim {
+ return value, nil
+ }
+
+ value = append(value, buf[0])
+ }
+}
+
+func (r *Reader) prepareForRead(t plumbing.ObjectType, size int64) {
+ r.hasher = plumbing.NewHasher(t, size)
+ r.multi = io.TeeReader(r.zlib, r.hasher)
+}
+
+// Read reads len(p) bytes into p from the object data stream. It returns
+// the number of bytes read (0 <= n <= len(p)) and any error encountered. Even
+// if Read returns n < len(p), it may use all of p as scratch space during the
+// call.
+//
+// If Read encounters the end of the data stream it will return err == io.EOF,
+// either in the current call if n > 0 or in a subsequent call.
+func (r *Reader) Read(p []byte) (n int, err error) {
+ return r.multi.Read(p)
+}
+
+// Hash returns the hash of the object data stream that has been read so far.
+func (r *Reader) Hash() plumbing.Hash {
+ return r.hasher.Sum()
+}
+
+// Close releases any resources consumed by the Reader. Calling Close does not
+// close the wrapped io.Reader originally passed to NewReader.
+func (r *Reader) Close() error {
+ sync.PutZlibReader(r.zlibref)
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/writer.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/writer.go
new file mode 100644
index 00000000..0d0f1549
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/objfile/writer.go
@@ -0,0 +1,112 @@
+package objfile
+
+import (
+ "compress/zlib"
+ "errors"
+ "io"
+ "strconv"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+var (
+ ErrOverflow = errors.New("objfile: declared data length exceeded (overflow)")
+)
+
+// Writer writes and encodes data in compressed objfile format to a provided
+// io.Writer. Close should be called when finished with the Writer. Close will
+// not close the underlying io.Writer.
+type Writer struct {
+ raw io.Writer
+ hasher plumbing.Hasher
+ multi io.Writer
+ zlib *zlib.Writer
+
+ closed bool
+ pending int64 // number of unwritten bytes
+}
+
+// NewWriter returns a new Writer writing to w.
+//
+// The returned Writer implements io.WriteCloser. Close should be called when
+// finished with the Writer. Close will not close the underlying io.Writer.
+func NewWriter(w io.Writer) *Writer {
+ zlib := sync.GetZlibWriter(w)
+ return &Writer{
+ raw: w,
+ zlib: zlib,
+ }
+}
+
+// WriteHeader writes the type and the size and prepares to accept the object's
+// contents. If an invalid t is provided, plumbing.ErrInvalidType is returned. If a
+// negative size is provided, ErrNegativeSize is returned.
+func (w *Writer) WriteHeader(t plumbing.ObjectType, size int64) error {
+ if !t.Valid() {
+ return plumbing.ErrInvalidType
+ }
+ if size < 0 {
+ return ErrNegativeSize
+ }
+
+ b := t.Bytes()
+ b = append(b, ' ')
+ b = append(b, []byte(strconv.FormatInt(size, 10))...)
+ b = append(b, 0)
+
+ defer w.prepareForWrite(t, size)
+ _, err := w.zlib.Write(b)
+
+ return err
+}
+
+func (w *Writer) prepareForWrite(t plumbing.ObjectType, size int64) {
+ w.pending = size
+
+ w.hasher = plumbing.NewHasher(t, size)
+ w.multi = io.MultiWriter(w.zlib, w.hasher)
+}
+
+// Write writes the object's contents. Write returns the error ErrOverflow if
+// more than size bytes are written after WriteHeader.
+func (w *Writer) Write(p []byte) (n int, err error) {
+ if w.closed {
+ return 0, ErrClosed
+ }
+
+ overwrite := false
+ if int64(len(p)) > w.pending {
+ p = p[0:w.pending]
+ overwrite = true
+ }
+
+ n, err = w.multi.Write(p)
+ w.pending -= int64(n)
+ if err == nil && overwrite {
+ err = ErrOverflow
+ return
+ }
+
+ return
+}
+
+// Hash returns the hash of the object data stream that has been written so far.
+// It can be called before or after Close.
+func (w *Writer) Hash() plumbing.Hash {
+ return w.hasher.Sum() // Not yet closed, return hash of data written so far
+}
+
+// Close releases any resources consumed by the Writer.
+//
+// Calling Close does not close the wrapped io.Writer originally passed to
+// NewWriter.
+func (w *Writer) Close() error {
+ defer sync.PutZlibWriter(w.zlib)
+ if err := w.zlib.Close(); err != nil {
+ return err
+ }
+
+ w.closed = true
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/common.go
new file mode 100644
index 00000000..36c5ef5b
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/common.go
@@ -0,0 +1,60 @@
+package packfile
+
+import (
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+var signature = []byte{'P', 'A', 'C', 'K'}
+
+const (
+ // VersionSupported is the packfile version supported by this package
+ VersionSupported uint32 = 2
+
+ firstLengthBits = uint8(4) // the first byte into object header has 4 bits to store the length
+ lengthBits = uint8(7) // subsequent bytes has 7 bits to store the length
+ maskFirstLength = 15 // 0000 1111
+ maskContinue = 0x80 // 1000 0000
+ maskLength = uint8(127) // 0111 1111
+ maskType = uint8(112) // 0111 0000
+)
+
+// UpdateObjectStorage updates the storer with the objects in the given
+// packfile.
+func UpdateObjectStorage(s storer.Storer, packfile io.Reader) error {
+ if pw, ok := s.(storer.PackfileWriter); ok {
+ return WritePackfileToObjectStorage(pw, packfile)
+ }
+
+ p, err := NewParserWithStorage(NewScanner(packfile), s)
+ if err != nil {
+ return err
+ }
+
+ _, err = p.Parse()
+ return err
+}
+
+// WritePackfileToObjectStorage writes all the packfile objects into the given
+// object storage.
+func WritePackfileToObjectStorage(
+ sw storer.PackfileWriter,
+ packfile io.Reader,
+) (err error) {
+ w, err := sw.PackfileWriter()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(w, &err)
+
+ var n int64
+ n, err = io.Copy(w, packfile)
+ if err == nil && n == 0 {
+ return ErrEmptyPackfile
+ }
+
+ return err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_index.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_index.go
new file mode 100644
index 00000000..07a61120
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_index.go
@@ -0,0 +1,297 @@
+package packfile
+
+const blksz = 16
+const maxChainLength = 64
+
+// deltaIndex is a modified version of JGit's DeltaIndex adapted to our current
+// design.
+type deltaIndex struct {
+ table []int
+ entries []int
+ mask int
+}
+
+func (idx *deltaIndex) init(buf []byte) {
+ scanner := newDeltaIndexScanner(buf, len(buf))
+ idx.mask = scanner.mask
+ idx.table = scanner.table
+ idx.entries = make([]int, countEntries(scanner)+1)
+ idx.copyEntries(scanner)
+}
+
+// findMatch returns the offset of src where the block starting at tgtOffset
+// is and the length of the match. A length of 0 means there was no match. A
+// length of -1 means the src length is lower than the blksz and whatever
+// other positive length is the length of the match in bytes.
+func (idx *deltaIndex) findMatch(src, tgt []byte, tgtOffset int) (srcOffset, l int) {
+ if len(tgt) < tgtOffset+s {
+ return 0, len(tgt) - tgtOffset
+ }
+
+ if len(src) < blksz {
+ return 0, -1
+ }
+
+ if len(tgt) >= tgtOffset+s && len(src) >= blksz {
+ h := hashBlock(tgt, tgtOffset)
+ tIdx := h & idx.mask
+ eIdx := idx.table[tIdx]
+ if eIdx != 0 {
+ srcOffset = idx.entries[eIdx]
+ } else {
+ return
+ }
+
+ l = matchLength(src, tgt, tgtOffset, srcOffset)
+ }
+
+ return
+}
+
+func matchLength(src, tgt []byte, otgt, osrc int) (l int) {
+ lensrc := len(src)
+ lentgt := len(tgt)
+ for (osrc < lensrc && otgt < lentgt) && src[osrc] == tgt[otgt] {
+ l++
+ osrc++
+ otgt++
+ }
+ return
+}
+
+func countEntries(scan *deltaIndexScanner) (cnt int) {
+ // Figure out exactly how many entries we need. As we do the
+ // enumeration truncate any delta chains longer than what we
+ // are willing to scan during encode. This keeps the encode
+ // logic linear in the size of the input rather than quadratic.
+ for i := 0; i < len(scan.table); i++ {
+ h := scan.table[i]
+ if h == 0 {
+ continue
+ }
+
+ size := 0
+ for {
+ size++
+ if size == maxChainLength {
+ scan.next[h] = 0
+ break
+ }
+ h = scan.next[h]
+
+ if h == 0 {
+ break
+ }
+ }
+ cnt += size
+ }
+
+ return
+}
+
+func (idx *deltaIndex) copyEntries(scanner *deltaIndexScanner) {
+ // Rebuild the entries list from the scanner, positioning all
+ // blocks in the same hash chain next to each other. We can
+ // then later discard the next list, along with the scanner.
+ //
+ next := 1
+ for i := 0; i < len(idx.table); i++ {
+ h := idx.table[i]
+ if h == 0 {
+ continue
+ }
+
+ idx.table[i] = next
+ for {
+ idx.entries[next] = scanner.entries[h]
+ next++
+ h = scanner.next[h]
+
+ if h == 0 {
+ break
+ }
+ }
+ }
+}
+
+type deltaIndexScanner struct {
+ table []int
+ entries []int
+ next []int
+ mask int
+ count int
+}
+
+func newDeltaIndexScanner(buf []byte, size int) *deltaIndexScanner {
+ size -= size % blksz
+ worstCaseBlockCnt := size / blksz
+ if worstCaseBlockCnt < 1 {
+ return new(deltaIndexScanner)
+ }
+
+ tableSize := tableSize(worstCaseBlockCnt)
+ scanner := &deltaIndexScanner{
+ table: make([]int, tableSize),
+ mask: tableSize - 1,
+ entries: make([]int, worstCaseBlockCnt+1),
+ next: make([]int, worstCaseBlockCnt+1),
+ }
+
+ scanner.scan(buf, size)
+ return scanner
+}
+
+// slightly modified version of JGit's DeltaIndexScanner. We store the offset on the entries
+// instead of the entries and the key, so we avoid operations to retrieve the offset later, as
+// we don't use the key.
+// See: https://github.com/eclipse/jgit/blob/005e5feb4ecd08c4e4d141a38b9e7942accb3212/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndexScanner.java
+func (s *deltaIndexScanner) scan(buf []byte, end int) {
+ lastHash := 0
+ ptr := end - blksz
+
+ for {
+ key := hashBlock(buf, ptr)
+ tIdx := key & s.mask
+ head := s.table[tIdx]
+ if head != 0 && lastHash == key {
+ s.entries[head] = ptr
+ } else {
+ s.count++
+ eIdx := s.count
+ s.entries[eIdx] = ptr
+ s.next[eIdx] = head
+ s.table[tIdx] = eIdx
+ }
+
+ lastHash = key
+ ptr -= blksz
+
+ if 0 > ptr {
+ break
+ }
+ }
+}
+
+func tableSize(worstCaseBlockCnt int) int {
+ shift := 32 - leadingZeros(uint32(worstCaseBlockCnt))
+ sz := 1 << uint(shift-1)
+ if sz < worstCaseBlockCnt {
+ sz <<= 1
+ }
+ return sz
+}
+
+// use https://golang.org/pkg/math/bits/#LeadingZeros32 in the future
+func leadingZeros(x uint32) (n int) {
+ if x >= 1<<16 {
+ x >>= 16
+ n = 16
+ }
+ if x >= 1<<8 {
+ x >>= 8
+ n += 8
+ }
+ n += int(len8tab[x])
+ return 32 - n
+}
+
+var len8tab = [256]uint8{
+ 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+}
+
+func hashBlock(raw []byte, ptr int) int {
+ // The first 4 steps collapse out into a 4 byte big-endian decode,
+ // with a larger right shift as we combined shift lefts together.
+ //
+ hash := ((uint32(raw[ptr]) & 0xff) << 24) |
+ ((uint32(raw[ptr+1]) & 0xff) << 16) |
+ ((uint32(raw[ptr+2]) & 0xff) << 8) |
+ (uint32(raw[ptr+3]) & 0xff)
+ hash ^= T[hash>>31]
+
+ hash = ((hash << 8) | (uint32(raw[ptr+4]) & 0xff)) ^ T[hash>>23]
+ hash = ((hash << 8) | (uint32(raw[ptr+5]) & 0xff)) ^ T[hash>>23]
+ hash = ((hash << 8) | (uint32(raw[ptr+6]) & 0xff)) ^ T[hash>>23]
+ hash = ((hash << 8) | (uint32(raw[ptr+7]) & 0xff)) ^ T[hash>>23]
+
+ hash = ((hash << 8) | (uint32(raw[ptr+8]) & 0xff)) ^ T[hash>>23]
+ hash = ((hash << 8) | (uint32(raw[ptr+9]) & 0xff)) ^ T[hash>>23]
+ hash = ((hash << 8) | (uint32(raw[ptr+10]) & 0xff)) ^ T[hash>>23]
+ hash = ((hash << 8) | (uint32(raw[ptr+11]) & 0xff)) ^ T[hash>>23]
+
+ hash = ((hash << 8) | (uint32(raw[ptr+12]) & 0xff)) ^ T[hash>>23]
+ hash = ((hash << 8) | (uint32(raw[ptr+13]) & 0xff)) ^ T[hash>>23]
+ hash = ((hash << 8) | (uint32(raw[ptr+14]) & 0xff)) ^ T[hash>>23]
+ hash = ((hash << 8) | (uint32(raw[ptr+15]) & 0xff)) ^ T[hash>>23]
+
+ return int(hash)
+}
+
+var T = []uint32{0x00000000, 0xd4c6b32d, 0x7d4bd577,
+ 0xa98d665a, 0x2e5119c3, 0xfa97aaee, 0x531accb4, 0x87dc7f99,
+ 0x5ca23386, 0x886480ab, 0x21e9e6f1, 0xf52f55dc, 0x72f32a45,
+ 0xa6359968, 0x0fb8ff32, 0xdb7e4c1f, 0x6d82d421, 0xb944670c,
+ 0x10c90156, 0xc40fb27b, 0x43d3cde2, 0x97157ecf, 0x3e981895,
+ 0xea5eabb8, 0x3120e7a7, 0xe5e6548a, 0x4c6b32d0, 0x98ad81fd,
+ 0x1f71fe64, 0xcbb74d49, 0x623a2b13, 0xb6fc983e, 0x0fc31b6f,
+ 0xdb05a842, 0x7288ce18, 0xa64e7d35, 0x219202ac, 0xf554b181,
+ 0x5cd9d7db, 0x881f64f6, 0x536128e9, 0x87a79bc4, 0x2e2afd9e,
+ 0xfaec4eb3, 0x7d30312a, 0xa9f68207, 0x007be45d, 0xd4bd5770,
+ 0x6241cf4e, 0xb6877c63, 0x1f0a1a39, 0xcbcca914, 0x4c10d68d,
+ 0x98d665a0, 0x315b03fa, 0xe59db0d7, 0x3ee3fcc8, 0xea254fe5,
+ 0x43a829bf, 0x976e9a92, 0x10b2e50b, 0xc4745626, 0x6df9307c,
+ 0xb93f8351, 0x1f8636de, 0xcb4085f3, 0x62cde3a9, 0xb60b5084,
+ 0x31d72f1d, 0xe5119c30, 0x4c9cfa6a, 0x985a4947, 0x43240558,
+ 0x97e2b675, 0x3e6fd02f, 0xeaa96302, 0x6d751c9b, 0xb9b3afb6,
+ 0x103ec9ec, 0xc4f87ac1, 0x7204e2ff, 0xa6c251d2, 0x0f4f3788,
+ 0xdb8984a5, 0x5c55fb3c, 0x88934811, 0x211e2e4b, 0xf5d89d66,
+ 0x2ea6d179, 0xfa606254, 0x53ed040e, 0x872bb723, 0x00f7c8ba,
+ 0xd4317b97, 0x7dbc1dcd, 0xa97aaee0, 0x10452db1, 0xc4839e9c,
+ 0x6d0ef8c6, 0xb9c84beb, 0x3e143472, 0xead2875f, 0x435fe105,
+ 0x97995228, 0x4ce71e37, 0x9821ad1a, 0x31accb40, 0xe56a786d,
+ 0x62b607f4, 0xb670b4d9, 0x1ffdd283, 0xcb3b61ae, 0x7dc7f990,
+ 0xa9014abd, 0x008c2ce7, 0xd44a9fca, 0x5396e053, 0x8750537e,
+ 0x2edd3524, 0xfa1b8609, 0x2165ca16, 0xf5a3793b, 0x5c2e1f61,
+ 0x88e8ac4c, 0x0f34d3d5, 0xdbf260f8, 0x727f06a2, 0xa6b9b58f,
+ 0x3f0c6dbc, 0xebcade91, 0x4247b8cb, 0x96810be6, 0x115d747f,
+ 0xc59bc752, 0x6c16a108, 0xb8d01225, 0x63ae5e3a, 0xb768ed17,
+ 0x1ee58b4d, 0xca233860, 0x4dff47f9, 0x9939f4d4, 0x30b4928e,
+ 0xe47221a3, 0x528eb99d, 0x86480ab0, 0x2fc56cea, 0xfb03dfc7,
+ 0x7cdfa05e, 0xa8191373, 0x01947529, 0xd552c604, 0x0e2c8a1b,
+ 0xdaea3936, 0x73675f6c, 0xa7a1ec41, 0x207d93d8, 0xf4bb20f5,
+ 0x5d3646af, 0x89f0f582, 0x30cf76d3, 0xe409c5fe, 0x4d84a3a4,
+ 0x99421089, 0x1e9e6f10, 0xca58dc3d, 0x63d5ba67, 0xb713094a,
+ 0x6c6d4555, 0xb8abf678, 0x11269022, 0xc5e0230f, 0x423c5c96,
+ 0x96faefbb, 0x3f7789e1, 0xebb13acc, 0x5d4da2f2, 0x898b11df,
+ 0x20067785, 0xf4c0c4a8, 0x731cbb31, 0xa7da081c, 0x0e576e46,
+ 0xda91dd6b, 0x01ef9174, 0xd5292259, 0x7ca44403, 0xa862f72e,
+ 0x2fbe88b7, 0xfb783b9a, 0x52f55dc0, 0x8633eeed, 0x208a5b62,
+ 0xf44ce84f, 0x5dc18e15, 0x89073d38, 0x0edb42a1, 0xda1df18c,
+ 0x739097d6, 0xa75624fb, 0x7c2868e4, 0xa8eedbc9, 0x0163bd93,
+ 0xd5a50ebe, 0x52797127, 0x86bfc20a, 0x2f32a450, 0xfbf4177d,
+ 0x4d088f43, 0x99ce3c6e, 0x30435a34, 0xe485e919, 0x63599680,
+ 0xb79f25ad, 0x1e1243f7, 0xcad4f0da, 0x11aabcc5, 0xc56c0fe8,
+ 0x6ce169b2, 0xb827da9f, 0x3ffba506, 0xeb3d162b, 0x42b07071,
+ 0x9676c35c, 0x2f49400d, 0xfb8ff320, 0x5202957a, 0x86c42657,
+ 0x011859ce, 0xd5deeae3, 0x7c538cb9, 0xa8953f94, 0x73eb738b,
+ 0xa72dc0a6, 0x0ea0a6fc, 0xda6615d1, 0x5dba6a48, 0x897cd965,
+ 0x20f1bf3f, 0xf4370c12, 0x42cb942c, 0x960d2701, 0x3f80415b,
+ 0xeb46f276, 0x6c9a8def, 0xb85c3ec2, 0x11d15898, 0xc517ebb5,
+ 0x1e69a7aa, 0xcaaf1487, 0x632272dd, 0xb7e4c1f0, 0x3038be69,
+ 0xe4fe0d44, 0x4d736b1e, 0x99b5d833,
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_selector.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_selector.go
new file mode 100644
index 00000000..4b60ff39
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/delta_selector.go
@@ -0,0 +1,369 @@
+package packfile
+
+import (
+ "sort"
+ "sync"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+const (
+ // deltas based on deltas, how many steps we can do.
+ // 50 is the default value used in JGit
+ maxDepth = int64(50)
+)
+
+// applyDelta is the set of object types that we should apply deltas
+var applyDelta = map[plumbing.ObjectType]bool{
+ plumbing.BlobObject: true,
+ plumbing.TreeObject: true,
+}
+
+type deltaSelector struct {
+ storer storer.EncodedObjectStorer
+}
+
+func newDeltaSelector(s storer.EncodedObjectStorer) *deltaSelector {
+ return &deltaSelector{s}
+}
+
+// ObjectsToPack creates a list of ObjectToPack from the hashes
+// provided, creating deltas if it's suitable, using an specific
+// internal logic. `packWindow` specifies the size of the sliding
+// window used to compare objects for delta compression; 0 turns off
+// delta compression entirely.
+func (dw *deltaSelector) ObjectsToPack(
+ hashes []plumbing.Hash,
+ packWindow uint,
+) ([]*ObjectToPack, error) {
+ otp, err := dw.objectsToPack(hashes, packWindow)
+ if err != nil {
+ return nil, err
+ }
+
+ if packWindow == 0 {
+ return otp, nil
+ }
+
+ dw.sort(otp)
+
+ var objectGroups [][]*ObjectToPack
+ var prev *ObjectToPack
+ i := -1
+ for _, obj := range otp {
+ if prev == nil || prev.Type() != obj.Type() {
+ objectGroups = append(objectGroups, []*ObjectToPack{obj})
+ i++
+ prev = obj
+ } else {
+ objectGroups[i] = append(objectGroups[i], obj)
+ }
+ }
+
+ var wg sync.WaitGroup
+ var once sync.Once
+ for _, objs := range objectGroups {
+ objs := objs
+ wg.Add(1)
+ go func() {
+ if walkErr := dw.walk(objs, packWindow); walkErr != nil {
+ once.Do(func() {
+ err = walkErr
+ })
+ }
+ wg.Done()
+ }()
+ }
+ wg.Wait()
+
+ if err != nil {
+ return nil, err
+ }
+
+ return otp, nil
+}
+
+func (dw *deltaSelector) objectsToPack(
+ hashes []plumbing.Hash,
+ packWindow uint,
+) ([]*ObjectToPack, error) {
+ var objectsToPack []*ObjectToPack
+ for _, h := range hashes {
+ var o plumbing.EncodedObject
+ var err error
+ if packWindow == 0 {
+ o, err = dw.encodedObject(h)
+ } else {
+ o, err = dw.encodedDeltaObject(h)
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ otp := newObjectToPack(o)
+ if _, ok := o.(plumbing.DeltaObject); ok {
+ otp.CleanOriginal()
+ }
+
+ objectsToPack = append(objectsToPack, otp)
+ }
+
+ if packWindow == 0 {
+ return objectsToPack, nil
+ }
+
+ if err := dw.fixAndBreakChains(objectsToPack); err != nil {
+ return nil, err
+ }
+
+ return objectsToPack, nil
+}
+
+func (dw *deltaSelector) encodedDeltaObject(h plumbing.Hash) (plumbing.EncodedObject, error) {
+ edos, ok := dw.storer.(storer.DeltaObjectStorer)
+ if !ok {
+ return dw.encodedObject(h)
+ }
+
+ return edos.DeltaObject(plumbing.AnyObject, h)
+}
+
+func (dw *deltaSelector) encodedObject(h plumbing.Hash) (plumbing.EncodedObject, error) {
+ return dw.storer.EncodedObject(plumbing.AnyObject, h)
+}
+
+func (dw *deltaSelector) fixAndBreakChains(objectsToPack []*ObjectToPack) error {
+ m := make(map[plumbing.Hash]*ObjectToPack, len(objectsToPack))
+ for _, otp := range objectsToPack {
+ m[otp.Hash()] = otp
+ }
+
+ for _, otp := range objectsToPack {
+ if err := dw.fixAndBreakChainsOne(m, otp); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (dw *deltaSelector) fixAndBreakChainsOne(objectsToPack map[plumbing.Hash]*ObjectToPack, otp *ObjectToPack) error {
+ if !otp.Object.Type().IsDelta() {
+ return nil
+ }
+
+ // Initial ObjectToPack instances might have a delta assigned to Object
+ // but no actual base initially. Once Base is assigned to a delta, it means
+ // we already fixed it.
+ if otp.Base != nil {
+ return nil
+ }
+
+ do, ok := otp.Object.(plumbing.DeltaObject)
+ if !ok {
+ // if this is not a DeltaObject, then we cannot retrieve its base,
+ // so we have to break the delta chain here.
+ return dw.undeltify(otp)
+ }
+
+ base, ok := objectsToPack[do.BaseHash()]
+ if !ok {
+ // The base of the delta is not in our list of objects to pack, so
+ // we break the chain.
+ return dw.undeltify(otp)
+ }
+
+ if err := dw.fixAndBreakChainsOne(objectsToPack, base); err != nil {
+ return err
+ }
+
+ otp.SetDelta(base, otp.Object)
+ return nil
+}
+
+func (dw *deltaSelector) restoreOriginal(otp *ObjectToPack) error {
+ if otp.Original != nil {
+ return nil
+ }
+
+ if !otp.Object.Type().IsDelta() {
+ return nil
+ }
+
+ obj, err := dw.encodedObject(otp.Hash())
+ if err != nil {
+ return err
+ }
+
+ otp.SetOriginal(obj)
+
+ return nil
+}
+
+// undeltify undeltifies an *ObjectToPack by retrieving the original object from
+// the storer and resetting it.
+func (dw *deltaSelector) undeltify(otp *ObjectToPack) error {
+ if err := dw.restoreOriginal(otp); err != nil {
+ return err
+ }
+
+ otp.Object = otp.Original
+ otp.Depth = 0
+ return nil
+}
+
+func (dw *deltaSelector) sort(objectsToPack []*ObjectToPack) {
+ sort.Sort(byTypeAndSize(objectsToPack))
+}
+
+func (dw *deltaSelector) walk(
+ objectsToPack []*ObjectToPack,
+ packWindow uint,
+) error {
+ indexMap := make(map[plumbing.Hash]*deltaIndex)
+ for i := 0; i < len(objectsToPack); i++ {
+ // Clean up the index map and reconstructed delta objects for anything
+ // outside our pack window, to save memory.
+ if i > int(packWindow) {
+ obj := objectsToPack[i-int(packWindow)]
+
+ delete(indexMap, obj.Hash())
+
+ if obj.IsDelta() {
+ obj.SaveOriginalMetadata()
+ obj.CleanOriginal()
+ }
+ }
+
+ target := objectsToPack[i]
+
+ // If we already have a delta, we don't try to find a new one for this
+ // object. This happens when a delta is set to be reused from an existing
+ // packfile.
+ if target.IsDelta() {
+ continue
+ }
+
+ // We only want to create deltas from specific types.
+ if !applyDelta[target.Type()] {
+ continue
+ }
+
+ for j := i - 1; j >= 0 && i-j < int(packWindow); j-- {
+ base := objectsToPack[j]
+ // Objects must use only the same type as their delta base.
+ // Since objectsToPack is sorted by type and size, once we find
+ // a different type, we know we won't find more of them.
+ if base.Type() != target.Type() {
+ break
+ }
+
+ if err := dw.tryToDeltify(indexMap, base, target); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func (dw *deltaSelector) tryToDeltify(indexMap map[plumbing.Hash]*deltaIndex, base, target *ObjectToPack) error {
+ // Original object might not be present if we're reusing a delta, so we
+ // ensure it is restored.
+ if err := dw.restoreOriginal(target); err != nil {
+ return err
+ }
+
+ if err := dw.restoreOriginal(base); err != nil {
+ return err
+ }
+
+ // If the sizes are radically different, this is a bad pairing.
+ if target.Size() < base.Size()>>4 {
+ return nil
+ }
+
+ msz := dw.deltaSizeLimit(
+ target.Object.Size(),
+ base.Depth,
+ target.Depth,
+ target.IsDelta(),
+ )
+
+ // Nearly impossible to fit useful delta.
+ if msz <= 8 {
+ return nil
+ }
+
+ // If we have to insert a lot to make this work, find another.
+ if base.Size()-target.Size() > msz {
+ return nil
+ }
+
+ if _, ok := indexMap[base.Hash()]; !ok {
+ indexMap[base.Hash()] = new(deltaIndex)
+ }
+
+ // Now we can generate the delta using originals
+ delta, err := getDelta(indexMap[base.Hash()], base.Original, target.Original)
+ if err != nil {
+ return err
+ }
+
+ // if delta better than target
+ if delta.Size() < msz {
+ target.SetDelta(base, delta)
+ }
+
+ return nil
+}
+
+func (dw *deltaSelector) deltaSizeLimit(targetSize int64, baseDepth int,
+ targetDepth int, targetDelta bool) int64 {
+ if !targetDelta {
+ // Any delta should be no more than 50% of the original size
+ // (for text files deflate of whole form should shrink 50%).
+ n := targetSize >> 1
+
+ // Evenly distribute delta size limits over allowed depth.
+ // If src is non-delta (depth = 0), delta <= 50% of original.
+ // If src is almost at limit (9/10), delta <= 10% of original.
+ return n * (maxDepth - int64(baseDepth)) / maxDepth
+ }
+
+ // With a delta base chosen any new delta must be "better".
+ // Retain the distribution described above.
+ d := int64(targetDepth)
+ n := targetSize
+
+ // If target depth is bigger than maxDepth, this delta is not suitable to be used.
+ if d >= maxDepth {
+ return 0
+ }
+
+ // If src is whole (depth=0) and base is near limit (depth=9/10)
+ // any delta using src can be 10x larger and still be better.
+ //
+ // If src is near limit (depth=9/10) and base is whole (depth=0)
+ // a new delta dependent on src must be 1/10th the size.
+ return n * (maxDepth - int64(baseDepth)) / (maxDepth - d)
+}
+
+type byTypeAndSize []*ObjectToPack
+
+func (a byTypeAndSize) Len() int { return len(a) }
+
+func (a byTypeAndSize) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+func (a byTypeAndSize) Less(i, j int) bool {
+ if a[i].Type() < a[j].Type() {
+ return false
+ }
+
+ if a[i].Type() > a[j].Type() {
+ return true
+ }
+
+ return a[i].Size() > a[j].Size()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/diff_delta.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/diff_delta.go
new file mode 100644
index 00000000..8898e583
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/diff_delta.go
@@ -0,0 +1,204 @@
+package packfile
+
+import (
+ "bytes"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+// See https://github.com/jelmer/dulwich/blob/master/dulwich/pack.py and
+// https://github.com/tarruda/node-git-core/blob/master/src/js/delta.js
+// for more info
+
+const (
+ // Standard chunk size used to generate fingerprints
+ s = 16
+
+ // https://github.com/git/git/blob/f7466e94375b3be27f229c78873f0acf8301c0a5/diff-delta.c#L428
+ // Max size of a copy operation (64KB).
+ maxCopySize = 64 * 1024
+
+ // Min size of a copy operation.
+ minCopySize = 4
+)
+
+// GetDelta returns an EncodedObject of type OFSDeltaObject. Base and Target object,
+// will be loaded into memory to be able to create the delta object.
+// To generate target again, you will need the obtained object and "base" one.
+// Error will be returned if base or target object cannot be read.
+func GetDelta(base, target plumbing.EncodedObject) (plumbing.EncodedObject, error) {
+ return getDelta(new(deltaIndex), base, target)
+}
+
+func getDelta(index *deltaIndex, base, target plumbing.EncodedObject) (o plumbing.EncodedObject, err error) {
+ br, err := base.Reader()
+ if err != nil {
+ return nil, err
+ }
+
+ defer ioutil.CheckClose(br, &err)
+
+ tr, err := target.Reader()
+ if err != nil {
+ return nil, err
+ }
+
+ defer ioutil.CheckClose(tr, &err)
+
+ bb := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(bb)
+
+ _, err = bb.ReadFrom(br)
+ if err != nil {
+ return nil, err
+ }
+
+ tb := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(tb)
+
+ _, err = tb.ReadFrom(tr)
+ if err != nil {
+ return nil, err
+ }
+
+ db := diffDelta(index, bb.Bytes(), tb.Bytes())
+ delta := &plumbing.MemoryObject{}
+ _, err = delta.Write(db)
+ if err != nil {
+ return nil, err
+ }
+
+ delta.SetSize(int64(len(db)))
+ delta.SetType(plumbing.OFSDeltaObject)
+
+ return delta, nil
+}
+
+// DiffDelta returns the delta that transforms src into tgt.
+func DiffDelta(src, tgt []byte) []byte {
+ return diffDelta(new(deltaIndex), src, tgt)
+}
+
+func diffDelta(index *deltaIndex, src []byte, tgt []byte) []byte {
+ buf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(buf)
+ buf.Write(deltaEncodeSize(len(src)))
+ buf.Write(deltaEncodeSize(len(tgt)))
+
+ if len(index.entries) == 0 {
+ index.init(src)
+ }
+
+ ibuf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(ibuf)
+ for i := 0; i < len(tgt); i++ {
+ offset, l := index.findMatch(src, tgt, i)
+
+ if l == 0 {
+ // couldn't find a match, just write the current byte and continue
+ ibuf.WriteByte(tgt[i])
+ } else if l < 0 {
+ // src is less than blksz, copy the rest of the target to avoid
+ // calls to findMatch
+ for ; i < len(tgt); i++ {
+ ibuf.WriteByte(tgt[i])
+ }
+ } else if l < s {
+ // remaining target is less than blksz, copy what's left of it
+ // and avoid calls to findMatch
+ for j := i; j < i+l; j++ {
+ ibuf.WriteByte(tgt[j])
+ }
+ i += l - 1
+ } else {
+ encodeInsertOperation(ibuf, buf)
+
+ rl := l
+ aOffset := offset
+ for rl > 0 {
+ if rl < maxCopySize {
+ buf.Write(encodeCopyOperation(aOffset, rl))
+ break
+ }
+
+ buf.Write(encodeCopyOperation(aOffset, maxCopySize))
+ rl -= maxCopySize
+ aOffset += maxCopySize
+ }
+
+ i += l - 1
+ }
+ }
+
+ encodeInsertOperation(ibuf, buf)
+
+ // buf.Bytes() is only valid until the next modifying operation on the buffer. Copy it.
+ return append([]byte{}, buf.Bytes()...)
+}
+
+func encodeInsertOperation(ibuf, buf *bytes.Buffer) {
+ if ibuf.Len() == 0 {
+ return
+ }
+
+ b := ibuf.Bytes()
+ s := ibuf.Len()
+ o := 0
+ for {
+ if s <= 127 {
+ break
+ }
+ buf.WriteByte(byte(127))
+ buf.Write(b[o : o+127])
+ s -= 127
+ o += 127
+ }
+ buf.WriteByte(byte(s))
+ buf.Write(b[o : o+s])
+
+ ibuf.Reset()
+}
+
+func deltaEncodeSize(size int) []byte {
+ var ret []byte
+ c := size & 0x7f
+ size >>= 7
+ for {
+ if size == 0 {
+ break
+ }
+
+ ret = append(ret, byte(c|0x80))
+ c = size & 0x7f
+ size >>= 7
+ }
+ ret = append(ret, byte(c))
+
+ return ret
+}
+
+func encodeCopyOperation(offset, length int) []byte {
+ code := 0x80
+ var opcodes []byte
+
+ var i uint
+ for i = 0; i < 4; i++ {
+ f := 0xff << (i * 8)
+ if offset&f != 0 {
+ opcodes = append(opcodes, byte(offset&f>>(i*8)))
+ code |= 0x01 << i
+ }
+ }
+
+ for i = 0; i < 3; i++ {
+ f := 0xff << (i * 8)
+ if length&f != 0 {
+ opcodes = append(opcodes, byte(length&f>>(i*8)))
+ code |= 0x10 << i
+ }
+ }
+
+ return append([]byte{byte(code)}, opcodes...)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/doc.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/doc.go
new file mode 100644
index 00000000..2882a7f3
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/doc.go
@@ -0,0 +1,39 @@
+// Package packfile implements encoding and decoding of packfile format.
+//
+// == pack-*.pack files have the following format:
+//
+// - A header appears at the beginning and consists of the following:
+//
+// 4-byte signature:
+// The signature is: {'P', 'A', 'C', 'K'}
+//
+// 4-byte version number (network byte order):
+// GIT currently accepts version number 2 or 3 but
+// generates version 2 only.
+//
+// 4-byte number of objects contained in the pack (network byte order)
+//
+// Observation: we cannot have more than 4G versions ;-) and
+// more than 4G objects in a pack.
+//
+// - The header is followed by number of object entries, each of
+// which looks like this:
+//
+// (undeltified representation)
+// n-byte type and length (3-bit type, (n-1)*7+4-bit length)
+// compressed data
+//
+// (deltified representation)
+// n-byte type and length (3-bit type, (n-1)*7+4-bit length)
+// 20-byte base object name
+// compressed delta data
+//
+// Observation: length of each object is encoded in a variable
+// length format and is not constrained to 32-bit or anything.
+//
+// - The trailer records 20-byte SHA1 checksum of all of the above.
+//
+//
+// Source:
+// https://www.kernel.org/pub/software/scm/git/docs/v1.7.5/technical/pack-protocol.txt
+package packfile
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/encoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/encoder.go
new file mode 100644
index 00000000..804f5a87
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/encoder.go
@@ -0,0 +1,221 @@
+package packfile
+
+import (
+ "compress/zlib"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/hash"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/binary"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// Encoder gets the data from the storage and write it into the writer in PACK
+// format
+type Encoder struct {
+ selector *deltaSelector
+ w *offsetWriter
+ zw *zlib.Writer
+ hasher plumbing.Hasher
+
+ useRefDeltas bool
+}
+
+// NewEncoder creates a new packfile encoder using a specific Writer and
+// EncodedObjectStorer. By default deltas used to generate the packfile will be
+// OFSDeltaObject. To use Reference deltas, set useRefDeltas to true.
+func NewEncoder(w io.Writer, s storer.EncodedObjectStorer, useRefDeltas bool) *Encoder {
+ h := plumbing.Hasher{
+ Hash: hash.New(hash.CryptoType),
+ }
+ mw := io.MultiWriter(w, h)
+ ow := newOffsetWriter(mw)
+ zw := zlib.NewWriter(mw)
+ return &Encoder{
+ selector: newDeltaSelector(s),
+ w: ow,
+ zw: zw,
+ hasher: h,
+ useRefDeltas: useRefDeltas,
+ }
+}
+
+// Encode creates a packfile containing all the objects referenced in
+// hashes and writes it to the writer in the Encoder. `packWindow`
+// specifies the size of the sliding window used to compare objects
+// for delta compression; 0 turns off delta compression entirely.
+func (e *Encoder) Encode(
+ hashes []plumbing.Hash,
+ packWindow uint,
+) (plumbing.Hash, error) {
+ objects, err := e.selector.ObjectsToPack(hashes, packWindow)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return e.encode(objects)
+}
+
+func (e *Encoder) encode(objects []*ObjectToPack) (plumbing.Hash, error) {
+ if err := e.head(len(objects)); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ for _, o := range objects {
+ if err := e.entry(o); err != nil {
+ return plumbing.ZeroHash, err
+ }
+ }
+
+ return e.footer()
+}
+
+func (e *Encoder) head(numEntries int) error {
+ return binary.Write(
+ e.w,
+ signature,
+ int32(VersionSupported),
+ int32(numEntries),
+ )
+}
+
+func (e *Encoder) entry(o *ObjectToPack) (err error) {
+ if o.WantWrite() {
+ // A cycle exists in this delta chain. This should only occur if a
+ // selected object representation disappeared during writing
+ // (for example due to a concurrent repack) and a different base
+ // was chosen, forcing a cycle. Select something other than a
+ // delta, and write this object.
+ e.selector.restoreOriginal(o)
+ o.BackToOriginal()
+ }
+
+ if o.IsWritten() {
+ return nil
+ }
+
+ o.MarkWantWrite()
+
+ if err := e.writeBaseIfDelta(o); err != nil {
+ return err
+ }
+
+ // We need to check if we already write that object due a cyclic delta chain
+ if o.IsWritten() {
+ return nil
+ }
+
+ o.Offset = e.w.Offset()
+
+ if o.IsDelta() {
+ if err := e.writeDeltaHeader(o); err != nil {
+ return err
+ }
+ } else {
+ if err := e.entryHead(o.Type(), o.Size()); err != nil {
+ return err
+ }
+ }
+
+ e.zw.Reset(e.w)
+
+ defer ioutil.CheckClose(e.zw, &err)
+
+ or, err := o.Object.Reader()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(or, &err)
+
+ _, err = io.Copy(e.zw, or)
+ return err
+}
+
+func (e *Encoder) writeBaseIfDelta(o *ObjectToPack) error {
+ if o.IsDelta() && !o.Base.IsWritten() {
+ // We must write base first
+ return e.entry(o.Base)
+ }
+
+ return nil
+}
+
+func (e *Encoder) writeDeltaHeader(o *ObjectToPack) error {
+ // Write offset deltas by default
+ t := plumbing.OFSDeltaObject
+ if e.useRefDeltas {
+ t = plumbing.REFDeltaObject
+ }
+
+ if err := e.entryHead(t, o.Object.Size()); err != nil {
+ return err
+ }
+
+ if e.useRefDeltas {
+ return e.writeRefDeltaHeader(o.Base.Hash())
+ } else {
+ return e.writeOfsDeltaHeader(o)
+ }
+}
+
+func (e *Encoder) writeRefDeltaHeader(base plumbing.Hash) error {
+ return binary.Write(e.w, base)
+}
+
+func (e *Encoder) writeOfsDeltaHeader(o *ObjectToPack) error {
+ // for OFS_DELTA, offset of the base is interpreted as negative offset
+ // relative to the type-byte of the header of the ofs-delta entry.
+ relativeOffset := o.Offset - o.Base.Offset
+ if relativeOffset <= 0 {
+ return fmt.Errorf("bad offset for OFS_DELTA entry: %d", relativeOffset)
+ }
+
+ return binary.WriteVariableWidthInt(e.w, relativeOffset)
+}
+
+func (e *Encoder) entryHead(typeNum plumbing.ObjectType, size int64) error {
+ t := int64(typeNum)
+ header := []byte{}
+ c := (t << firstLengthBits) | (size & maskFirstLength)
+ size >>= firstLengthBits
+ for {
+ if size == 0 {
+ break
+ }
+ header = append(header, byte(c|maskContinue))
+ c = size & int64(maskLength)
+ size >>= lengthBits
+ }
+
+ header = append(header, byte(c))
+ _, err := e.w.Write(header)
+
+ return err
+}
+
+func (e *Encoder) footer() (plumbing.Hash, error) {
+ h := e.hasher.Sum()
+ return h, binary.Write(e.w, h)
+}
+
+type offsetWriter struct {
+ w io.Writer
+ offset int64
+}
+
+func newOffsetWriter(w io.Writer) *offsetWriter {
+ return &offsetWriter{w: w}
+}
+
+func (ow *offsetWriter) Write(p []byte) (n int, err error) {
+ n, err = ow.w.Write(p)
+ ow.offset += int64(n)
+ return n, err
+}
+
+func (ow *offsetWriter) Offset() int64 {
+ return ow.offset
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/error.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/error.go
new file mode 100644
index 00000000..c0b91633
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/error.go
@@ -0,0 +1,30 @@
+package packfile
+
+import "fmt"
+
+// Error specifies errors returned during packfile parsing.
+type Error struct {
+ reason, details string
+}
+
+// NewError returns a new error.
+func NewError(reason string) *Error {
+ return &Error{reason: reason}
+}
+
+// Error returns a text representation of the error.
+func (e *Error) Error() string {
+ if e.details == "" {
+ return e.reason
+ }
+
+ return fmt.Sprintf("%s: %s", e.reason, e.details)
+}
+
+// AddDetails adds details to an error, with additional text.
+func (e *Error) AddDetails(format string, args ...interface{}) *Error {
+ return &Error{
+ reason: e.reason,
+ details: fmt.Sprintf(format, args...),
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/fsobject.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/fsobject.go
new file mode 100644
index 00000000..238339da
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/fsobject.go
@@ -0,0 +1,119 @@
+package packfile
+
+import (
+ "io"
+
+ billy "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ "github.com/go-git/go-git/v5/plumbing/format/idxfile"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// FSObject is an object from the packfile on the filesystem.
+type FSObject struct {
+ hash plumbing.Hash
+ offset int64
+ size int64
+ typ plumbing.ObjectType
+ index idxfile.Index
+ fs billy.Filesystem
+ path string
+ cache cache.Object
+ largeObjectThreshold int64
+}
+
+// NewFSObject creates a new filesystem object.
+func NewFSObject(
+ hash plumbing.Hash,
+ finalType plumbing.ObjectType,
+ offset int64,
+ contentSize int64,
+ index idxfile.Index,
+ fs billy.Filesystem,
+ path string,
+ cache cache.Object,
+ largeObjectThreshold int64,
+) *FSObject {
+ return &FSObject{
+ hash: hash,
+ offset: offset,
+ size: contentSize,
+ typ: finalType,
+ index: index,
+ fs: fs,
+ path: path,
+ cache: cache,
+ largeObjectThreshold: largeObjectThreshold,
+ }
+}
+
+// Reader implements the plumbing.EncodedObject interface.
+func (o *FSObject) Reader() (io.ReadCloser, error) {
+ obj, ok := o.cache.Get(o.hash)
+ if ok && obj != o {
+ reader, err := obj.Reader()
+ if err != nil {
+ return nil, err
+ }
+
+ return reader, nil
+ }
+
+ f, err := o.fs.Open(o.path)
+ if err != nil {
+ return nil, err
+ }
+
+ p := NewPackfileWithCache(o.index, nil, f, o.cache, o.largeObjectThreshold)
+ if o.largeObjectThreshold > 0 && o.size > o.largeObjectThreshold {
+ // We have a big object
+ h, err := p.objectHeaderAtOffset(o.offset)
+ if err != nil {
+ return nil, err
+ }
+
+ r, err := p.getReaderDirect(h)
+ if err != nil {
+ _ = f.Close()
+ return nil, err
+ }
+ return ioutil.NewReadCloserWithCloser(r, f.Close), nil
+ }
+ r, err := p.getObjectContent(o.offset)
+ if err != nil {
+ _ = f.Close()
+ return nil, err
+ }
+
+ if err := f.Close(); err != nil {
+ return nil, err
+ }
+
+ return r, nil
+}
+
+// SetSize implements the plumbing.EncodedObject interface. This method
+// is a noop.
+func (o *FSObject) SetSize(int64) {}
+
+// SetType implements the plumbing.EncodedObject interface. This method is
+// a noop.
+func (o *FSObject) SetType(plumbing.ObjectType) {}
+
+// Hash implements the plumbing.EncodedObject interface.
+func (o *FSObject) Hash() plumbing.Hash { return o.hash }
+
+// Size implements the plumbing.EncodedObject interface.
+func (o *FSObject) Size() int64 { return o.size }
+
+// Type implements the plumbing.EncodedObject interface.
+func (o *FSObject) Type() plumbing.ObjectType {
+ return o.typ
+}
+
+// Writer implements the plumbing.EncodedObject interface. This method always
+// returns a nil writer.
+func (o *FSObject) Writer() (io.WriteCloser, error) {
+ return nil, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/object_pack.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/object_pack.go
new file mode 100644
index 00000000..8ce29ef8
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/object_pack.go
@@ -0,0 +1,164 @@
+package packfile
+
+import (
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+// ObjectToPack is a representation of an object that is going to be into a
+// pack file.
+type ObjectToPack struct {
+ // The main object to pack, it could be any object, including deltas
+ Object plumbing.EncodedObject
+ // Base is the object that a delta is based on (it could be also another delta).
+ // If the main object is not a delta, Base will be null
+ Base *ObjectToPack
+ // Original is the object that we can generate applying the delta to
+ // Base, or the same object as Object in the case of a non-delta
+ // object.
+ Original plumbing.EncodedObject
+ // Depth is the amount of deltas needed to resolve to obtain Original
+ // (delta based on delta based on ...)
+ Depth int
+
+ // offset in pack when object has been already written, or 0 if it
+ // has not been written yet
+ Offset int64
+
+ // Information from the original object
+ resolvedOriginal bool
+ originalType plumbing.ObjectType
+ originalSize int64
+ originalHash plumbing.Hash
+}
+
+// newObjectToPack creates a correct ObjectToPack based on a non-delta object
+func newObjectToPack(o plumbing.EncodedObject) *ObjectToPack {
+ return &ObjectToPack{
+ Object: o,
+ Original: o,
+ }
+}
+
+// newDeltaObjectToPack creates a correct ObjectToPack for a delta object, based on
+// his base (could be another delta), the delta target (in this case called original),
+// and the delta Object itself
+func newDeltaObjectToPack(base *ObjectToPack, original, delta plumbing.EncodedObject) *ObjectToPack {
+ return &ObjectToPack{
+ Object: delta,
+ Base: base,
+ Original: original,
+ Depth: base.Depth + 1,
+ }
+}
+
+// BackToOriginal converts that ObjectToPack to a non-deltified object if it was one
+func (o *ObjectToPack) BackToOriginal() {
+ if o.IsDelta() && o.Original != nil {
+ o.Object = o.Original
+ o.Base = nil
+ o.Depth = 0
+ }
+}
+
+// IsWritten returns if that ObjectToPack was
+// already written into the packfile or not
+func (o *ObjectToPack) IsWritten() bool {
+ return o.Offset > 1
+}
+
+// MarkWantWrite marks this ObjectToPack as WantWrite
+// to avoid delta chain loops
+func (o *ObjectToPack) MarkWantWrite() {
+ o.Offset = 1
+}
+
+// WantWrite checks if this ObjectToPack was marked as WantWrite before
+func (o *ObjectToPack) WantWrite() bool {
+ return o.Offset == 1
+}
+
+// SetOriginal sets both Original and saves size, type and hash. If object
+// is nil Original is set but previous resolved values are kept
+func (o *ObjectToPack) SetOriginal(obj plumbing.EncodedObject) {
+ o.Original = obj
+ o.SaveOriginalMetadata()
+}
+
+// SaveOriginalMetadata saves size, type and hash of Original object
+func (o *ObjectToPack) SaveOriginalMetadata() {
+ if o.Original != nil {
+ o.originalSize = o.Original.Size()
+ o.originalType = o.Original.Type()
+ o.originalHash = o.Original.Hash()
+ o.resolvedOriginal = true
+ }
+}
+
+// CleanOriginal sets Original to nil
+func (o *ObjectToPack) CleanOriginal() {
+ o.Original = nil
+}
+
+func (o *ObjectToPack) Type() plumbing.ObjectType {
+ if o.Original != nil {
+ return o.Original.Type()
+ }
+
+ if o.resolvedOriginal {
+ return o.originalType
+ }
+
+ if o.Base != nil {
+ return o.Base.Type()
+ }
+
+ if o.Object != nil {
+ return o.Object.Type()
+ }
+
+ panic("cannot get type")
+}
+
+func (o *ObjectToPack) Hash() plumbing.Hash {
+ if o.Original != nil {
+ return o.Original.Hash()
+ }
+
+ if o.resolvedOriginal {
+ return o.originalHash
+ }
+
+ do, ok := o.Object.(plumbing.DeltaObject)
+ if ok {
+ return do.ActualHash()
+ }
+
+ panic("cannot get hash")
+}
+
+func (o *ObjectToPack) Size() int64 {
+ if o.Original != nil {
+ return o.Original.Size()
+ }
+
+ if o.resolvedOriginal {
+ return o.originalSize
+ }
+
+ do, ok := o.Object.(plumbing.DeltaObject)
+ if ok {
+ return do.ActualSize()
+ }
+
+ panic("cannot get ObjectToPack size")
+}
+
+func (o *ObjectToPack) IsDelta() bool {
+ return o.Base != nil
+}
+
+func (o *ObjectToPack) SetDelta(base *ObjectToPack, delta plumbing.EncodedObject) {
+ o.Object = delta
+ o.Base = base
+ o.Depth = base.Depth + 1
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/packfile.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/packfile.go
new file mode 100644
index 00000000..68527022
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/packfile.go
@@ -0,0 +1,641 @@
+package packfile
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+
+ billy "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ "github.com/go-git/go-git/v5/plumbing/format/idxfile"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+var (
+ // ErrInvalidObject is returned by Decode when an invalid object is
+ // found in the packfile.
+ ErrInvalidObject = NewError("invalid git object")
+ // ErrZLib is returned by Decode when there was an error unzipping
+ // the packfile contents.
+ ErrZLib = NewError("zlib reading error")
+)
+
+// When reading small objects from packfile it is beneficial to do so at
+// once to exploit the buffered I/O. In many cases the objects are so small
+// that they were already loaded to memory when the object header was
+// loaded from the packfile. Wrapping in FSObject would cause this buffered
+// data to be thrown away and then re-read later, with the additional
+// seeking causing reloads from disk. Objects smaller than this threshold
+// are now always read into memory and stored in cache instead of being
+// wrapped in FSObject.
+const smallObjectThreshold = 16 * 1024
+
+// Packfile allows retrieving information from inside a packfile.
+type Packfile struct {
+ idxfile.Index
+ fs billy.Filesystem
+ file billy.File
+ s *Scanner
+ deltaBaseCache cache.Object
+ offsetToType map[int64]plumbing.ObjectType
+ largeObjectThreshold int64
+}
+
+// NewPackfileWithCache creates a new Packfile with the given object cache.
+// If the filesystem is provided, the packfile will return FSObjects, otherwise
+// it will return MemoryObjects.
+func NewPackfileWithCache(
+ index idxfile.Index,
+ fs billy.Filesystem,
+ file billy.File,
+ cache cache.Object,
+ largeObjectThreshold int64,
+) *Packfile {
+ s := NewScanner(file)
+ return &Packfile{
+ index,
+ fs,
+ file,
+ s,
+ cache,
+ make(map[int64]plumbing.ObjectType),
+ largeObjectThreshold,
+ }
+}
+
+// NewPackfile returns a packfile representation for the given packfile file
+// and packfile idx.
+// If the filesystem is provided, the packfile will return FSObjects, otherwise
+// it will return MemoryObjects.
+func NewPackfile(index idxfile.Index, fs billy.Filesystem, file billy.File, largeObjectThreshold int64) *Packfile {
+ return NewPackfileWithCache(index, fs, file, cache.NewObjectLRUDefault(), largeObjectThreshold)
+}
+
+// Get retrieves the encoded object in the packfile with the given hash.
+func (p *Packfile) Get(h plumbing.Hash) (plumbing.EncodedObject, error) {
+ offset, err := p.FindOffset(h)
+ if err != nil {
+ return nil, err
+ }
+
+ return p.objectAtOffset(offset, h)
+}
+
+// GetByOffset retrieves the encoded object from the packfile at the given
+// offset.
+func (p *Packfile) GetByOffset(o int64) (plumbing.EncodedObject, error) {
+ hash, err := p.FindHash(o)
+ if err != nil {
+ return nil, err
+ }
+
+ return p.objectAtOffset(o, hash)
+}
+
+// GetSizeByOffset retrieves the size of the encoded object from the
+// packfile with the given offset.
+func (p *Packfile) GetSizeByOffset(o int64) (size int64, err error) {
+ if _, err := p.s.SeekFromStart(o); err != nil {
+ if err == io.EOF || isInvalid(err) {
+ return 0, plumbing.ErrObjectNotFound
+ }
+
+ return 0, err
+ }
+
+ h, err := p.nextObjectHeader()
+ if err != nil {
+ return 0, err
+ }
+ return p.getObjectSize(h)
+}
+
+func (p *Packfile) objectHeaderAtOffset(offset int64) (*ObjectHeader, error) {
+ h, err := p.s.SeekObjectHeader(offset)
+ p.s.pendingObject = nil
+ return h, err
+}
+
+func (p *Packfile) nextObjectHeader() (*ObjectHeader, error) {
+ h, err := p.s.NextObjectHeader()
+ p.s.pendingObject = nil
+ return h, err
+}
+
+func (p *Packfile) getDeltaObjectSize(buf *bytes.Buffer) int64 {
+ delta := buf.Bytes()
+ _, delta = decodeLEB128(delta) // skip src size
+ sz, _ := decodeLEB128(delta)
+ return int64(sz)
+}
+
+func (p *Packfile) getObjectSize(h *ObjectHeader) (int64, error) {
+ switch h.Type {
+ case plumbing.CommitObject, plumbing.TreeObject, plumbing.BlobObject, plumbing.TagObject:
+ return h.Length, nil
+ case plumbing.REFDeltaObject, plumbing.OFSDeltaObject:
+ buf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(buf)
+
+ if _, _, err := p.s.NextObject(buf); err != nil {
+ return 0, err
+ }
+
+ return p.getDeltaObjectSize(buf), nil
+ default:
+ return 0, ErrInvalidObject.AddDetails("type %q", h.Type)
+ }
+}
+
+func (p *Packfile) getObjectType(h *ObjectHeader) (typ plumbing.ObjectType, err error) {
+ switch h.Type {
+ case plumbing.CommitObject, plumbing.TreeObject, plumbing.BlobObject, plumbing.TagObject:
+ return h.Type, nil
+ case plumbing.REFDeltaObject, plumbing.OFSDeltaObject:
+ var offset int64
+ if h.Type == plumbing.REFDeltaObject {
+ offset, err = p.FindOffset(h.Reference)
+ if err != nil {
+ return
+ }
+ } else {
+ offset = h.OffsetReference
+ }
+
+ if baseType, ok := p.offsetToType[offset]; ok {
+ typ = baseType
+ } else {
+ h, err = p.objectHeaderAtOffset(offset)
+ if err != nil {
+ return
+ }
+
+ typ, err = p.getObjectType(h)
+ if err != nil {
+ return
+ }
+ }
+ default:
+ err = ErrInvalidObject.AddDetails("type %q", h.Type)
+ }
+
+ p.offsetToType[h.Offset] = typ
+
+ return
+}
+
+func (p *Packfile) objectAtOffset(offset int64, hash plumbing.Hash) (plumbing.EncodedObject, error) {
+ if obj, ok := p.cacheGet(hash); ok {
+ return obj, nil
+ }
+
+ h, err := p.objectHeaderAtOffset(offset)
+ if err != nil {
+ if err == io.EOF || isInvalid(err) {
+ return nil, plumbing.ErrObjectNotFound
+ }
+ return nil, err
+ }
+
+ return p.getNextObject(h, hash)
+}
+
+func (p *Packfile) getNextObject(h *ObjectHeader, hash plumbing.Hash) (plumbing.EncodedObject, error) {
+ var err error
+
+ // If we have no filesystem, we will return a MemoryObject instead
+ // of an FSObject.
+ if p.fs == nil {
+ return p.getNextMemoryObject(h)
+ }
+
+ // If the object is small enough then read it completely into memory now since
+ // it is already read from disk into buffer anyway. For delta objects we want
+ // to perform the optimization too, but we have to be careful about applying
+ // small deltas on big objects.
+ var size int64
+ if h.Length <= smallObjectThreshold {
+ if h.Type != plumbing.OFSDeltaObject && h.Type != plumbing.REFDeltaObject {
+ return p.getNextMemoryObject(h)
+ }
+
+ // For delta objects we read the delta data and apply the small object
+ // optimization only if the expanded version of the object still meets
+ // the small object threshold condition.
+ buf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(buf)
+
+ if _, _, err := p.s.NextObject(buf); err != nil {
+ return nil, err
+ }
+
+ size = p.getDeltaObjectSize(buf)
+ if size <= smallObjectThreshold {
+ var obj = new(plumbing.MemoryObject)
+ obj.SetSize(size)
+ if h.Type == plumbing.REFDeltaObject {
+ err = p.fillREFDeltaObjectContentWithBuffer(obj, h.Reference, buf)
+ } else {
+ err = p.fillOFSDeltaObjectContentWithBuffer(obj, h.OffsetReference, buf)
+ }
+ return obj, err
+ }
+ } else {
+ size, err = p.getObjectSize(h)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ typ, err := p.getObjectType(h)
+ if err != nil {
+ return nil, err
+ }
+
+ p.offsetToType[h.Offset] = typ
+
+ return NewFSObject(
+ hash,
+ typ,
+ h.Offset,
+ size,
+ p.Index,
+ p.fs,
+ p.file.Name(),
+ p.deltaBaseCache,
+ p.largeObjectThreshold,
+ ), nil
+}
+
+func (p *Packfile) getObjectContent(offset int64) (io.ReadCloser, error) {
+ h, err := p.objectHeaderAtOffset(offset)
+ if err != nil {
+ return nil, err
+ }
+
+ // getObjectContent is called from FSObject, so we have to explicitly
+ // get memory object here to avoid recursive cycle
+ obj, err := p.getNextMemoryObject(h)
+ if err != nil {
+ return nil, err
+ }
+
+ return obj.Reader()
+}
+
+func asyncReader(p *Packfile) (io.ReadCloser, error) {
+ reader := ioutil.NewReaderUsingReaderAt(p.file, p.s.r.offset)
+ zr, err := sync.GetZlibReader(reader)
+ if err != nil {
+ return nil, fmt.Errorf("zlib reset error: %s", err)
+ }
+
+ return ioutil.NewReadCloserWithCloser(zr.Reader, func() error {
+ sync.PutZlibReader(zr)
+ return nil
+ }), nil
+
+}
+
+func (p *Packfile) getReaderDirect(h *ObjectHeader) (io.ReadCloser, error) {
+ switch h.Type {
+ case plumbing.CommitObject, plumbing.TreeObject, plumbing.BlobObject, plumbing.TagObject:
+ return asyncReader(p)
+ case plumbing.REFDeltaObject:
+ deltaRc, err := asyncReader(p)
+ if err != nil {
+ return nil, err
+ }
+ r, err := p.readREFDeltaObjectContent(h, deltaRc)
+ if err != nil {
+ return nil, err
+ }
+ return r, nil
+ case plumbing.OFSDeltaObject:
+ deltaRc, err := asyncReader(p)
+ if err != nil {
+ return nil, err
+ }
+ r, err := p.readOFSDeltaObjectContent(h, deltaRc)
+ if err != nil {
+ return nil, err
+ }
+ return r, nil
+ default:
+ return nil, ErrInvalidObject.AddDetails("type %q", h.Type)
+ }
+}
+
+func (p *Packfile) getNextMemoryObject(h *ObjectHeader) (plumbing.EncodedObject, error) {
+ var obj = new(plumbing.MemoryObject)
+ obj.SetSize(h.Length)
+ obj.SetType(h.Type)
+
+ var err error
+ switch h.Type {
+ case plumbing.CommitObject, plumbing.TreeObject, plumbing.BlobObject, plumbing.TagObject:
+ err = p.fillRegularObjectContent(obj)
+ case plumbing.REFDeltaObject:
+ err = p.fillREFDeltaObjectContent(obj, h.Reference)
+ case plumbing.OFSDeltaObject:
+ err = p.fillOFSDeltaObjectContent(obj, h.OffsetReference)
+ default:
+ err = ErrInvalidObject.AddDetails("type %q", h.Type)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ p.offsetToType[h.Offset] = obj.Type()
+
+ return obj, nil
+}
+
+func (p *Packfile) fillRegularObjectContent(obj plumbing.EncodedObject) (err error) {
+ w, err := obj.Writer()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(w, &err)
+
+ _, _, err = p.s.NextObject(w)
+ p.cachePut(obj)
+
+ return err
+}
+
+func (p *Packfile) fillREFDeltaObjectContent(obj plumbing.EncodedObject, ref plumbing.Hash) error {
+ buf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(buf)
+
+ _, _, err := p.s.NextObject(buf)
+ if err != nil {
+ return err
+ }
+
+ return p.fillREFDeltaObjectContentWithBuffer(obj, ref, buf)
+}
+
+func (p *Packfile) readREFDeltaObjectContent(h *ObjectHeader, deltaRC io.Reader) (io.ReadCloser, error) {
+ var err error
+
+ base, ok := p.cacheGet(h.Reference)
+ if !ok {
+ base, err = p.Get(h.Reference)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return ReaderFromDelta(base, deltaRC)
+}
+
+func (p *Packfile) fillREFDeltaObjectContentWithBuffer(obj plumbing.EncodedObject, ref plumbing.Hash, buf *bytes.Buffer) error {
+ var err error
+
+ base, ok := p.cacheGet(ref)
+ if !ok {
+ base, err = p.Get(ref)
+ if err != nil {
+ return err
+ }
+ }
+
+ obj.SetType(base.Type())
+ err = ApplyDelta(obj, base, buf.Bytes())
+ p.cachePut(obj)
+
+ return err
+}
+
+func (p *Packfile) fillOFSDeltaObjectContent(obj plumbing.EncodedObject, offset int64) error {
+ buf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(buf)
+
+ _, _, err := p.s.NextObject(buf)
+ if err != nil {
+ return err
+ }
+
+ return p.fillOFSDeltaObjectContentWithBuffer(obj, offset, buf)
+}
+
+func (p *Packfile) readOFSDeltaObjectContent(h *ObjectHeader, deltaRC io.Reader) (io.ReadCloser, error) {
+ hash, err := p.FindHash(h.OffsetReference)
+ if err != nil {
+ return nil, err
+ }
+
+ base, err := p.objectAtOffset(h.OffsetReference, hash)
+ if err != nil {
+ return nil, err
+ }
+
+ return ReaderFromDelta(base, deltaRC)
+}
+
+func (p *Packfile) fillOFSDeltaObjectContentWithBuffer(obj plumbing.EncodedObject, offset int64, buf *bytes.Buffer) error {
+ hash, err := p.FindHash(offset)
+ if err != nil {
+ return err
+ }
+
+ base, err := p.objectAtOffset(offset, hash)
+ if err != nil {
+ return err
+ }
+
+ obj.SetType(base.Type())
+ err = ApplyDelta(obj, base, buf.Bytes())
+ p.cachePut(obj)
+
+ return err
+}
+
+func (p *Packfile) cacheGet(h plumbing.Hash) (plumbing.EncodedObject, bool) {
+ if p.deltaBaseCache == nil {
+ return nil, false
+ }
+
+ return p.deltaBaseCache.Get(h)
+}
+
+func (p *Packfile) cachePut(obj plumbing.EncodedObject) {
+ if p.deltaBaseCache == nil {
+ return
+ }
+
+ p.deltaBaseCache.Put(obj)
+}
+
+// GetAll returns an iterator with all encoded objects in the packfile.
+// The iterator returned is not thread-safe, it should be used in the same
+// thread as the Packfile instance.
+func (p *Packfile) GetAll() (storer.EncodedObjectIter, error) {
+ return p.GetByType(plumbing.AnyObject)
+}
+
+// GetByType returns all the objects of the given type.
+func (p *Packfile) GetByType(typ plumbing.ObjectType) (storer.EncodedObjectIter, error) {
+ switch typ {
+ case plumbing.AnyObject,
+ plumbing.BlobObject,
+ plumbing.TreeObject,
+ plumbing.CommitObject,
+ plumbing.TagObject:
+ entries, err := p.EntriesByOffset()
+ if err != nil {
+ return nil, err
+ }
+
+ return &objectIter{
+ // Easiest way to provide an object decoder is just to pass a Packfile
+ // instance. To not mess with the seeks, it's a new instance with a
+ // different scanner but the same cache and offset to hash map for
+ // reusing as much cache as possible.
+ p: p,
+ iter: entries,
+ typ: typ,
+ }, nil
+ default:
+ return nil, plumbing.ErrInvalidType
+ }
+}
+
+// ID returns the ID of the packfile, which is the checksum at the end of it.
+func (p *Packfile) ID() (plumbing.Hash, error) {
+ prev, err := p.file.Seek(-20, io.SeekEnd)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ var hash plumbing.Hash
+ if _, err := io.ReadFull(p.file, hash[:]); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ if _, err := p.file.Seek(prev, io.SeekStart); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return hash, nil
+}
+
+// Scanner returns the packfile's Scanner
+func (p *Packfile) Scanner() *Scanner {
+ return p.s
+}
+
+// Close the packfile and its resources.
+func (p *Packfile) Close() error {
+ closer, ok := p.file.(io.Closer)
+ if !ok {
+ return nil
+ }
+
+ return closer.Close()
+}
+
+type objectIter struct {
+ p *Packfile
+ typ plumbing.ObjectType
+ iter idxfile.EntryIter
+}
+
+func (i *objectIter) Next() (plumbing.EncodedObject, error) {
+ for {
+ e, err := i.iter.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ if i.typ != plumbing.AnyObject {
+ if typ, ok := i.p.offsetToType[int64(e.Offset)]; ok {
+ if typ != i.typ {
+ continue
+ }
+ } else if obj, ok := i.p.cacheGet(e.Hash); ok {
+ if obj.Type() != i.typ {
+ i.p.offsetToType[int64(e.Offset)] = obj.Type()
+ continue
+ }
+ return obj, nil
+ } else {
+ h, err := i.p.objectHeaderAtOffset(int64(e.Offset))
+ if err != nil {
+ return nil, err
+ }
+
+ if h.Type == plumbing.REFDeltaObject || h.Type == plumbing.OFSDeltaObject {
+ typ, err := i.p.getObjectType(h)
+ if err != nil {
+ return nil, err
+ }
+ if typ != i.typ {
+ i.p.offsetToType[int64(e.Offset)] = typ
+ continue
+ }
+ // getObjectType will seek in the file so we cannot use getNextObject safely
+ return i.p.objectAtOffset(int64(e.Offset), e.Hash)
+ } else {
+ if h.Type != i.typ {
+ i.p.offsetToType[int64(e.Offset)] = h.Type
+ continue
+ }
+ return i.p.getNextObject(h, e.Hash)
+ }
+ }
+ }
+
+ obj, err := i.p.objectAtOffset(int64(e.Offset), e.Hash)
+ if err != nil {
+ return nil, err
+ }
+
+ return obj, nil
+ }
+}
+
+func (i *objectIter) ForEach(f func(plumbing.EncodedObject) error) error {
+ for {
+ o, err := i.Next()
+ if err != nil {
+ if err == io.EOF {
+ return nil
+ }
+ return err
+ }
+
+ if err := f(o); err != nil {
+ return err
+ }
+ }
+}
+
+func (i *objectIter) Close() {
+ i.iter.Close()
+}
+
+// isInvalid checks whether an error is an os.PathError with an os.ErrInvalid
+// error inside. It also checks for the windows error, which is different from
+// os.ErrInvalid.
+func isInvalid(err error) bool {
+ pe, ok := err.(*os.PathError)
+ if !ok {
+ return false
+ }
+
+ errstr := pe.Err.Error()
+ return errstr == errInvalidUnix || errstr == errInvalidWindows
+}
+
+// errInvalidWindows is the Windows equivalent to os.ErrInvalid
+const errInvalidWindows = "The parameter is incorrect."
+
+var errInvalidUnix = os.ErrInvalid.Error()
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/parser.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/parser.go
new file mode 100644
index 00000000..62f1d13c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/parser.go
@@ -0,0 +1,611 @@
+package packfile
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+var (
+ // ErrReferenceDeltaNotFound is returned when the reference delta is not
+ // found.
+ ErrReferenceDeltaNotFound = errors.New("reference delta not found")
+
+ // ErrNotSeekableSource is returned when the source for the parser is not
+ // seekable and a storage was not provided, so it can't be parsed.
+ ErrNotSeekableSource = errors.New("parser source is not seekable and storage was not provided")
+
+ // ErrDeltaNotCached is returned when the delta could not be found in cache.
+ ErrDeltaNotCached = errors.New("delta could not be found in cache")
+)
+
+// Observer interface is implemented by index encoders.
+type Observer interface {
+ // OnHeader is called when a new packfile is opened.
+ OnHeader(count uint32) error
+ // OnInflatedObjectHeader is called for each object header read.
+ OnInflatedObjectHeader(t plumbing.ObjectType, objSize int64, pos int64) error
+ // OnInflatedObjectContent is called for each decoded object.
+ OnInflatedObjectContent(h plumbing.Hash, pos int64, crc uint32, content []byte) error
+ // OnFooter is called when decoding is done.
+ OnFooter(h plumbing.Hash) error
+}
+
+// Parser decodes a packfile and calls any observer associated to it. Is used
+// to generate indexes.
+type Parser struct {
+ storage storer.EncodedObjectStorer
+ scanner *Scanner
+ count uint32
+ oi []*objectInfo
+ oiByHash map[plumbing.Hash]*objectInfo
+ oiByOffset map[int64]*objectInfo
+ checksum plumbing.Hash
+
+ cache *cache.BufferLRU
+ // delta content by offset, only used if source is not seekable
+ deltas map[int64][]byte
+
+ ob []Observer
+}
+
+// NewParser creates a new Parser. The Scanner source must be seekable.
+// If it's not, NewParserWithStorage should be used instead.
+func NewParser(scanner *Scanner, ob ...Observer) (*Parser, error) {
+ return NewParserWithStorage(scanner, nil, ob...)
+}
+
+// NewParserWithStorage creates a new Parser. The scanner source must either
+// be seekable or a storage must be provided.
+func NewParserWithStorage(
+ scanner *Scanner,
+ storage storer.EncodedObjectStorer,
+ ob ...Observer,
+) (*Parser, error) {
+ if !scanner.IsSeekable && storage == nil {
+ return nil, ErrNotSeekableSource
+ }
+
+ var deltas map[int64][]byte
+ if !scanner.IsSeekable {
+ deltas = make(map[int64][]byte)
+ }
+
+ return &Parser{
+ storage: storage,
+ scanner: scanner,
+ ob: ob,
+ count: 0,
+ cache: cache.NewBufferLRUDefault(),
+ deltas: deltas,
+ }, nil
+}
+
+func (p *Parser) forEachObserver(f func(o Observer) error) error {
+ for _, o := range p.ob {
+ if err := f(o); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (p *Parser) onHeader(count uint32) error {
+ return p.forEachObserver(func(o Observer) error {
+ return o.OnHeader(count)
+ })
+}
+
+func (p *Parser) onInflatedObjectHeader(
+ t plumbing.ObjectType,
+ objSize int64,
+ pos int64,
+) error {
+ return p.forEachObserver(func(o Observer) error {
+ return o.OnInflatedObjectHeader(t, objSize, pos)
+ })
+}
+
+func (p *Parser) onInflatedObjectContent(
+ h plumbing.Hash,
+ pos int64,
+ crc uint32,
+ content []byte,
+) error {
+ return p.forEachObserver(func(o Observer) error {
+ return o.OnInflatedObjectContent(h, pos, crc, content)
+ })
+}
+
+func (p *Parser) onFooter(h plumbing.Hash) error {
+ return p.forEachObserver(func(o Observer) error {
+ return o.OnFooter(h)
+ })
+}
+
+// Parse start decoding phase of the packfile.
+func (p *Parser) Parse() (plumbing.Hash, error) {
+ if err := p.init(); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ if err := p.indexObjects(); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ var err error
+ p.checksum, err = p.scanner.Checksum()
+ if err != nil && err != io.EOF {
+ return plumbing.ZeroHash, err
+ }
+
+ if err := p.resolveDeltas(); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ if err := p.onFooter(p.checksum); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return p.checksum, nil
+}
+
+func (p *Parser) init() error {
+ _, c, err := p.scanner.Header()
+ if err != nil {
+ return err
+ }
+
+ if err := p.onHeader(c); err != nil {
+ return err
+ }
+
+ p.count = c
+ p.oiByHash = make(map[plumbing.Hash]*objectInfo, p.count)
+ p.oiByOffset = make(map[int64]*objectInfo, p.count)
+ p.oi = make([]*objectInfo, p.count)
+
+ return nil
+}
+
+type objectHeaderWriter func(typ plumbing.ObjectType, sz int64) error
+
+type lazyObjectWriter interface {
+ // LazyWriter enables an object to be lazily written.
+ // It returns:
+ // - w: a writer to receive the object's content.
+ // - lwh: a func to write the object header.
+ // - err: any error from the initial writer creation process.
+ //
+ // Note that if the object header is not written BEFORE the writer
+ // is used, this will result in an invalid object.
+ LazyWriter() (w io.WriteCloser, lwh objectHeaderWriter, err error)
+}
+
+func (p *Parser) indexObjects() error {
+ buf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(buf)
+
+ for i := uint32(0); i < p.count; i++ {
+ oh, err := p.scanner.NextObjectHeader()
+ if err != nil {
+ return err
+ }
+
+ delta := false
+ var ota *objectInfo
+ switch t := oh.Type; t {
+ case plumbing.OFSDeltaObject:
+ delta = true
+
+ parent, ok := p.oiByOffset[oh.OffsetReference]
+ if !ok {
+ return plumbing.ErrObjectNotFound
+ }
+
+ ota = newDeltaObject(oh.Offset, oh.Length, t, parent)
+ parent.Children = append(parent.Children, ota)
+ case plumbing.REFDeltaObject:
+ delta = true
+ parent, ok := p.oiByHash[oh.Reference]
+ if !ok {
+ // can't find referenced object in this pack file
+ // this must be a "thin" pack.
+ parent = &objectInfo{ //Placeholder parent
+ SHA1: oh.Reference,
+ ExternalRef: true, // mark as an external reference that must be resolved
+ Type: plumbing.AnyObject,
+ DiskType: plumbing.AnyObject,
+ }
+ p.oiByHash[oh.Reference] = parent
+ }
+ ota = newDeltaObject(oh.Offset, oh.Length, t, parent)
+ parent.Children = append(parent.Children, ota)
+
+ default:
+ ota = newBaseObject(oh.Offset, oh.Length, t)
+ }
+
+ hasher := plumbing.NewHasher(oh.Type, oh.Length)
+ writers := []io.Writer{hasher}
+ var obj *plumbing.MemoryObject
+
+ // Lazy writing is only available for non-delta objects.
+ if p.storage != nil && !delta {
+ // When a storage is set and supports lazy writing,
+ // use that instead of creating a memory object.
+ if low, ok := p.storage.(lazyObjectWriter); ok {
+ ow, lwh, err := low.LazyWriter()
+ if err != nil {
+ return err
+ }
+
+ if err = lwh(oh.Type, oh.Length); err != nil {
+ return err
+ }
+
+ defer ow.Close()
+ writers = append(writers, ow)
+ } else {
+ obj = new(plumbing.MemoryObject)
+ obj.SetSize(oh.Length)
+ obj.SetType(oh.Type)
+
+ writers = append(writers, obj)
+ }
+ }
+ if delta && !p.scanner.IsSeekable {
+ buf.Reset()
+ buf.Grow(int(oh.Length))
+ writers = append(writers, buf)
+ }
+
+ mw := io.MultiWriter(writers...)
+
+ _, crc, err := p.scanner.NextObject(mw)
+ if err != nil {
+ return err
+ }
+
+ // Non delta objects needs to be added into the storage. This
+ // is only required when lazy writing is not supported.
+ if obj != nil {
+ if _, err := p.storage.SetEncodedObject(obj); err != nil {
+ return err
+ }
+ }
+
+ ota.Crc32 = crc
+ ota.Length = oh.Length
+
+ if !delta {
+ sha1 := hasher.Sum()
+
+ // Move children of placeholder parent into actual parent, in case this
+ // was a non-external delta reference.
+ if placeholder, ok := p.oiByHash[sha1]; ok {
+ ota.Children = placeholder.Children
+ for _, c := range ota.Children {
+ c.Parent = ota
+ }
+ }
+
+ ota.SHA1 = sha1
+ p.oiByHash[ota.SHA1] = ota
+ }
+
+ if delta && !p.scanner.IsSeekable {
+ data := buf.Bytes()
+ p.deltas[oh.Offset] = make([]byte, len(data))
+ copy(p.deltas[oh.Offset], data)
+ }
+
+ p.oiByOffset[oh.Offset] = ota
+ p.oi[i] = ota
+ }
+
+ return nil
+}
+
+func (p *Parser) resolveDeltas() error {
+ buf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(buf)
+
+ for _, obj := range p.oi {
+ buf.Reset()
+ buf.Grow(int(obj.Length))
+ err := p.get(obj, buf)
+ if err != nil {
+ return err
+ }
+
+ if err := p.onInflatedObjectHeader(obj.Type, obj.Length, obj.Offset); err != nil {
+ return err
+ }
+
+ if err := p.onInflatedObjectContent(obj.SHA1, obj.Offset, obj.Crc32, nil); err != nil {
+ return err
+ }
+
+ if !obj.IsDelta() && len(obj.Children) > 0 {
+ // Dealing with an io.ReaderAt object, means we can
+ // create it once and reuse across all children.
+ r := bytes.NewReader(buf.Bytes())
+ for _, child := range obj.Children {
+ // Even though we are discarding the output, we still need to read it to
+ // so that the scanner can advance to the next object, and the SHA1 can be
+ // calculated.
+ if err := p.resolveObject(io.Discard, child, r); err != nil {
+ return err
+ }
+ p.resolveExternalRef(child)
+ }
+
+ // Remove the delta from the cache.
+ if obj.DiskType.IsDelta() && !p.scanner.IsSeekable {
+ delete(p.deltas, obj.Offset)
+ }
+ }
+ }
+
+ return nil
+}
+
+func (p *Parser) resolveExternalRef(o *objectInfo) {
+ if ref, ok := p.oiByHash[o.SHA1]; ok && ref.ExternalRef {
+ p.oiByHash[o.SHA1] = o
+ o.Children = ref.Children
+ for _, c := range o.Children {
+ c.Parent = o
+ }
+ }
+}
+
+func (p *Parser) get(o *objectInfo, buf *bytes.Buffer) (err error) {
+ if !o.ExternalRef { // skip cache check for placeholder parents
+ b, ok := p.cache.Get(o.Offset)
+ if ok {
+ _, err := buf.Write(b)
+ return err
+ }
+ }
+
+ // If it's not on the cache and is not a delta we can try to find it in the
+ // storage, if there's one. External refs must enter here.
+ if p.storage != nil && !o.Type.IsDelta() {
+ var e plumbing.EncodedObject
+ e, err = p.storage.EncodedObject(plumbing.AnyObject, o.SHA1)
+ if err != nil {
+ return err
+ }
+ o.Type = e.Type()
+
+ var r io.ReadCloser
+ r, err = e.Reader()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(r, &err)
+
+ _, err = buf.ReadFrom(io.LimitReader(r, e.Size()))
+ return err
+ }
+
+ if o.ExternalRef {
+ // we were not able to resolve a ref in a thin pack
+ return ErrReferenceDeltaNotFound
+ }
+
+ if o.DiskType.IsDelta() {
+ b := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(b)
+ buf.Grow(int(o.Length))
+ err := p.get(o.Parent, b)
+ if err != nil {
+ return err
+ }
+
+ err = p.resolveObject(buf, o, bytes.NewReader(b.Bytes()))
+ if err != nil {
+ return err
+ }
+ } else {
+ err := p.readData(buf, o)
+ if err != nil {
+ return err
+ }
+ }
+
+ // If the scanner is seekable, caching this data into
+ // memory by offset seems wasteful.
+ // There is a trade-off to be considered here in terms
+ // of execution time vs memory consumption.
+ //
+ // TODO: improve seekable execution time, so that we can
+ // skip this cache.
+ if len(o.Children) > 0 {
+ data := make([]byte, buf.Len())
+ copy(data, buf.Bytes())
+ p.cache.Put(o.Offset, data)
+ }
+ return nil
+}
+
+// resolveObject resolves an object from base, using information
+// provided by o.
+//
+// This call has the side-effect of changing field values
+// from the object info o:
+// - Type: OFSDeltaObject may become the target type (e.g. Blob).
+// - Size: The size may be update with the target size.
+// - Hash: Zero hashes will be calculated as part of the object
+// resolution. Hence why this process can't be avoided even when w
+// is an io.Discard.
+//
+// base must be an io.ReaderAt, which is a requirement from
+// patchDeltaStream. The main reason being that reversing an
+// delta object may lead to going backs and forths within base,
+// which is not supported by io.Reader.
+func (p *Parser) resolveObject(
+ w io.Writer,
+ o *objectInfo,
+ base io.ReaderAt,
+) error {
+ if !o.DiskType.IsDelta() {
+ return nil
+ }
+ buf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(buf)
+ err := p.readData(buf, o)
+ if err != nil {
+ return err
+ }
+
+ writers := []io.Writer{w}
+ var obj *plumbing.MemoryObject
+ var lwh objectHeaderWriter
+
+ if p.storage != nil {
+ if low, ok := p.storage.(lazyObjectWriter); ok {
+ ow, wh, err := low.LazyWriter()
+ if err != nil {
+ return err
+ }
+ lwh = wh
+
+ defer ow.Close()
+ writers = append(writers, ow)
+ } else {
+ obj = new(plumbing.MemoryObject)
+ ow, err := obj.Writer()
+ if err != nil {
+ return err
+ }
+
+ writers = append(writers, ow)
+ }
+ }
+
+ mw := io.MultiWriter(writers...)
+
+ err = applyPatchBase(o, base, buf, mw, lwh)
+ if err != nil {
+ return err
+ }
+
+ if obj != nil {
+ obj.SetType(o.Type)
+ obj.SetSize(o.Size()) // Size here is correct as it was populated by applyPatchBase.
+ if _, err := p.storage.SetEncodedObject(obj); err != nil {
+ return err
+ }
+ }
+ return err
+}
+
+func (p *Parser) readData(w io.Writer, o *objectInfo) error {
+ if !p.scanner.IsSeekable && o.DiskType.IsDelta() {
+ data, ok := p.deltas[o.Offset]
+ if !ok {
+ return ErrDeltaNotCached
+ }
+ _, err := w.Write(data)
+ return err
+ }
+
+ if _, err := p.scanner.SeekObjectHeader(o.Offset); err != nil {
+ return err
+ }
+
+ if _, _, err := p.scanner.NextObject(w); err != nil {
+ return err
+ }
+ return nil
+}
+
+// applyPatchBase applies the patch to target.
+//
+// Note that ota will be updated based on the description in resolveObject.
+func applyPatchBase(ota *objectInfo, base io.ReaderAt, delta io.Reader, target io.Writer, wh objectHeaderWriter) error {
+ if target == nil {
+ return fmt.Errorf("cannot apply patch against nil target")
+ }
+
+ typ := ota.Type
+ if ota.SHA1 == plumbing.ZeroHash {
+ typ = ota.Parent.Type
+ }
+
+ sz, h, err := patchDeltaWriter(target, base, delta, typ, wh)
+ if err != nil {
+ return err
+ }
+
+ if ota.SHA1 == plumbing.ZeroHash {
+ ota.Type = typ
+ ota.Length = int64(sz)
+ ota.SHA1 = h
+ }
+
+ return nil
+}
+
+func getSHA1(t plumbing.ObjectType, data []byte) (plumbing.Hash, error) {
+ hasher := plumbing.NewHasher(t, int64(len(data)))
+ if _, err := hasher.Write(data); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return hasher.Sum(), nil
+}
+
+type objectInfo struct {
+ Offset int64
+ Length int64
+ Type plumbing.ObjectType
+ DiskType plumbing.ObjectType
+ ExternalRef bool // indicates this is an external reference in a thin pack file
+
+ Crc32 uint32
+
+ Parent *objectInfo
+ Children []*objectInfo
+ SHA1 plumbing.Hash
+}
+
+func newBaseObject(offset, length int64, t plumbing.ObjectType) *objectInfo {
+ return newDeltaObject(offset, length, t, nil)
+}
+
+func newDeltaObject(
+ offset, length int64,
+ t plumbing.ObjectType,
+ parent *objectInfo,
+) *objectInfo {
+ obj := &objectInfo{
+ Offset: offset,
+ Length: length,
+ Type: t,
+ DiskType: t,
+ Crc32: 0,
+ Parent: parent,
+ }
+
+ return obj
+}
+
+func (o *objectInfo) IsDelta() bool {
+ return o.Type.IsDelta()
+}
+
+func (o *objectInfo) Size() int64 {
+ return o.Length
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/patch_delta.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/patch_delta.go
new file mode 100644
index 00000000..960769c7
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/patch_delta.go
@@ -0,0 +1,526 @@
+package packfile
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+// See https://github.com/git/git/blob/49fa3dc76179e04b0833542fa52d0f287a4955ac/delta.h
+// https://github.com/git/git/blob/c2c5f6b1e479f2c38e0e01345350620944e3527f/patch-delta.c,
+// and https://github.com/tarruda/node-git-core/blob/master/src/js/delta.js
+// for details about the delta format.
+
+var (
+ ErrInvalidDelta = errors.New("invalid delta")
+ ErrDeltaCmd = errors.New("wrong delta command")
+)
+
+const (
+ payload = 0x7f // 0111 1111
+ continuation = 0x80 // 1000 0000
+)
+
+type offset struct {
+ mask byte
+ shift uint
+}
+
+var offsets = []offset{
+ {mask: 0x01, shift: 0},
+ {mask: 0x02, shift: 8},
+ {mask: 0x04, shift: 16},
+ {mask: 0x08, shift: 24},
+}
+
+var sizes = []offset{
+ {mask: 0x10, shift: 0},
+ {mask: 0x20, shift: 8},
+ {mask: 0x40, shift: 16},
+}
+
+// ApplyDelta writes to target the result of applying the modification deltas in delta to base.
+func ApplyDelta(target, base plumbing.EncodedObject, delta []byte) (err error) {
+ r, err := base.Reader()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(r, &err)
+
+ w, err := target.Writer()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(w, &err)
+
+ buf := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(buf)
+ _, err = buf.ReadFrom(r)
+ if err != nil {
+ return err
+ }
+ src := buf.Bytes()
+
+ dst := sync.GetBytesBuffer()
+ defer sync.PutBytesBuffer(dst)
+ err = patchDelta(dst, src, delta)
+ if err != nil {
+ return err
+ }
+
+ target.SetSize(int64(dst.Len()))
+
+ b := sync.GetByteSlice()
+ _, err = io.CopyBuffer(w, dst, *b)
+ sync.PutByteSlice(b)
+ return err
+}
+
+// PatchDelta returns the result of applying the modification deltas in delta to src.
+// An error will be returned if delta is corrupted (ErrDeltaLen) or an action command
+// is not copy from source or copy from delta (ErrDeltaCmd).
+func PatchDelta(src, delta []byte) ([]byte, error) {
+ b := &bytes.Buffer{}
+ if err := patchDelta(b, src, delta); err != nil {
+ return nil, err
+ }
+ return b.Bytes(), nil
+}
+
+func ReaderFromDelta(base plumbing.EncodedObject, deltaRC io.Reader) (io.ReadCloser, error) {
+ deltaBuf := bufio.NewReaderSize(deltaRC, 1024)
+ srcSz, err := decodeLEB128ByteReader(deltaBuf)
+ if err != nil {
+ if err == io.EOF {
+ return nil, ErrInvalidDelta
+ }
+ return nil, err
+ }
+ if srcSz != uint(base.Size()) {
+ return nil, ErrInvalidDelta
+ }
+
+ targetSz, err := decodeLEB128ByteReader(deltaBuf)
+ if err != nil {
+ if err == io.EOF {
+ return nil, ErrInvalidDelta
+ }
+ return nil, err
+ }
+ remainingTargetSz := targetSz
+
+ dstRd, dstWr := io.Pipe()
+
+ go func() {
+ baseRd, err := base.Reader()
+ if err != nil {
+ _ = dstWr.CloseWithError(ErrInvalidDelta)
+ return
+ }
+ defer baseRd.Close()
+
+ baseBuf := bufio.NewReader(baseRd)
+ basePos := uint(0)
+
+ for {
+ cmd, err := deltaBuf.ReadByte()
+ if err == io.EOF {
+ _ = dstWr.CloseWithError(ErrInvalidDelta)
+ return
+ }
+ if err != nil {
+ _ = dstWr.CloseWithError(err)
+ return
+ }
+
+ switch {
+ case isCopyFromSrc(cmd):
+ offset, err := decodeOffsetByteReader(cmd, deltaBuf)
+ if err != nil {
+ _ = dstWr.CloseWithError(err)
+ return
+ }
+ sz, err := decodeSizeByteReader(cmd, deltaBuf)
+ if err != nil {
+ _ = dstWr.CloseWithError(err)
+ return
+ }
+
+ if invalidSize(sz, targetSz) ||
+ invalidOffsetSize(offset, sz, srcSz) {
+ _ = dstWr.Close()
+ return
+ }
+
+ discard := offset - basePos
+ if basePos > offset {
+ _ = baseRd.Close()
+ baseRd, err = base.Reader()
+ if err != nil {
+ _ = dstWr.CloseWithError(ErrInvalidDelta)
+ return
+ }
+ baseBuf.Reset(baseRd)
+ discard = offset
+ }
+ for discard > math.MaxInt32 {
+ n, err := baseBuf.Discard(math.MaxInt32)
+ if err != nil {
+ _ = dstWr.CloseWithError(err)
+ return
+ }
+ basePos += uint(n)
+ discard -= uint(n)
+ }
+ for discard > 0 {
+ n, err := baseBuf.Discard(int(discard))
+ if err != nil {
+ _ = dstWr.CloseWithError(err)
+ return
+ }
+ basePos += uint(n)
+ discard -= uint(n)
+ }
+ if _, err := io.Copy(dstWr, io.LimitReader(baseBuf, int64(sz))); err != nil {
+ _ = dstWr.CloseWithError(err)
+ return
+ }
+ remainingTargetSz -= sz
+ basePos += sz
+
+ case isCopyFromDelta(cmd):
+ sz := uint(cmd) // cmd is the size itself
+ if invalidSize(sz, targetSz) {
+ _ = dstWr.CloseWithError(ErrInvalidDelta)
+ return
+ }
+ if _, err := io.Copy(dstWr, io.LimitReader(deltaBuf, int64(sz))); err != nil {
+ _ = dstWr.CloseWithError(err)
+ return
+ }
+
+ remainingTargetSz -= sz
+
+ default:
+ _ = dstWr.CloseWithError(ErrDeltaCmd)
+ return
+ }
+
+ if remainingTargetSz <= 0 {
+ _ = dstWr.Close()
+ return
+ }
+ }
+ }()
+
+ return dstRd, nil
+}
+
+func patchDelta(dst *bytes.Buffer, src, delta []byte) error {
+ if len(delta) < minCopySize {
+ return ErrInvalidDelta
+ }
+
+ srcSz, delta := decodeLEB128(delta)
+ if srcSz != uint(len(src)) {
+ return ErrInvalidDelta
+ }
+
+ targetSz, delta := decodeLEB128(delta)
+ remainingTargetSz := targetSz
+
+ var cmd byte
+ dst.Grow(int(targetSz))
+ for {
+ if len(delta) == 0 {
+ return ErrInvalidDelta
+ }
+
+ cmd = delta[0]
+ delta = delta[1:]
+
+ switch {
+ case isCopyFromSrc(cmd):
+ var offset, sz uint
+ var err error
+ offset, delta, err = decodeOffset(cmd, delta)
+ if err != nil {
+ return err
+ }
+
+ sz, delta, err = decodeSize(cmd, delta)
+ if err != nil {
+ return err
+ }
+
+ if invalidSize(sz, targetSz) ||
+ invalidOffsetSize(offset, sz, srcSz) {
+ break
+ }
+ dst.Write(src[offset : offset+sz])
+ remainingTargetSz -= sz
+
+ case isCopyFromDelta(cmd):
+ sz := uint(cmd) // cmd is the size itself
+ if invalidSize(sz, targetSz) {
+ return ErrInvalidDelta
+ }
+
+ if uint(len(delta)) < sz {
+ return ErrInvalidDelta
+ }
+
+ dst.Write(delta[0:sz])
+ remainingTargetSz -= sz
+ delta = delta[sz:]
+
+ default:
+ return ErrDeltaCmd
+ }
+
+ if remainingTargetSz <= 0 {
+ break
+ }
+ }
+
+ return nil
+}
+
+func patchDeltaWriter(dst io.Writer, base io.ReaderAt, delta io.Reader,
+ typ plumbing.ObjectType, writeHeader objectHeaderWriter) (uint, plumbing.Hash, error) {
+ deltaBuf := bufio.NewReaderSize(delta, 1024)
+ srcSz, err := decodeLEB128ByteReader(deltaBuf)
+ if err != nil {
+ if err == io.EOF {
+ return 0, plumbing.ZeroHash, ErrInvalidDelta
+ }
+ return 0, plumbing.ZeroHash, err
+ }
+
+ if r, ok := base.(*bytes.Reader); ok && srcSz != uint(r.Size()) {
+ return 0, plumbing.ZeroHash, ErrInvalidDelta
+ }
+
+ targetSz, err := decodeLEB128ByteReader(deltaBuf)
+ if err != nil {
+ if err == io.EOF {
+ return 0, plumbing.ZeroHash, ErrInvalidDelta
+ }
+ return 0, plumbing.ZeroHash, err
+ }
+
+ // If header still needs to be written, caller will provide
+ // a LazyObjectWriterHeader. This seems to be the case when
+ // dealing with thin-packs.
+ if writeHeader != nil {
+ err = writeHeader(typ, int64(targetSz))
+ if err != nil {
+ return 0, plumbing.ZeroHash, fmt.Errorf("could not lazy write header: %w", err)
+ }
+ }
+
+ remainingTargetSz := targetSz
+
+ hasher := plumbing.NewHasher(typ, int64(targetSz))
+ mw := io.MultiWriter(dst, hasher)
+
+ bufp := sync.GetByteSlice()
+ defer sync.PutByteSlice(bufp)
+
+ sr := io.NewSectionReader(base, int64(0), int64(srcSz))
+ // Keep both the io.LimitedReader types, so we can reset N.
+ baselr := io.LimitReader(sr, 0).(*io.LimitedReader)
+ deltalr := io.LimitReader(deltaBuf, 0).(*io.LimitedReader)
+
+ for {
+ buf := *bufp
+ cmd, err := deltaBuf.ReadByte()
+ if err == io.EOF {
+ return 0, plumbing.ZeroHash, ErrInvalidDelta
+ }
+ if err != nil {
+ return 0, plumbing.ZeroHash, err
+ }
+
+ if isCopyFromSrc(cmd) {
+ offset, err := decodeOffsetByteReader(cmd, deltaBuf)
+ if err != nil {
+ return 0, plumbing.ZeroHash, err
+ }
+ sz, err := decodeSizeByteReader(cmd, deltaBuf)
+ if err != nil {
+ return 0, plumbing.ZeroHash, err
+ }
+
+ if invalidSize(sz, targetSz) ||
+ invalidOffsetSize(offset, sz, srcSz) {
+ return 0, plumbing.ZeroHash, err
+ }
+
+ if _, err := sr.Seek(int64(offset), io.SeekStart); err != nil {
+ return 0, plumbing.ZeroHash, err
+ }
+ baselr.N = int64(sz)
+ if _, err := io.CopyBuffer(mw, baselr, buf); err != nil {
+ return 0, plumbing.ZeroHash, err
+ }
+ remainingTargetSz -= sz
+ } else if isCopyFromDelta(cmd) {
+ sz := uint(cmd) // cmd is the size itself
+ if invalidSize(sz, targetSz) {
+ return 0, plumbing.ZeroHash, ErrInvalidDelta
+ }
+ deltalr.N = int64(sz)
+ if _, err := io.CopyBuffer(mw, deltalr, buf); err != nil {
+ return 0, plumbing.ZeroHash, err
+ }
+
+ remainingTargetSz -= sz
+ } else {
+ return 0, plumbing.ZeroHash, err
+ }
+ if remainingTargetSz <= 0 {
+ break
+ }
+ }
+
+ return targetSz, hasher.Sum(), nil
+}
+
+// Decodes a number encoded as an unsigned LEB128 at the start of some
+// binary data and returns the decoded number and the rest of the
+// stream.
+//
+// This must be called twice on the delta data buffer, first to get the
+// expected source buffer size, and again to get the target buffer size.
+func decodeLEB128(input []byte) (uint, []byte) {
+ var num, sz uint
+ var b byte
+ for {
+ b = input[sz]
+ num |= (uint(b) & payload) << (sz * 7) // concats 7 bits chunks
+ sz++
+
+ if uint(b)&continuation == 0 || sz == uint(len(input)) {
+ break
+ }
+ }
+
+ return num, input[sz:]
+}
+
+func decodeLEB128ByteReader(input io.ByteReader) (uint, error) {
+ var num, sz uint
+ for {
+ b, err := input.ReadByte()
+ if err != nil {
+ return 0, err
+ }
+
+ num |= (uint(b) & payload) << (sz * 7) // concats 7 bits chunks
+ sz++
+
+ if uint(b)&continuation == 0 {
+ break
+ }
+ }
+
+ return num, nil
+}
+
+func isCopyFromSrc(cmd byte) bool {
+ return (cmd & continuation) != 0
+}
+
+func isCopyFromDelta(cmd byte) bool {
+ return (cmd&continuation) == 0 && cmd != 0
+}
+
+func decodeOffsetByteReader(cmd byte, delta io.ByteReader) (uint, error) {
+ var offset uint
+ for _, o := range offsets {
+ if (cmd & o.mask) != 0 {
+ next, err := delta.ReadByte()
+ if err != nil {
+ return 0, err
+ }
+ offset |= uint(next) << o.shift
+ }
+ }
+
+ return offset, nil
+}
+
+func decodeOffset(cmd byte, delta []byte) (uint, []byte, error) {
+ var offset uint
+ for _, o := range offsets {
+ if (cmd & o.mask) != 0 {
+ if len(delta) == 0 {
+ return 0, nil, ErrInvalidDelta
+ }
+ offset |= uint(delta[0]) << o.shift
+ delta = delta[1:]
+ }
+ }
+
+ return offset, delta, nil
+}
+
+func decodeSizeByteReader(cmd byte, delta io.ByteReader) (uint, error) {
+ var sz uint
+ for _, s := range sizes {
+ if (cmd & s.mask) != 0 {
+ next, err := delta.ReadByte()
+ if err != nil {
+ return 0, err
+ }
+ sz |= uint(next) << s.shift
+ }
+ }
+
+ if sz == 0 {
+ sz = maxCopySize
+ }
+
+ return sz, nil
+}
+
+func decodeSize(cmd byte, delta []byte) (uint, []byte, error) {
+ var sz uint
+ for _, s := range sizes {
+ if (cmd & s.mask) != 0 {
+ if len(delta) == 0 {
+ return 0, nil, ErrInvalidDelta
+ }
+ sz |= uint(delta[0]) << s.shift
+ delta = delta[1:]
+ }
+ }
+ if sz == 0 {
+ sz = maxCopySize
+ }
+
+ return sz, delta, nil
+}
+
+func invalidSize(sz, targetSz uint) bool {
+ return sz > targetSz
+}
+
+func invalidOffsetSize(offset, sz, srcSz uint) bool {
+ return sumOverflows(offset, sz) ||
+ offset+sz > srcSz
+}
+
+func sumOverflows(a, b uint) bool {
+ return a+b < a
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/scanner.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/scanner.go
new file mode 100644
index 00000000..730343ee
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/scanner.go
@@ -0,0 +1,474 @@
+package packfile
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "hash"
+ "hash/crc32"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/utils/binary"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+var (
+ // ErrEmptyPackfile is returned by ReadHeader when no data is found in the packfile
+ ErrEmptyPackfile = NewError("empty packfile")
+ // ErrBadSignature is returned by ReadHeader when the signature in the packfile is incorrect.
+ ErrBadSignature = NewError("malformed pack file signature")
+ // ErrUnsupportedVersion is returned by ReadHeader when the packfile version is
+ // different than VersionSupported.
+ ErrUnsupportedVersion = NewError("unsupported packfile version")
+ // ErrSeekNotSupported returned if seek is not support
+ ErrSeekNotSupported = NewError("not seek support")
+)
+
+// ObjectHeader contains the information related to the object, this information
+// is collected from the previous bytes to the content of the object.
+type ObjectHeader struct {
+ Type plumbing.ObjectType
+ Offset int64
+ Length int64
+ Reference plumbing.Hash
+ OffsetReference int64
+}
+
+type Scanner struct {
+ r *scannerReader
+ crc hash.Hash32
+
+ // pendingObject is used to detect if an object has been read, or still
+ // is waiting to be read
+ pendingObject *ObjectHeader
+ version, objects uint32
+
+ // lsSeekable says if this scanner can do Seek or not, to have a Scanner
+ // seekable a r implementing io.Seeker is required
+ IsSeekable bool
+}
+
+// NewScanner returns a new Scanner based on a reader, if the given reader
+// implements io.ReadSeeker the Scanner will be also Seekable
+func NewScanner(r io.Reader) *Scanner {
+ _, ok := r.(io.ReadSeeker)
+
+ crc := crc32.NewIEEE()
+ return &Scanner{
+ r: newScannerReader(r, crc),
+ crc: crc,
+ IsSeekable: ok,
+ }
+}
+
+func (s *Scanner) Reset(r io.Reader) {
+ _, ok := r.(io.ReadSeeker)
+
+ s.r.Reset(r)
+ s.crc.Reset()
+ s.IsSeekable = ok
+ s.pendingObject = nil
+ s.version = 0
+ s.objects = 0
+}
+
+// Header reads the whole packfile header (signature, version and object count).
+// It returns the version and the object count and performs checks on the
+// validity of the signature and the version fields.
+func (s *Scanner) Header() (version, objects uint32, err error) {
+ if s.version != 0 {
+ return s.version, s.objects, nil
+ }
+
+ sig, err := s.readSignature()
+ if err != nil {
+ if err == io.EOF {
+ err = ErrEmptyPackfile
+ }
+
+ return
+ }
+
+ if !s.isValidSignature(sig) {
+ err = ErrBadSignature
+ return
+ }
+
+ version, err = s.readVersion()
+ s.version = version
+ if err != nil {
+ return
+ }
+
+ if !s.isSupportedVersion(version) {
+ err = ErrUnsupportedVersion.AddDetails("%d", version)
+ return
+ }
+
+ objects, err = s.readCount()
+ s.objects = objects
+ return
+}
+
+// readSignature reads a returns the signature field in the packfile.
+func (s *Scanner) readSignature() ([]byte, error) {
+ var sig = make([]byte, 4)
+ if _, err := io.ReadFull(s.r, sig); err != nil {
+ return []byte{}, err
+ }
+
+ return sig, nil
+}
+
+// isValidSignature returns if sig is a valid packfile signature.
+func (s *Scanner) isValidSignature(sig []byte) bool {
+ return bytes.Equal(sig, signature)
+}
+
+// readVersion reads and returns the version field of a packfile.
+func (s *Scanner) readVersion() (uint32, error) {
+ return binary.ReadUint32(s.r)
+}
+
+// isSupportedVersion returns whether version v is supported by the parser.
+// The current supported version is VersionSupported, defined above.
+func (s *Scanner) isSupportedVersion(v uint32) bool {
+ return v == VersionSupported
+}
+
+// readCount reads and returns the count of objects field of a packfile.
+func (s *Scanner) readCount() (uint32, error) {
+ return binary.ReadUint32(s.r)
+}
+
+// SeekObjectHeader seeks to specified offset and returns the ObjectHeader
+// for the next object in the reader
+func (s *Scanner) SeekObjectHeader(offset int64) (*ObjectHeader, error) {
+ // if seeking we assume that you are not interested in the header
+ if s.version == 0 {
+ s.version = VersionSupported
+ }
+
+ if _, err := s.r.Seek(offset, io.SeekStart); err != nil {
+ return nil, err
+ }
+
+ h, err := s.nextObjectHeader()
+ if err != nil {
+ return nil, err
+ }
+
+ h.Offset = offset
+ return h, nil
+}
+
+// NextObjectHeader returns the ObjectHeader for the next object in the reader
+func (s *Scanner) NextObjectHeader() (*ObjectHeader, error) {
+ if err := s.doPending(); err != nil {
+ return nil, err
+ }
+
+ offset, err := s.r.Seek(0, io.SeekCurrent)
+ if err != nil {
+ return nil, err
+ }
+
+ h, err := s.nextObjectHeader()
+ if err != nil {
+ return nil, err
+ }
+
+ h.Offset = offset
+ return h, nil
+}
+
+// nextObjectHeader returns the ObjectHeader for the next object in the reader
+// without the Offset field
+func (s *Scanner) nextObjectHeader() (*ObjectHeader, error) {
+ s.r.Flush()
+ s.crc.Reset()
+
+ h := &ObjectHeader{}
+ s.pendingObject = h
+
+ var err error
+ h.Offset, err = s.r.Seek(0, io.SeekCurrent)
+ if err != nil {
+ return nil, err
+ }
+
+ h.Type, h.Length, err = s.readObjectTypeAndLength()
+ if err != nil {
+ return nil, err
+ }
+
+ switch h.Type {
+ case plumbing.OFSDeltaObject:
+ no, err := binary.ReadVariableWidthInt(s.r)
+ if err != nil {
+ return nil, err
+ }
+
+ h.OffsetReference = h.Offset - no
+ case plumbing.REFDeltaObject:
+ var err error
+ h.Reference, err = binary.ReadHash(s.r)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return h, nil
+}
+
+func (s *Scanner) doPending() error {
+ if s.version == 0 {
+ var err error
+ s.version, s.objects, err = s.Header()
+ if err != nil {
+ return err
+ }
+ }
+
+ return s.discardObjectIfNeeded()
+}
+
+func (s *Scanner) discardObjectIfNeeded() error {
+ if s.pendingObject == nil {
+ return nil
+ }
+
+ h := s.pendingObject
+ n, _, err := s.NextObject(io.Discard)
+ if err != nil {
+ return err
+ }
+
+ if n != h.Length {
+ return fmt.Errorf(
+ "error discarding object, discarded %d, expected %d",
+ n, h.Length,
+ )
+ }
+
+ return nil
+}
+
+// ReadObjectTypeAndLength reads and returns the object type and the
+// length field from an object entry in a packfile.
+func (s *Scanner) readObjectTypeAndLength() (plumbing.ObjectType, int64, error) {
+ t, c, err := s.readType()
+ if err != nil {
+ return t, 0, err
+ }
+
+ l, err := s.readLength(c)
+
+ return t, l, err
+}
+
+func (s *Scanner) readType() (plumbing.ObjectType, byte, error) {
+ var c byte
+ var err error
+ if c, err = s.r.ReadByte(); err != nil {
+ return plumbing.ObjectType(0), 0, err
+ }
+
+ typ := parseType(c)
+
+ return typ, c, nil
+}
+
+func parseType(b byte) plumbing.ObjectType {
+ return plumbing.ObjectType((b & maskType) >> firstLengthBits)
+}
+
+// the length is codified in the last 4 bits of the first byte and in
+// the last 7 bits of subsequent bytes. Last byte has a 0 MSB.
+func (s *Scanner) readLength(first byte) (int64, error) {
+ length := int64(first & maskFirstLength)
+
+ c := first
+ shift := firstLengthBits
+ var err error
+ for c&maskContinue > 0 {
+ if c, err = s.r.ReadByte(); err != nil {
+ return 0, err
+ }
+
+ length += int64(c&maskLength) << shift
+ shift += lengthBits
+ }
+
+ return length, nil
+}
+
+// NextObject writes the content of the next object into the reader, returns
+// the number of bytes written, the CRC32 of the content and an error, if any
+func (s *Scanner) NextObject(w io.Writer) (written int64, crc32 uint32, err error) {
+ s.pendingObject = nil
+ written, err = s.copyObject(w)
+
+ s.r.Flush()
+ crc32 = s.crc.Sum32()
+ s.crc.Reset()
+
+ return
+}
+
+// ReadObject returns a reader for the object content and an error
+func (s *Scanner) ReadObject() (io.ReadCloser, error) {
+ s.pendingObject = nil
+ zr, err := sync.GetZlibReader(s.r)
+
+ if err != nil {
+ return nil, fmt.Errorf("zlib reset error: %s", err)
+ }
+
+ return ioutil.NewReadCloserWithCloser(zr.Reader, func() error {
+ sync.PutZlibReader(zr)
+ return nil
+ }), nil
+}
+
+// ReadRegularObject reads and write a non-deltified object
+// from it zlib stream in an object entry in the packfile.
+func (s *Scanner) copyObject(w io.Writer) (n int64, err error) {
+ zr, err := sync.GetZlibReader(s.r)
+ defer sync.PutZlibReader(zr)
+
+ if err != nil {
+ return 0, fmt.Errorf("zlib reset error: %s", err)
+ }
+
+ defer ioutil.CheckClose(zr.Reader, &err)
+ buf := sync.GetByteSlice()
+ n, err = io.CopyBuffer(w, zr.Reader, *buf)
+ sync.PutByteSlice(buf)
+ return
+}
+
+// SeekFromStart sets a new offset from start, returns the old position before
+// the change.
+func (s *Scanner) SeekFromStart(offset int64) (previous int64, err error) {
+ // if seeking we assume that you are not interested in the header
+ if s.version == 0 {
+ s.version = VersionSupported
+ }
+
+ previous, err = s.r.Seek(0, io.SeekCurrent)
+ if err != nil {
+ return -1, err
+ }
+
+ _, err = s.r.Seek(offset, io.SeekStart)
+ return previous, err
+}
+
+// Checksum returns the checksum of the packfile
+func (s *Scanner) Checksum() (plumbing.Hash, error) {
+ err := s.discardObjectIfNeeded()
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return binary.ReadHash(s.r)
+}
+
+// Close reads the reader until io.EOF
+func (s *Scanner) Close() error {
+ buf := sync.GetByteSlice()
+ _, err := io.CopyBuffer(io.Discard, s.r, *buf)
+ sync.PutByteSlice(buf)
+
+ return err
+}
+
+// Flush is a no-op (deprecated)
+func (s *Scanner) Flush() error {
+ return nil
+}
+
+// scannerReader has the following characteristics:
+// - Provides an io.SeekReader impl for bufio.Reader, when the underlying
+// reader supports it.
+// - Keeps track of the current read position, for when the underlying reader
+// isn't an io.SeekReader, but we still want to know the current offset.
+// - Writes to the hash writer what it reads, with the aid of a smaller buffer.
+// The buffer helps avoid a performance penalty for performing small writes
+// to the crc32 hash writer.
+type scannerReader struct {
+ reader io.Reader
+ crc io.Writer
+ rbuf *bufio.Reader
+ wbuf *bufio.Writer
+ offset int64
+}
+
+func newScannerReader(r io.Reader, h io.Writer) *scannerReader {
+ sr := &scannerReader{
+ rbuf: bufio.NewReader(nil),
+ wbuf: bufio.NewWriterSize(nil, 64),
+ crc: h,
+ }
+ sr.Reset(r)
+
+ return sr
+}
+
+func (r *scannerReader) Reset(reader io.Reader) {
+ r.reader = reader
+ r.rbuf.Reset(r.reader)
+ r.wbuf.Reset(r.crc)
+
+ r.offset = 0
+ if seeker, ok := r.reader.(io.ReadSeeker); ok {
+ r.offset, _ = seeker.Seek(0, io.SeekCurrent)
+ }
+}
+
+func (r *scannerReader) Read(p []byte) (n int, err error) {
+ n, err = r.rbuf.Read(p)
+
+ r.offset += int64(n)
+ if _, err := r.wbuf.Write(p[:n]); err != nil {
+ return n, err
+ }
+ return
+}
+
+func (r *scannerReader) ReadByte() (b byte, err error) {
+ b, err = r.rbuf.ReadByte()
+ if err == nil {
+ r.offset++
+ return b, r.wbuf.WriteByte(b)
+ }
+ return
+}
+
+func (r *scannerReader) Flush() error {
+ return r.wbuf.Flush()
+}
+
+// Seek seeks to a location. If the underlying reader is not an io.ReadSeeker,
+// then only whence=io.SeekCurrent is supported, any other operation fails.
+func (r *scannerReader) Seek(offset int64, whence int) (int64, error) {
+ var err error
+
+ if seeker, ok := r.reader.(io.ReadSeeker); !ok {
+ if whence != io.SeekCurrent || offset != 0 {
+ return -1, ErrSeekNotSupported
+ }
+ } else {
+ if whence == io.SeekCurrent && offset == 0 {
+ return r.offset, nil
+ }
+
+ r.offset, err = seeker.Seek(offset, whence)
+ r.rbuf.Reset(r.reader)
+ }
+
+ return r.offset, err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/encoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/encoder.go
new file mode 100644
index 00000000..b6144faf
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/encoder.go
@@ -0,0 +1,126 @@
+// Package pktline implements reading payloads form pkt-lines and encoding
+// pkt-lines from payloads.
+package pktline
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/utils/trace"
+)
+
+// An Encoder writes pkt-lines to an output stream.
+type Encoder struct {
+ w io.Writer
+}
+
+const (
+ // MaxPayloadSize is the maximum payload size of a pkt-line in bytes.
+ MaxPayloadSize = 65516
+
+ // For compatibility with canonical Git implementation, accept longer pkt-lines
+ OversizePayloadMax = 65520
+)
+
+var (
+ // FlushPkt are the contents of a flush-pkt pkt-line.
+ FlushPkt = []byte{'0', '0', '0', '0'}
+ // Flush is the payload to use with the Encode method to encode a flush-pkt.
+ Flush = []byte{}
+ // FlushString is the payload to use with the EncodeString method to encode a flush-pkt.
+ FlushString = ""
+ // ErrPayloadTooLong is returned by the Encode methods when any of the
+ // provided payloads is bigger than MaxPayloadSize.
+ ErrPayloadTooLong = errors.New("payload is too long")
+)
+
+// NewEncoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+ return &Encoder{
+ w: w,
+ }
+}
+
+// Flush encodes a flush-pkt to the output stream.
+func (e *Encoder) Flush() error {
+ defer trace.Packet.Print("packet: > 0000")
+ _, err := e.w.Write(FlushPkt)
+ return err
+}
+
+// Encode encodes a pkt-line with the payload specified and write it to
+// the output stream. If several payloads are specified, each of them
+// will get streamed in their own pkt-lines.
+func (e *Encoder) Encode(payloads ...[]byte) error {
+ for _, p := range payloads {
+ if err := e.encodeLine(p); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (e *Encoder) encodeLine(p []byte) error {
+ if len(p) > MaxPayloadSize {
+ return ErrPayloadTooLong
+ }
+
+ if bytes.Equal(p, Flush) {
+ return e.Flush()
+ }
+
+ n := len(p) + 4
+ defer trace.Packet.Printf("packet: > %04x %s", n, p)
+ if _, err := e.w.Write(asciiHex16(n)); err != nil {
+ return err
+ }
+ _, err := e.w.Write(p)
+ return err
+}
+
+// Returns the hexadecimal ascii representation of the 16 less
+// significant bits of n. The length of the returned slice will always
+// be 4. Example: if n is 1234 (0x4d2), the return value will be
+// []byte{'0', '4', 'd', '2'}.
+func asciiHex16(n int) []byte {
+ var ret [4]byte
+ ret[0] = byteToASCIIHex(byte(n & 0xf000 >> 12))
+ ret[1] = byteToASCIIHex(byte(n & 0x0f00 >> 8))
+ ret[2] = byteToASCIIHex(byte(n & 0x00f0 >> 4))
+ ret[3] = byteToASCIIHex(byte(n & 0x000f))
+
+ return ret[:]
+}
+
+// turns a byte into its hexadecimal ascii representation. Example:
+// from 11 (0xb) to 'b'.
+func byteToASCIIHex(n byte) byte {
+ if n < 10 {
+ return '0' + n
+ }
+
+ return 'a' - 10 + n
+}
+
+// EncodeString works similarly as Encode but payloads are specified as strings.
+func (e *Encoder) EncodeString(payloads ...string) error {
+ for _, p := range payloads {
+ if err := e.Encode([]byte(p)); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Encodef encodes a single pkt-line with the payload formatted as
+// the format specifier. The rest of the arguments will be used in
+// the format string.
+func (e *Encoder) Encodef(format string, a ...interface{}) error {
+ return e.EncodeString(
+ fmt.Sprintf(format, a...),
+ )
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/error.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/error.go
new file mode 100644
index 00000000..2c0e5a72
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/error.go
@@ -0,0 +1,51 @@
+package pktline
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "strings"
+)
+
+var (
+ // ErrInvalidErrorLine is returned by Decode when the packet line is not an
+ // error line.
+ ErrInvalidErrorLine = errors.New("expected an error-line")
+
+ errPrefix = []byte("ERR ")
+)
+
+// ErrorLine is a packet line that contains an error message.
+// Once this packet is sent by client or server, the data transfer process is
+// terminated.
+// See https://git-scm.com/docs/pack-protocol#_pkt_line_format
+type ErrorLine struct {
+ Text string
+}
+
+// Error implements the error interface.
+func (e *ErrorLine) Error() string {
+ return e.Text
+}
+
+// Encode encodes the ErrorLine into a packet line.
+func (e *ErrorLine) Encode(w io.Writer) error {
+ p := NewEncoder(w)
+ return p.Encodef("%s%s\n", string(errPrefix), e.Text)
+}
+
+// Decode decodes a packet line into an ErrorLine.
+func (e *ErrorLine) Decode(r io.Reader) error {
+ s := NewScanner(r)
+ if !s.Scan() {
+ return s.Err()
+ }
+
+ line := s.Bytes()
+ if !bytes.HasPrefix(line, errPrefix) {
+ return ErrInvalidErrorLine
+ }
+
+ e.Text = strings.TrimSpace(string(line[4:]))
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/scanner.go b/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/scanner.go
new file mode 100644
index 00000000..fbb137de
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/format/pktline/scanner.go
@@ -0,0 +1,146 @@
+package pktline
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "strings"
+
+ "github.com/go-git/go-git/v5/utils/trace"
+)
+
+const (
+ lenSize = 4
+)
+
+// ErrInvalidPktLen is returned by Err() when an invalid pkt-len is found.
+var ErrInvalidPktLen = errors.New("invalid pkt-len found")
+
+// Scanner provides a convenient interface for reading the payloads of a
+// series of pkt-lines. It takes an io.Reader providing the source,
+// which then can be tokenized through repeated calls to the Scan
+// method.
+//
+// After each Scan call, the Bytes method will return the payload of the
+// corresponding pkt-line on a shared buffer, which will be 65516 bytes
+// or smaller. Flush pkt-lines are represented by empty byte slices.
+//
+// Scanning stops at EOF or the first I/O error.
+type Scanner struct {
+ r io.Reader // The reader provided by the client
+ err error // Sticky error
+ payload []byte // Last pkt-payload
+ len [lenSize]byte // Last pkt-len
+}
+
+// NewScanner returns a new Scanner to read from r.
+func NewScanner(r io.Reader) *Scanner {
+ return &Scanner{
+ r: r,
+ }
+}
+
+// Err returns the first error encountered by the Scanner.
+func (s *Scanner) Err() error {
+ return s.err
+}
+
+// Scan advances the Scanner to the next pkt-line, whose payload will
+// then be available through the Bytes method. Scanning stops at EOF
+// or the first I/O error. After Scan returns false, the Err method
+// will return any error that occurred during scanning, except that if
+// it was io.EOF, Err will return nil.
+func (s *Scanner) Scan() bool {
+ var l int
+ l, s.err = s.readPayloadLen()
+ if s.err == io.EOF {
+ s.err = nil
+ return false
+ }
+ if s.err != nil {
+ return false
+ }
+
+ if cap(s.payload) < l {
+ s.payload = make([]byte, 0, l)
+ }
+
+ if _, s.err = io.ReadFull(s.r, s.payload[:l]); s.err != nil {
+ return false
+ }
+ s.payload = s.payload[:l]
+ trace.Packet.Printf("packet: < %04x %s", l, s.payload)
+
+ if bytes.HasPrefix(s.payload, errPrefix) {
+ s.err = &ErrorLine{
+ Text: strings.TrimSpace(string(s.payload[4:])),
+ }
+ return false
+ }
+
+ return true
+}
+
+// Bytes returns the most recent payload generated by a call to Scan.
+// The underlying array may point to data that will be overwritten by a
+// subsequent call to Scan. It does no allocation.
+func (s *Scanner) Bytes() []byte {
+ return s.payload
+}
+
+// Method readPayloadLen returns the payload length by reading the
+// pkt-len and subtracting the pkt-len size.
+func (s *Scanner) readPayloadLen() (int, error) {
+ if _, err := io.ReadFull(s.r, s.len[:]); err != nil {
+ if err == io.ErrUnexpectedEOF {
+ return 0, ErrInvalidPktLen
+ }
+
+ return 0, err
+ }
+
+ n, err := hexDecode(s.len)
+ if err != nil {
+ return 0, err
+ }
+
+ switch {
+ case n == 0:
+ return 0, nil
+ case n <= lenSize:
+ return 0, ErrInvalidPktLen
+ case n > OversizePayloadMax+lenSize:
+ return 0, ErrInvalidPktLen
+ default:
+ return n - lenSize, nil
+ }
+}
+
+// Turns the hexadecimal representation of a number in a byte slice into
+// a number. This function substitute strconv.ParseUint(string(buf), 16,
+// 16) and/or hex.Decode, to avoid generating new strings, thus helping the
+// GC.
+func hexDecode(buf [lenSize]byte) (int, error) {
+ var ret int
+ for i := 0; i < lenSize; i++ {
+ n, err := asciiHexToByte(buf[i])
+ if err != nil {
+ return 0, ErrInvalidPktLen
+ }
+ ret = 16*ret + int(n)
+ }
+ return ret, nil
+}
+
+// turns the hexadecimal ascii representation of a byte into its
+// numerical value. Example: from 'b' to 11 (0xb).
+func asciiHexToByte(b byte) (byte, error) {
+ switch {
+ case b >= '0' && b <= '9':
+ return b - '0', nil
+ case b >= 'a' && b <= 'f':
+ return b - 'a' + 10, nil
+ default:
+ return 0, ErrInvalidPktLen
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/hash.go b/vendor/github.com/go-git/go-git/v5/plumbing/hash.go
new file mode 100644
index 00000000..39bb73fb
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/hash.go
@@ -0,0 +1,84 @@
+package plumbing
+
+import (
+ "bytes"
+ "encoding/hex"
+ "sort"
+ "strconv"
+
+ "github.com/go-git/go-git/v5/plumbing/hash"
+)
+
+// Hash SHA1 hashed content
+type Hash [hash.Size]byte
+
+// ZeroHash is Hash with value zero
+var ZeroHash Hash
+
+// ComputeHash compute the hash for a given ObjectType and content
+func ComputeHash(t ObjectType, content []byte) Hash {
+ h := NewHasher(t, int64(len(content)))
+ h.Write(content)
+ return h.Sum()
+}
+
+// NewHash return a new Hash from a hexadecimal hash representation
+func NewHash(s string) Hash {
+ b, _ := hex.DecodeString(s)
+
+ var h Hash
+ copy(h[:], b)
+
+ return h
+}
+
+func (h Hash) IsZero() bool {
+ var empty Hash
+ return h == empty
+}
+
+func (h Hash) String() string {
+ return hex.EncodeToString(h[:])
+}
+
+type Hasher struct {
+ hash.Hash
+}
+
+func NewHasher(t ObjectType, size int64) Hasher {
+ h := Hasher{hash.New(hash.CryptoType)}
+ h.Write(t.Bytes())
+ h.Write([]byte(" "))
+ h.Write([]byte(strconv.FormatInt(size, 10)))
+ h.Write([]byte{0})
+ return h
+}
+
+func (h Hasher) Sum() (hash Hash) {
+ copy(hash[:], h.Hash.Sum(nil))
+ return
+}
+
+// HashesSort sorts a slice of Hashes in increasing order.
+func HashesSort(a []Hash) {
+ sort.Sort(HashSlice(a))
+}
+
+// HashSlice attaches the methods of sort.Interface to []Hash, sorting in
+// increasing order.
+type HashSlice []Hash
+
+func (p HashSlice) Len() int { return len(p) }
+func (p HashSlice) Less(i, j int) bool { return bytes.Compare(p[i][:], p[j][:]) < 0 }
+func (p HashSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+// IsHash returns true if the given string is a valid hash.
+func IsHash(s string) bool {
+ switch len(s) {
+ case hash.HexSize:
+ _, err := hex.DecodeString(s)
+ return err == nil
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/hash/hash.go b/vendor/github.com/go-git/go-git/v5/plumbing/hash/hash.go
new file mode 100644
index 00000000..8609848f
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/hash/hash.go
@@ -0,0 +1,60 @@
+// package hash provides a way for managing the
+// underlying hash implementations used across go-git.
+package hash
+
+import (
+ "crypto"
+ "fmt"
+ "hash"
+
+ "github.com/pjbgf/sha1cd"
+)
+
+// algos is a map of hash algorithms.
+var algos = map[crypto.Hash]func() hash.Hash{}
+
+func init() {
+ reset()
+}
+
+// reset resets the default algos value. Can be used after running tests
+// that registers new algorithms to avoid side effects.
+func reset() {
+ algos[crypto.SHA1] = sha1cd.New
+ algos[crypto.SHA256] = crypto.SHA256.New
+}
+
+// RegisterHash allows for the hash algorithm used to be overridden.
+// This ensures the hash selection for go-git must be explicit, when
+// overriding the default value.
+func RegisterHash(h crypto.Hash, f func() hash.Hash) error {
+ if f == nil {
+ return fmt.Errorf("cannot register hash: f is nil")
+ }
+
+ switch h {
+ case crypto.SHA1:
+ algos[h] = f
+ case crypto.SHA256:
+ algos[h] = f
+ default:
+ return fmt.Errorf("unsupported hash function: %v", h)
+ }
+ return nil
+}
+
+// Hash is the same as hash.Hash. This allows consumers
+// to not having to import this package alongside "hash".
+type Hash interface {
+ hash.Hash
+}
+
+// New returns a new Hash for the given hash function.
+// It panics if the hash function is not registered.
+func New(h crypto.Hash) Hash {
+ hh, ok := algos[h]
+ if !ok {
+ panic(fmt.Sprintf("hash algorithm not registered: %v", h))
+ }
+ return hh()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/hash/hash_sha1.go b/vendor/github.com/go-git/go-git/v5/plumbing/hash/hash_sha1.go
new file mode 100644
index 00000000..e3cb60fe
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/hash/hash_sha1.go
@@ -0,0 +1,15 @@
+//go:build !sha256
+// +build !sha256
+
+package hash
+
+import "crypto"
+
+const (
+ // CryptoType defines what hash algorithm is being used.
+ CryptoType = crypto.SHA1
+ // Size defines the amount of bytes the hash yields.
+ Size = 20
+ // HexSize defines the strings size of the hash when represented in hexadecimal.
+ HexSize = 40
+)
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/hash/hash_sha256.go b/vendor/github.com/go-git/go-git/v5/plumbing/hash/hash_sha256.go
new file mode 100644
index 00000000..1c52b897
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/hash/hash_sha256.go
@@ -0,0 +1,15 @@
+//go:build sha256
+// +build sha256
+
+package hash
+
+import "crypto"
+
+const (
+ // CryptoType defines what hash algorithm is being used.
+ CryptoType = crypto.SHA256
+ // Size defines the amount of bytes the hash yields.
+ Size = 32
+ // HexSize defines the strings size of the hash when represented in hexadecimal.
+ HexSize = 64
+)
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/memory.go b/vendor/github.com/go-git/go-git/v5/plumbing/memory.go
new file mode 100644
index 00000000..6d11271d
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/memory.go
@@ -0,0 +1,72 @@
+package plumbing
+
+import (
+ "bytes"
+ "io"
+)
+
+// MemoryObject on memory Object implementation
+type MemoryObject struct {
+ t ObjectType
+ h Hash
+ cont []byte
+ sz int64
+}
+
+// Hash returns the object Hash, the hash is calculated on-the-fly the first
+// time it's called, in all subsequent calls the same Hash is returned even
+// if the type or the content have changed. The Hash is only generated if the
+// size of the content is exactly the object size.
+func (o *MemoryObject) Hash() Hash {
+ if o.h == ZeroHash && int64(len(o.cont)) == o.sz {
+ o.h = ComputeHash(o.t, o.cont)
+ }
+
+ return o.h
+}
+
+// Type returns the ObjectType
+func (o *MemoryObject) Type() ObjectType { return o.t }
+
+// SetType sets the ObjectType
+func (o *MemoryObject) SetType(t ObjectType) { o.t = t }
+
+// Size returns the size of the object
+func (o *MemoryObject) Size() int64 { return o.sz }
+
+// SetSize set the object size, a content of the given size should be written
+// afterwards
+func (o *MemoryObject) SetSize(s int64) { o.sz = s }
+
+// Reader returns an io.ReadCloser used to read the object's content.
+//
+// For a MemoryObject, this reader is seekable.
+func (o *MemoryObject) Reader() (io.ReadCloser, error) {
+ return nopCloser{bytes.NewReader(o.cont)}, nil
+}
+
+// Writer returns a ObjectWriter used to write the object's content.
+func (o *MemoryObject) Writer() (io.WriteCloser, error) {
+ return o, nil
+}
+
+func (o *MemoryObject) Write(p []byte) (n int, err error) {
+ o.cont = append(o.cont, p...)
+ o.sz = int64(len(o.cont))
+
+ return len(p), nil
+}
+
+// Close releases any resources consumed by the object when it is acting as a
+// ObjectWriter.
+func (o *MemoryObject) Close() error { return nil }
+
+// nopCloser exposes the extra methods of bytes.Reader while nopping Close().
+//
+// This allows clients to attempt seeking in a cached Blob's Reader.
+type nopCloser struct {
+ *bytes.Reader
+}
+
+// Close does nothing.
+func (nc nopCloser) Close() error { return nil }
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object.go b/vendor/github.com/go-git/go-git/v5/plumbing/object.go
new file mode 100644
index 00000000..3ee9de9f
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object.go
@@ -0,0 +1,111 @@
+// package plumbing implement the core interfaces and structs used by go-git
+package plumbing
+
+import (
+ "errors"
+ "io"
+)
+
+var (
+ ErrObjectNotFound = errors.New("object not found")
+ // ErrInvalidType is returned when an invalid object type is provided.
+ ErrInvalidType = errors.New("invalid object type")
+)
+
+// Object is a generic representation of any git object
+type EncodedObject interface {
+ Hash() Hash
+ Type() ObjectType
+ SetType(ObjectType)
+ Size() int64
+ SetSize(int64)
+ Reader() (io.ReadCloser, error)
+ Writer() (io.WriteCloser, error)
+}
+
+// DeltaObject is an EncodedObject representing a delta.
+type DeltaObject interface {
+ EncodedObject
+ // BaseHash returns the hash of the object used as base for this delta.
+ BaseHash() Hash
+ // ActualHash returns the hash of the object after applying the delta.
+ ActualHash() Hash
+ // Size returns the size of the object after applying the delta.
+ ActualSize() int64
+}
+
+// ObjectType internal object type
+// Integer values from 0 to 7 map to those exposed by git.
+// AnyObject is used to represent any from 0 to 7.
+type ObjectType int8
+
+const (
+ InvalidObject ObjectType = 0
+ CommitObject ObjectType = 1
+ TreeObject ObjectType = 2
+ BlobObject ObjectType = 3
+ TagObject ObjectType = 4
+ // 5 reserved for future expansion
+ OFSDeltaObject ObjectType = 6
+ REFDeltaObject ObjectType = 7
+
+ AnyObject ObjectType = -127
+)
+
+func (t ObjectType) String() string {
+ switch t {
+ case CommitObject:
+ return "commit"
+ case TreeObject:
+ return "tree"
+ case BlobObject:
+ return "blob"
+ case TagObject:
+ return "tag"
+ case OFSDeltaObject:
+ return "ofs-delta"
+ case REFDeltaObject:
+ return "ref-delta"
+ case AnyObject:
+ return "any"
+ default:
+ return "unknown"
+ }
+}
+
+func (t ObjectType) Bytes() []byte {
+ return []byte(t.String())
+}
+
+// Valid returns true if t is a valid ObjectType.
+func (t ObjectType) Valid() bool {
+ return t >= CommitObject && t <= REFDeltaObject
+}
+
+// IsDelta returns true for any ObjectType that represents a delta (i.e.
+// REFDeltaObject or OFSDeltaObject).
+func (t ObjectType) IsDelta() bool {
+ return t == REFDeltaObject || t == OFSDeltaObject
+}
+
+// ParseObjectType parses a string representation of ObjectType. It returns an
+// error on parse failure.
+func ParseObjectType(value string) (typ ObjectType, err error) {
+ switch value {
+ case "commit":
+ typ = CommitObject
+ case "tree":
+ typ = TreeObject
+ case "blob":
+ typ = BlobObject
+ case "tag":
+ typ = TagObject
+ case "ofs-delta":
+ typ = OFSDeltaObject
+ case "ref-delta":
+ typ = REFDeltaObject
+ default:
+ err = ErrInvalidType
+ }
+ return
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/blob.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/blob.go
new file mode 100644
index 00000000..8fb7576f
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/blob.go
@@ -0,0 +1,144 @@
+package object
+
+import (
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// Blob is used to store arbitrary data - it is generally a file.
+type Blob struct {
+ // Hash of the blob.
+ Hash plumbing.Hash
+ // Size of the (uncompressed) blob.
+ Size int64
+
+ obj plumbing.EncodedObject
+}
+
+// GetBlob gets a blob from an object storer and decodes it.
+func GetBlob(s storer.EncodedObjectStorer, h plumbing.Hash) (*Blob, error) {
+ o, err := s.EncodedObject(plumbing.BlobObject, h)
+ if err != nil {
+ return nil, err
+ }
+
+ return DecodeBlob(o)
+}
+
+// DecodeObject decodes an encoded object into a *Blob.
+func DecodeBlob(o plumbing.EncodedObject) (*Blob, error) {
+ b := &Blob{}
+ if err := b.Decode(o); err != nil {
+ return nil, err
+ }
+
+ return b, nil
+}
+
+// ID returns the object ID of the blob. The returned value will always match
+// the current value of Blob.Hash.
+//
+// ID is present to fulfill the Object interface.
+func (b *Blob) ID() plumbing.Hash {
+ return b.Hash
+}
+
+// Type returns the type of object. It always returns plumbing.BlobObject.
+//
+// Type is present to fulfill the Object interface.
+func (b *Blob) Type() plumbing.ObjectType {
+ return plumbing.BlobObject
+}
+
+// Decode transforms a plumbing.EncodedObject into a Blob struct.
+func (b *Blob) Decode(o plumbing.EncodedObject) error {
+ if o.Type() != plumbing.BlobObject {
+ return ErrUnsupportedObject
+ }
+
+ b.Hash = o.Hash()
+ b.Size = o.Size()
+ b.obj = o
+
+ return nil
+}
+
+// Encode transforms a Blob into a plumbing.EncodedObject.
+func (b *Blob) Encode(o plumbing.EncodedObject) (err error) {
+ o.SetType(plumbing.BlobObject)
+
+ w, err := o.Writer()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(w, &err)
+
+ r, err := b.Reader()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(r, &err)
+
+ _, err = io.Copy(w, r)
+ return err
+}
+
+// Reader returns a reader allow the access to the content of the blob
+func (b *Blob) Reader() (io.ReadCloser, error) {
+ return b.obj.Reader()
+}
+
+// BlobIter provides an iterator for a set of blobs.
+type BlobIter struct {
+ storer.EncodedObjectIter
+ s storer.EncodedObjectStorer
+}
+
+// NewBlobIter takes a storer.EncodedObjectStorer and a
+// storer.EncodedObjectIter and returns a *BlobIter that iterates over all
+// blobs contained in the storer.EncodedObjectIter.
+//
+// Any non-blob object returned by the storer.EncodedObjectIter is skipped.
+func NewBlobIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *BlobIter {
+ return &BlobIter{iter, s}
+}
+
+// Next moves the iterator to the next blob and returns a pointer to it. If
+// there are no more blobs, it returns io.EOF.
+func (iter *BlobIter) Next() (*Blob, error) {
+ for {
+ obj, err := iter.EncodedObjectIter.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ if obj.Type() != plumbing.BlobObject {
+ continue
+ }
+
+ return DecodeBlob(obj)
+ }
+}
+
+// ForEach call the cb function for each blob contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *BlobIter) ForEach(cb func(*Blob) error) error {
+ return iter.EncodedObjectIter.ForEach(func(obj plumbing.EncodedObject) error {
+ if obj.Type() != plumbing.BlobObject {
+ return nil
+ }
+
+ b, err := DecodeBlob(obj)
+ if err != nil {
+ return err
+ }
+
+ return cb(b)
+ })
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/change.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/change.go
new file mode 100644
index 00000000..3c619df8
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/change.go
@@ -0,0 +1,159 @@
+package object
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "strings"
+
+ "github.com/go-git/go-git/v5/utils/merkletrie"
+)
+
+// Change values represent a detected change between two git trees. For
+// modifications, From is the original status of the node and To is its
+// final status. For insertions, From is the zero value and for
+// deletions To is the zero value.
+type Change struct {
+ From ChangeEntry
+ To ChangeEntry
+}
+
+var empty ChangeEntry
+
+// Action returns the kind of action represented by the change, an
+// insertion, a deletion or a modification.
+func (c *Change) Action() (merkletrie.Action, error) {
+ if c.From == empty && c.To == empty {
+ return merkletrie.Action(0),
+ fmt.Errorf("malformed change: empty from and to")
+ }
+
+ if c.From == empty {
+ return merkletrie.Insert, nil
+ }
+
+ if c.To == empty {
+ return merkletrie.Delete, nil
+ }
+
+ return merkletrie.Modify, nil
+}
+
+// Files returns the files before and after a change.
+// For insertions from will be nil. For deletions to will be nil.
+func (c *Change) Files() (from, to *File, err error) {
+ action, err := c.Action()
+ if err != nil {
+ return
+ }
+
+ if action == merkletrie.Insert || action == merkletrie.Modify {
+ to, err = c.To.Tree.TreeEntryFile(&c.To.TreeEntry)
+ if !c.To.TreeEntry.Mode.IsFile() {
+ return nil, nil, nil
+ }
+
+ if err != nil {
+ return
+ }
+ }
+
+ if action == merkletrie.Delete || action == merkletrie.Modify {
+ from, err = c.From.Tree.TreeEntryFile(&c.From.TreeEntry)
+ if !c.From.TreeEntry.Mode.IsFile() {
+ return nil, nil, nil
+ }
+
+ if err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+func (c *Change) String() string {
+ action, err := c.Action()
+ if err != nil {
+ return "malformed change"
+ }
+
+ return fmt.Sprintf("", action, c.name())
+}
+
+// Patch returns a Patch with all the file changes in chunks. This
+// representation can be used to create several diff outputs.
+func (c *Change) Patch() (*Patch, error) {
+ return c.PatchContext(context.Background())
+}
+
+// Patch returns a Patch with all the file changes in chunks. This
+// representation can be used to create several diff outputs.
+// If context expires, an non-nil error will be returned
+// Provided context must be non-nil
+func (c *Change) PatchContext(ctx context.Context) (*Patch, error) {
+ return getPatchContext(ctx, "", c)
+}
+
+func (c *Change) name() string {
+ if c.From != empty {
+ return c.From.Name
+ }
+
+ return c.To.Name
+}
+
+// ChangeEntry values represent a node that has suffered a change.
+type ChangeEntry struct {
+ // Full path of the node using "/" as separator.
+ Name string
+ // Parent tree of the node that has changed.
+ Tree *Tree
+ // The entry of the node.
+ TreeEntry TreeEntry
+}
+
+// Changes represents a collection of changes between two git trees.
+// Implements sort.Interface lexicographically over the path of the
+// changed files.
+type Changes []*Change
+
+func (c Changes) Len() int {
+ return len(c)
+}
+
+func (c Changes) Swap(i, j int) {
+ c[i], c[j] = c[j], c[i]
+}
+
+func (c Changes) Less(i, j int) bool {
+ return strings.Compare(c[i].name(), c[j].name()) < 0
+}
+
+func (c Changes) String() string {
+ var buffer bytes.Buffer
+ buffer.WriteString("[")
+ comma := ""
+ for _, v := range c {
+ buffer.WriteString(comma)
+ buffer.WriteString(v.String())
+ comma = ", "
+ }
+ buffer.WriteString("]")
+
+ return buffer.String()
+}
+
+// Patch returns a Patch with all the changes in chunks. This
+// representation can be used to create several diff outputs.
+func (c Changes) Patch() (*Patch, error) {
+ return c.PatchContext(context.Background())
+}
+
+// Patch returns a Patch with all the changes in chunks. This
+// representation can be used to create several diff outputs.
+// If context expires, an non-nil error will be returned
+// Provided context must be non-nil
+func (c Changes) PatchContext(ctx context.Context) (*Patch, error) {
+ return getPatchContext(ctx, "", c...)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/change_adaptor.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/change_adaptor.go
new file mode 100644
index 00000000..b96ee84d
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/change_adaptor.go
@@ -0,0 +1,61 @@
+package object
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/go-git/go-git/v5/utils/merkletrie"
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+// The following functions transform changes types form the merkletrie
+// package to changes types from this package.
+
+func newChange(c merkletrie.Change) (*Change, error) {
+ ret := &Change{}
+
+ var err error
+ if ret.From, err = newChangeEntry(c.From); err != nil {
+ return nil, fmt.Errorf("from field: %s", err)
+ }
+
+ if ret.To, err = newChangeEntry(c.To); err != nil {
+ return nil, fmt.Errorf("to field: %s", err)
+ }
+
+ return ret, nil
+}
+
+func newChangeEntry(p noder.Path) (ChangeEntry, error) {
+ if p == nil {
+ return empty, nil
+ }
+
+ asTreeNoder, ok := p.Last().(*treeNoder)
+ if !ok {
+ return ChangeEntry{}, errors.New("cannot transform non-TreeNoders")
+ }
+
+ return ChangeEntry{
+ Name: p.String(),
+ Tree: asTreeNoder.parent,
+ TreeEntry: TreeEntry{
+ Name: asTreeNoder.name,
+ Mode: asTreeNoder.mode,
+ Hash: asTreeNoder.hash,
+ },
+ }, nil
+}
+
+func newChanges(src merkletrie.Changes) (Changes, error) {
+ ret := make(Changes, len(src))
+ var err error
+ for i, e := range src {
+ ret[i], err = newChange(e)
+ if err != nil {
+ return nil, fmt.Errorf("change #%d: %s", i, err)
+ }
+ }
+
+ return ret, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit.go
new file mode 100644
index 00000000..3d096e18
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit.go
@@ -0,0 +1,507 @@
+package object
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "strings"
+
+ "github.com/ProtonMail/go-crypto/openpgp"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+const (
+ beginpgp string = "-----BEGIN PGP SIGNATURE-----"
+ endpgp string = "-----END PGP SIGNATURE-----"
+ headerpgp string = "gpgsig"
+ headerencoding string = "encoding"
+
+ // https://github.com/git/git/blob/bcb6cae2966cc407ca1afc77413b3ef11103c175/Documentation/gitformat-signature.txt#L153
+ // When a merge commit is created from a signed tag, the tag is embedded in
+ // the commit with the "mergetag" header.
+ headermergetag string = "mergetag"
+
+ defaultUtf8CommitMessageEncoding MessageEncoding = "UTF-8"
+)
+
+// Hash represents the hash of an object
+type Hash plumbing.Hash
+
+// MessageEncoding represents the encoding of a commit
+type MessageEncoding string
+
+// Commit points to a single tree, marking it as what the project looked like
+// at a certain point in time. It contains meta-information about that point
+// in time, such as a timestamp, the author of the changes since the last
+// commit, a pointer to the previous commit(s), etc.
+// http://shafiulazam.com/gitbook/1_the_git_object_model.html
+type Commit struct {
+ // Hash of the commit object.
+ Hash plumbing.Hash
+ // Author is the original author of the commit.
+ Author Signature
+ // Committer is the one performing the commit, might be different from
+ // Author.
+ Committer Signature
+ // MergeTag is the embedded tag object when a merge commit is created by
+ // merging a signed tag.
+ MergeTag string
+ // PGPSignature is the PGP signature of the commit.
+ PGPSignature string
+ // Message is the commit message, contains arbitrary text.
+ Message string
+ // TreeHash is the hash of the root tree of the commit.
+ TreeHash plumbing.Hash
+ // ParentHashes are the hashes of the parent commits of the commit.
+ ParentHashes []plumbing.Hash
+ // Encoding is the encoding of the commit.
+ Encoding MessageEncoding
+
+ s storer.EncodedObjectStorer
+}
+
+// GetCommit gets a commit from an object storer and decodes it.
+func GetCommit(s storer.EncodedObjectStorer, h plumbing.Hash) (*Commit, error) {
+ o, err := s.EncodedObject(plumbing.CommitObject, h)
+ if err != nil {
+ return nil, err
+ }
+
+ return DecodeCommit(s, o)
+}
+
+// DecodeCommit decodes an encoded object into a *Commit and associates it to
+// the given object storer.
+func DecodeCommit(s storer.EncodedObjectStorer, o plumbing.EncodedObject) (*Commit, error) {
+ c := &Commit{s: s}
+ if err := c.Decode(o); err != nil {
+ return nil, err
+ }
+
+ return c, nil
+}
+
+// Tree returns the Tree from the commit.
+func (c *Commit) Tree() (*Tree, error) {
+ return GetTree(c.s, c.TreeHash)
+}
+
+// PatchContext returns the Patch between the actual commit and the provided one.
+// Error will be return if context expires. Provided context must be non-nil.
+//
+// NOTE: Since version 5.1.0 the renames are correctly handled, the settings
+// used are the recommended options DefaultDiffTreeOptions.
+func (c *Commit) PatchContext(ctx context.Context, to *Commit) (*Patch, error) {
+ fromTree, err := c.Tree()
+ if err != nil {
+ return nil, err
+ }
+
+ var toTree *Tree
+ if to != nil {
+ toTree, err = to.Tree()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return fromTree.PatchContext(ctx, toTree)
+}
+
+// Patch returns the Patch between the actual commit and the provided one.
+//
+// NOTE: Since version 5.1.0 the renames are correctly handled, the settings
+// used are the recommended options DefaultDiffTreeOptions.
+func (c *Commit) Patch(to *Commit) (*Patch, error) {
+ return c.PatchContext(context.Background(), to)
+}
+
+// Parents return a CommitIter to the parent Commits.
+func (c *Commit) Parents() CommitIter {
+ return NewCommitIter(c.s,
+ storer.NewEncodedObjectLookupIter(c.s, plumbing.CommitObject, c.ParentHashes),
+ )
+}
+
+// NumParents returns the number of parents in a commit.
+func (c *Commit) NumParents() int {
+ return len(c.ParentHashes)
+}
+
+var ErrParentNotFound = errors.New("commit parent not found")
+
+// Parent returns the ith parent of a commit.
+func (c *Commit) Parent(i int) (*Commit, error) {
+ if len(c.ParentHashes) == 0 || i > len(c.ParentHashes)-1 {
+ return nil, ErrParentNotFound
+ }
+
+ return GetCommit(c.s, c.ParentHashes[i])
+}
+
+// File returns the file with the specified "path" in the commit and a
+// nil error if the file exists. If the file does not exist, it returns
+// a nil file and the ErrFileNotFound error.
+func (c *Commit) File(path string) (*File, error) {
+ tree, err := c.Tree()
+ if err != nil {
+ return nil, err
+ }
+
+ return tree.File(path)
+}
+
+// Files returns a FileIter allowing to iterate over the Tree
+func (c *Commit) Files() (*FileIter, error) {
+ tree, err := c.Tree()
+ if err != nil {
+ return nil, err
+ }
+
+ return tree.Files(), nil
+}
+
+// ID returns the object ID of the commit. The returned value will always match
+// the current value of Commit.Hash.
+//
+// ID is present to fulfill the Object interface.
+func (c *Commit) ID() plumbing.Hash {
+ return c.Hash
+}
+
+// Type returns the type of object. It always returns plumbing.CommitObject.
+//
+// Type is present to fulfill the Object interface.
+func (c *Commit) Type() plumbing.ObjectType {
+ return plumbing.CommitObject
+}
+
+// Decode transforms a plumbing.EncodedObject into a Commit struct.
+func (c *Commit) Decode(o plumbing.EncodedObject) (err error) {
+ if o.Type() != plumbing.CommitObject {
+ return ErrUnsupportedObject
+ }
+
+ c.Hash = o.Hash()
+ c.Encoding = defaultUtf8CommitMessageEncoding
+
+ reader, err := o.Reader()
+ if err != nil {
+ return err
+ }
+ defer ioutil.CheckClose(reader, &err)
+
+ r := sync.GetBufioReader(reader)
+ defer sync.PutBufioReader(r)
+
+ var message bool
+ var mergetag bool
+ var pgpsig bool
+ var msgbuf bytes.Buffer
+ for {
+ line, err := r.ReadBytes('\n')
+ if err != nil && err != io.EOF {
+ return err
+ }
+
+ if mergetag {
+ if len(line) > 0 && line[0] == ' ' {
+ line = bytes.TrimLeft(line, " ")
+ c.MergeTag += string(line)
+ continue
+ } else {
+ mergetag = false
+ }
+ }
+
+ if pgpsig {
+ if len(line) > 0 && line[0] == ' ' {
+ line = bytes.TrimLeft(line, " ")
+ c.PGPSignature += string(line)
+ continue
+ } else {
+ pgpsig = false
+ }
+ }
+
+ if !message {
+ line = bytes.TrimSpace(line)
+ if len(line) == 0 {
+ message = true
+ continue
+ }
+
+ split := bytes.SplitN(line, []byte{' '}, 2)
+
+ var data []byte
+ if len(split) == 2 {
+ data = split[1]
+ }
+
+ switch string(split[0]) {
+ case "tree":
+ c.TreeHash = plumbing.NewHash(string(data))
+ case "parent":
+ c.ParentHashes = append(c.ParentHashes, plumbing.NewHash(string(data)))
+ case "author":
+ c.Author.Decode(data)
+ case "committer":
+ c.Committer.Decode(data)
+ case headermergetag:
+ c.MergeTag += string(data) + "\n"
+ mergetag = true
+ case headerencoding:
+ c.Encoding = MessageEncoding(data)
+ case headerpgp:
+ c.PGPSignature += string(data) + "\n"
+ pgpsig = true
+ }
+ } else {
+ msgbuf.Write(line)
+ }
+
+ if err == io.EOF {
+ break
+ }
+ }
+ c.Message = msgbuf.String()
+ return nil
+}
+
+// Encode transforms a Commit into a plumbing.EncodedObject.
+func (c *Commit) Encode(o plumbing.EncodedObject) error {
+ return c.encode(o, true)
+}
+
+// EncodeWithoutSignature export a Commit into a plumbing.EncodedObject without the signature (correspond to the payload of the PGP signature).
+func (c *Commit) EncodeWithoutSignature(o plumbing.EncodedObject) error {
+ return c.encode(o, false)
+}
+
+func (c *Commit) encode(o plumbing.EncodedObject, includeSig bool) (err error) {
+ o.SetType(plumbing.CommitObject)
+ w, err := o.Writer()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(w, &err)
+
+ if _, err = fmt.Fprintf(w, "tree %s\n", c.TreeHash.String()); err != nil {
+ return err
+ }
+
+ for _, parent := range c.ParentHashes {
+ if _, err = fmt.Fprintf(w, "parent %s\n", parent.String()); err != nil {
+ return err
+ }
+ }
+
+ if _, err = fmt.Fprint(w, "author "); err != nil {
+ return err
+ }
+
+ if err = c.Author.Encode(w); err != nil {
+ return err
+ }
+
+ if _, err = fmt.Fprint(w, "\ncommitter "); err != nil {
+ return err
+ }
+
+ if err = c.Committer.Encode(w); err != nil {
+ return err
+ }
+
+ if c.MergeTag != "" {
+ if _, err = fmt.Fprint(w, "\n"+headermergetag+" "); err != nil {
+ return err
+ }
+
+ // Split tag information lines and re-write with a left padding and
+ // newline. Use join for this so it's clear that a newline should not be
+ // added after this section. The newline will be added either as part of
+ // the PGP signature or the commit message.
+ mergetag := strings.TrimSuffix(c.MergeTag, "\n")
+ lines := strings.Split(mergetag, "\n")
+ if _, err = fmt.Fprint(w, strings.Join(lines, "\n ")); err != nil {
+ return err
+ }
+ }
+
+ if string(c.Encoding) != "" && c.Encoding != defaultUtf8CommitMessageEncoding {
+ if _, err = fmt.Fprintf(w, "\n%s %s", headerencoding, c.Encoding); err != nil {
+ return err
+ }
+ }
+
+ if c.PGPSignature != "" && includeSig {
+ if _, err = fmt.Fprint(w, "\n"+headerpgp+" "); err != nil {
+ return err
+ }
+
+ // Split all the signature lines and re-write with a left padding and
+ // newline. Use join for this so it's clear that a newline should not be
+ // added after this section, as it will be added when the message is
+ // printed.
+ signature := strings.TrimSuffix(c.PGPSignature, "\n")
+ lines := strings.Split(signature, "\n")
+ if _, err = fmt.Fprint(w, strings.Join(lines, "\n ")); err != nil {
+ return err
+ }
+ }
+
+ if _, err = fmt.Fprintf(w, "\n\n%s", c.Message); err != nil {
+ return err
+ }
+
+ return err
+}
+
+// Stats returns the stats of a commit.
+func (c *Commit) Stats() (FileStats, error) {
+ return c.StatsContext(context.Background())
+}
+
+// StatsContext returns the stats of a commit. Error will be return if context
+// expires. Provided context must be non-nil.
+func (c *Commit) StatsContext(ctx context.Context) (FileStats, error) {
+ fromTree, err := c.Tree()
+ if err != nil {
+ return nil, err
+ }
+
+ toTree := &Tree{}
+ if c.NumParents() != 0 {
+ firstParent, err := c.Parents().Next()
+ if err != nil {
+ return nil, err
+ }
+
+ toTree, err = firstParent.Tree()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ patch, err := toTree.PatchContext(ctx, fromTree)
+ if err != nil {
+ return nil, err
+ }
+
+ return getFileStatsFromFilePatches(patch.FilePatches()), nil
+}
+
+func (c *Commit) String() string {
+ return fmt.Sprintf(
+ "%s %s\nAuthor: %s\nDate: %s\n\n%s\n",
+ plumbing.CommitObject, c.Hash, c.Author.String(),
+ c.Author.When.Format(DateFormat), indent(c.Message),
+ )
+}
+
+// Verify performs PGP verification of the commit with a provided armored
+// keyring and returns openpgp.Entity associated with verifying key on success.
+func (c *Commit) Verify(armoredKeyRing string) (*openpgp.Entity, error) {
+ keyRingReader := strings.NewReader(armoredKeyRing)
+ keyring, err := openpgp.ReadArmoredKeyRing(keyRingReader)
+ if err != nil {
+ return nil, err
+ }
+
+ // Extract signature.
+ signature := strings.NewReader(c.PGPSignature)
+
+ encoded := &plumbing.MemoryObject{}
+ // Encode commit components, excluding signature and get a reader object.
+ if err := c.EncodeWithoutSignature(encoded); err != nil {
+ return nil, err
+ }
+ er, err := encoded.Reader()
+ if err != nil {
+ return nil, err
+ }
+
+ return openpgp.CheckArmoredDetachedSignature(keyring, er, signature, nil)
+}
+
+// Less defines a compare function to determine which commit is 'earlier' by:
+// - First use Committer.When
+// - If Committer.When are equal then use Author.When
+// - If Author.When also equal then compare the string value of the hash
+func (c *Commit) Less(rhs *Commit) bool {
+ return c.Committer.When.Before(rhs.Committer.When) ||
+ (c.Committer.When.Equal(rhs.Committer.When) &&
+ (c.Author.When.Before(rhs.Author.When) ||
+ (c.Author.When.Equal(rhs.Author.When) && bytes.Compare(c.Hash[:], rhs.Hash[:]) < 0)))
+}
+
+func indent(t string) string {
+ var output []string
+ for _, line := range strings.Split(t, "\n") {
+ if len(line) != 0 {
+ line = " " + line
+ }
+
+ output = append(output, line)
+ }
+
+ return strings.Join(output, "\n")
+}
+
+// CommitIter is a generic closable interface for iterating over commits.
+type CommitIter interface {
+ Next() (*Commit, error)
+ ForEach(func(*Commit) error) error
+ Close()
+}
+
+// storerCommitIter provides an iterator from commits in an EncodedObjectStorer.
+type storerCommitIter struct {
+ storer.EncodedObjectIter
+ s storer.EncodedObjectStorer
+}
+
+// NewCommitIter takes a storer.EncodedObjectStorer and a
+// storer.EncodedObjectIter and returns a CommitIter that iterates over all
+// commits contained in the storer.EncodedObjectIter.
+//
+// Any non-commit object returned by the storer.EncodedObjectIter is skipped.
+func NewCommitIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) CommitIter {
+ return &storerCommitIter{iter, s}
+}
+
+// Next moves the iterator to the next commit and returns a pointer to it. If
+// there are no more commits, it returns io.EOF.
+func (iter *storerCommitIter) Next() (*Commit, error) {
+ obj, err := iter.EncodedObjectIter.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return DecodeCommit(iter.s, obj)
+}
+
+// ForEach call the cb function for each commit contained on this iter until
+// an error appends or the end of the iter is reached. If ErrStop is sent
+// the iteration is stopped but no error is returned. The iterator is closed.
+func (iter *storerCommitIter) ForEach(cb func(*Commit) error) error {
+ return iter.EncodedObjectIter.ForEach(func(obj plumbing.EncodedObject) error {
+ c, err := DecodeCommit(iter.s, obj)
+ if err != nil {
+ return err
+ }
+
+ return cb(c)
+ })
+}
+
+func (iter *storerCommitIter) Close() {
+ iter.EncodedObjectIter.Close()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker.go
new file mode 100644
index 00000000..a96b6a4c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker.go
@@ -0,0 +1,327 @@
+package object
+
+import (
+ "container/list"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/storage"
+)
+
+type commitPreIterator struct {
+ seenExternal map[plumbing.Hash]bool
+ seen map[plumbing.Hash]bool
+ stack []CommitIter
+ start *Commit
+}
+
+// NewCommitPreorderIter returns a CommitIter that walks the commit history,
+// starting at the given commit and visiting its parents in pre-order.
+// The given callback will be called for each visited commit. Each commit will
+// be visited only once. If the callback returns an error, walking will stop
+// and will return the error. Other errors might be returned if the history
+// cannot be traversed (e.g. missing objects). Ignore allows to skip some
+// commits from being iterated.
+func NewCommitPreorderIter(
+ c *Commit,
+ seenExternal map[plumbing.Hash]bool,
+ ignore []plumbing.Hash,
+) CommitIter {
+ seen := make(map[plumbing.Hash]bool)
+ for _, h := range ignore {
+ seen[h] = true
+ }
+
+ return &commitPreIterator{
+ seenExternal: seenExternal,
+ seen: seen,
+ stack: make([]CommitIter, 0),
+ start: c,
+ }
+}
+
+func (w *commitPreIterator) Next() (*Commit, error) {
+ var c *Commit
+ for {
+ if w.start != nil {
+ c = w.start
+ w.start = nil
+ } else {
+ current := len(w.stack) - 1
+ if current < 0 {
+ return nil, io.EOF
+ }
+
+ var err error
+ c, err = w.stack[current].Next()
+ if err == io.EOF {
+ w.stack = w.stack[:current]
+ continue
+ }
+
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if w.seen[c.Hash] || w.seenExternal[c.Hash] {
+ continue
+ }
+
+ w.seen[c.Hash] = true
+
+ if c.NumParents() > 0 {
+ w.stack = append(w.stack, filteredParentIter(c, w.seen))
+ }
+
+ return c, nil
+ }
+}
+
+func filteredParentIter(c *Commit, seen map[plumbing.Hash]bool) CommitIter {
+ var hashes []plumbing.Hash
+ for _, h := range c.ParentHashes {
+ if !seen[h] {
+ hashes = append(hashes, h)
+ }
+ }
+
+ return NewCommitIter(c.s,
+ storer.NewEncodedObjectLookupIter(c.s, plumbing.CommitObject, hashes),
+ )
+}
+
+func (w *commitPreIterator) ForEach(cb func(*Commit) error) error {
+ for {
+ c, err := w.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ err = cb(c)
+ if err == storer.ErrStop {
+ break
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (w *commitPreIterator) Close() {}
+
+type commitPostIterator struct {
+ stack []*Commit
+ seen map[plumbing.Hash]bool
+}
+
+// NewCommitPostorderIter returns a CommitIter that walks the commit
+// history like WalkCommitHistory but in post-order. This means that after
+// walking a merge commit, the merged commit will be walked before the base
+// it was merged on. This can be useful if you wish to see the history in
+// chronological order. Ignore allows to skip some commits from being iterated.
+func NewCommitPostorderIter(c *Commit, ignore []plumbing.Hash) CommitIter {
+ seen := make(map[plumbing.Hash]bool)
+ for _, h := range ignore {
+ seen[h] = true
+ }
+
+ return &commitPostIterator{
+ stack: []*Commit{c},
+ seen: seen,
+ }
+}
+
+func (w *commitPostIterator) Next() (*Commit, error) {
+ for {
+ if len(w.stack) == 0 {
+ return nil, io.EOF
+ }
+
+ c := w.stack[len(w.stack)-1]
+ w.stack = w.stack[:len(w.stack)-1]
+
+ if w.seen[c.Hash] {
+ continue
+ }
+
+ w.seen[c.Hash] = true
+
+ return c, c.Parents().ForEach(func(p *Commit) error {
+ w.stack = append(w.stack, p)
+ return nil
+ })
+ }
+}
+
+func (w *commitPostIterator) ForEach(cb func(*Commit) error) error {
+ for {
+ c, err := w.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ err = cb(c)
+ if err == storer.ErrStop {
+ break
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (w *commitPostIterator) Close() {}
+
+// commitAllIterator stands for commit iterator for all refs.
+type commitAllIterator struct {
+ // currCommit points to the current commit.
+ currCommit *list.Element
+}
+
+// NewCommitAllIter returns a new commit iterator for all refs.
+// repoStorer is a repo Storer used to get commits and references.
+// commitIterFunc is a commit iterator function, used to iterate through ref commits in chosen order
+func NewCommitAllIter(repoStorer storage.Storer, commitIterFunc func(*Commit) CommitIter) (CommitIter, error) {
+ commitsPath := list.New()
+ commitsLookup := make(map[plumbing.Hash]*list.Element)
+ head, err := storer.ResolveReference(repoStorer, plumbing.HEAD)
+ if err == nil {
+ err = addReference(repoStorer, commitIterFunc, head, commitsPath, commitsLookup)
+ }
+
+ if err != nil && err != plumbing.ErrReferenceNotFound {
+ return nil, err
+ }
+
+ // add all references along with the HEAD
+ refIter, err := repoStorer.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+ defer refIter.Close()
+
+ for {
+ ref, err := refIter.Next()
+ if err == io.EOF {
+ break
+ }
+
+ if err == plumbing.ErrReferenceNotFound {
+ continue
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if err = addReference(repoStorer, commitIterFunc, ref, commitsPath, commitsLookup); err != nil {
+ return nil, err
+ }
+ }
+
+ return &commitAllIterator{commitsPath.Front()}, nil
+}
+
+func addReference(
+ repoStorer storage.Storer,
+ commitIterFunc func(*Commit) CommitIter,
+ ref *plumbing.Reference,
+ commitsPath *list.List,
+ commitsLookup map[plumbing.Hash]*list.Element) error {
+
+ _, exists := commitsLookup[ref.Hash()]
+ if exists {
+ // we already have it - skip the reference.
+ return nil
+ }
+
+ refCommit, _ := GetCommit(repoStorer, ref.Hash())
+ if refCommit == nil {
+ // if it's not a commit - skip it.
+ return nil
+ }
+
+ var (
+ refCommits []*Commit
+ parent *list.Element
+ )
+ // collect all ref commits to add
+ commitIter := commitIterFunc(refCommit)
+ for c, e := commitIter.Next(); e == nil; {
+ parent, exists = commitsLookup[c.Hash]
+ if exists {
+ break
+ }
+ refCommits = append(refCommits, c)
+ c, e = commitIter.Next()
+ }
+ commitIter.Close()
+
+ if parent == nil {
+ // common parent - not found
+ // add all commits to the path from this ref (maybe it's a HEAD and we don't have anything, yet)
+ for _, c := range refCommits {
+ parent = commitsPath.PushBack(c)
+ commitsLookup[c.Hash] = parent
+ }
+ } else {
+ // add ref's commits to the path in reverse order (from the latest)
+ for i := len(refCommits) - 1; i >= 0; i-- {
+ c := refCommits[i]
+ // insert before found common parent
+ parent = commitsPath.InsertBefore(c, parent)
+ commitsLookup[c.Hash] = parent
+ }
+ }
+
+ return nil
+}
+
+func (it *commitAllIterator) Next() (*Commit, error) {
+ if it.currCommit == nil {
+ return nil, io.EOF
+ }
+
+ c := it.currCommit.Value.(*Commit)
+ it.currCommit = it.currCommit.Next()
+
+ return c, nil
+}
+
+func (it *commitAllIterator) ForEach(cb func(*Commit) error) error {
+ for {
+ c, err := it.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ err = cb(c)
+ if err == storer.ErrStop {
+ break
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (it *commitAllIterator) Close() {
+ it.currCommit = nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs.go
new file mode 100644
index 00000000..8047fa9b
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs.go
@@ -0,0 +1,100 @@
+package object
+
+import (
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+type bfsCommitIterator struct {
+ seenExternal map[plumbing.Hash]bool
+ seen map[plumbing.Hash]bool
+ queue []*Commit
+}
+
+// NewCommitIterBSF returns a CommitIter that walks the commit history,
+// starting at the given commit and visiting its parents in pre-order.
+// The given callback will be called for each visited commit. Each commit will
+// be visited only once. If the callback returns an error, walking will stop
+// and will return the error. Other errors might be returned if the history
+// cannot be traversed (e.g. missing objects). Ignore allows to skip some
+// commits from being iterated.
+func NewCommitIterBSF(
+ c *Commit,
+ seenExternal map[plumbing.Hash]bool,
+ ignore []plumbing.Hash,
+) CommitIter {
+ seen := make(map[plumbing.Hash]bool)
+ for _, h := range ignore {
+ seen[h] = true
+ }
+
+ return &bfsCommitIterator{
+ seenExternal: seenExternal,
+ seen: seen,
+ queue: []*Commit{c},
+ }
+}
+
+func (w *bfsCommitIterator) appendHash(store storer.EncodedObjectStorer, h plumbing.Hash) error {
+ if w.seen[h] || w.seenExternal[h] {
+ return nil
+ }
+ c, err := GetCommit(store, h)
+ if err != nil {
+ return err
+ }
+ w.queue = append(w.queue, c)
+ return nil
+}
+
+func (w *bfsCommitIterator) Next() (*Commit, error) {
+ var c *Commit
+ for {
+ if len(w.queue) == 0 {
+ return nil, io.EOF
+ }
+ c = w.queue[0]
+ w.queue = w.queue[1:]
+
+ if w.seen[c.Hash] || w.seenExternal[c.Hash] {
+ continue
+ }
+
+ w.seen[c.Hash] = true
+
+ for _, h := range c.ParentHashes {
+ err := w.appendHash(c.s, h)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return c, nil
+ }
+}
+
+func (w *bfsCommitIterator) ForEach(cb func(*Commit) error) error {
+ for {
+ c, err := w.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ err = cb(c)
+ if err == storer.ErrStop {
+ break
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (w *bfsCommitIterator) Close() {}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs_filtered.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs_filtered.go
new file mode 100644
index 00000000..9d518133
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_bfs_filtered.go
@@ -0,0 +1,175 @@
+package object
+
+import (
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+// NewFilterCommitIter returns a CommitIter that walks the commit history,
+// starting at the passed commit and visiting its parents in Breadth-first order.
+// The commits returned by the CommitIter will validate the passed CommitFilter.
+// The history won't be transversed beyond a commit if isLimit is true for it.
+// Each commit will be visited only once.
+// If the commit history can not be traversed, or the Close() method is called,
+// the CommitIter won't return more commits.
+// If no isValid is passed, all ancestors of from commit will be valid.
+// If no isLimit is limit, all ancestors of all commits will be visited.
+func NewFilterCommitIter(
+ from *Commit,
+ isValid *CommitFilter,
+ isLimit *CommitFilter,
+) CommitIter {
+ var validFilter CommitFilter
+ if isValid == nil {
+ validFilter = func(_ *Commit) bool {
+ return true
+ }
+ } else {
+ validFilter = *isValid
+ }
+
+ var limitFilter CommitFilter
+ if isLimit == nil {
+ limitFilter = func(_ *Commit) bool {
+ return false
+ }
+ } else {
+ limitFilter = *isLimit
+ }
+
+ return &filterCommitIter{
+ isValid: validFilter,
+ isLimit: limitFilter,
+ visited: map[plumbing.Hash]struct{}{},
+ queue: []*Commit{from},
+ }
+}
+
+// CommitFilter returns a boolean for the passed Commit
+type CommitFilter func(*Commit) bool
+
+// filterCommitIter implements CommitIter
+type filterCommitIter struct {
+ isValid CommitFilter
+ isLimit CommitFilter
+ visited map[plumbing.Hash]struct{}
+ queue []*Commit
+ lastErr error
+}
+
+// Next returns the next commit of the CommitIter.
+// It will return io.EOF if there are no more commits to visit,
+// or an error if the history could not be traversed.
+func (w *filterCommitIter) Next() (*Commit, error) {
+ var commit *Commit
+ var err error
+ for {
+ commit, err = w.popNewFromQueue()
+ if err != nil {
+ return nil, w.close(err)
+ }
+
+ w.visited[commit.Hash] = struct{}{}
+
+ if !w.isLimit(commit) {
+ err = w.addToQueue(commit.s, commit.ParentHashes...)
+ if err != nil {
+ return nil, w.close(err)
+ }
+ }
+
+ if w.isValid(commit) {
+ return commit, nil
+ }
+ }
+}
+
+// ForEach runs the passed callback over each Commit returned by the CommitIter
+// until the callback returns an error or there is no more commits to traverse.
+func (w *filterCommitIter) ForEach(cb func(*Commit) error) error {
+ for {
+ commit, err := w.Next()
+ if err == io.EOF {
+ break
+ }
+
+ if err != nil {
+ return err
+ }
+
+ if err := cb(commit); err == storer.ErrStop {
+ break
+ } else if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Error returns the error that caused that the CommitIter is no longer returning commits
+func (w *filterCommitIter) Error() error {
+ return w.lastErr
+}
+
+// Close closes the CommitIter
+func (w *filterCommitIter) Close() {
+ w.visited = map[plumbing.Hash]struct{}{}
+ w.queue = []*Commit{}
+ w.isLimit = nil
+ w.isValid = nil
+}
+
+// close closes the CommitIter with an error
+func (w *filterCommitIter) close(err error) error {
+ w.Close()
+ w.lastErr = err
+ return err
+}
+
+// popNewFromQueue returns the first new commit from the internal fifo queue,
+// or an io.EOF error if the queue is empty
+func (w *filterCommitIter) popNewFromQueue() (*Commit, error) {
+ var first *Commit
+ for {
+ if len(w.queue) == 0 {
+ if w.lastErr != nil {
+ return nil, w.lastErr
+ }
+
+ return nil, io.EOF
+ }
+
+ first = w.queue[0]
+ w.queue = w.queue[1:]
+ if _, ok := w.visited[first.Hash]; ok {
+ continue
+ }
+
+ return first, nil
+ }
+}
+
+// addToQueue adds the passed commits to the internal fifo queue if they weren't seen
+// or returns an error if the passed hashes could not be used to get valid commits
+func (w *filterCommitIter) addToQueue(
+ store storer.EncodedObjectStorer,
+ hashes ...plumbing.Hash,
+) error {
+ for _, hash := range hashes {
+ if _, ok := w.visited[hash]; ok {
+ continue
+ }
+
+ commit, err := GetCommit(store, hash)
+ if err != nil {
+ return err
+ }
+
+ w.queue = append(w.queue, commit)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_ctime.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_ctime.go
new file mode 100644
index 00000000..fbddf1d2
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_ctime.go
@@ -0,0 +1,103 @@
+package object
+
+import (
+ "io"
+
+ "github.com/emirpasic/gods/trees/binaryheap"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+type commitIteratorByCTime struct {
+ seenExternal map[plumbing.Hash]bool
+ seen map[plumbing.Hash]bool
+ heap *binaryheap.Heap
+}
+
+// NewCommitIterCTime returns a CommitIter that walks the commit history,
+// starting at the given commit and visiting its parents while preserving Committer Time order.
+// this appears to be the closest order to `git log`
+// The given callback will be called for each visited commit. Each commit will
+// be visited only once. If the callback returns an error, walking will stop
+// and will return the error. Other errors might be returned if the history
+// cannot be traversed (e.g. missing objects). Ignore allows to skip some
+// commits from being iterated.
+func NewCommitIterCTime(
+ c *Commit,
+ seenExternal map[plumbing.Hash]bool,
+ ignore []plumbing.Hash,
+) CommitIter {
+ seen := make(map[plumbing.Hash]bool)
+ for _, h := range ignore {
+ seen[h] = true
+ }
+
+ heap := binaryheap.NewWith(func(a, b interface{}) int {
+ if a.(*Commit).Committer.When.Before(b.(*Commit).Committer.When) {
+ return 1
+ }
+ return -1
+ })
+ heap.Push(c)
+
+ return &commitIteratorByCTime{
+ seenExternal: seenExternal,
+ seen: seen,
+ heap: heap,
+ }
+}
+
+func (w *commitIteratorByCTime) Next() (*Commit, error) {
+ var c *Commit
+ for {
+ cIn, ok := w.heap.Pop()
+ if !ok {
+ return nil, io.EOF
+ }
+ c = cIn.(*Commit)
+
+ if w.seen[c.Hash] || w.seenExternal[c.Hash] {
+ continue
+ }
+
+ w.seen[c.Hash] = true
+
+ for _, h := range c.ParentHashes {
+ if w.seen[h] || w.seenExternal[h] {
+ continue
+ }
+ pc, err := GetCommit(c.s, h)
+ if err != nil {
+ return nil, err
+ }
+ w.heap.Push(pc)
+ }
+
+ return c, nil
+ }
+}
+
+func (w *commitIteratorByCTime) ForEach(cb func(*Commit) error) error {
+ for {
+ c, err := w.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ err = cb(c)
+ if err == storer.ErrStop {
+ break
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (w *commitIteratorByCTime) Close() {}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_limit.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_limit.go
new file mode 100644
index 00000000..ac56a71c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_limit.go
@@ -0,0 +1,65 @@
+package object
+
+import (
+ "io"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+type commitLimitIter struct {
+ sourceIter CommitIter
+ limitOptions LogLimitOptions
+}
+
+type LogLimitOptions struct {
+ Since *time.Time
+ Until *time.Time
+}
+
+func NewCommitLimitIterFromIter(commitIter CommitIter, limitOptions LogLimitOptions) CommitIter {
+ iterator := new(commitLimitIter)
+ iterator.sourceIter = commitIter
+ iterator.limitOptions = limitOptions
+ return iterator
+}
+
+func (c *commitLimitIter) Next() (*Commit, error) {
+ for {
+ commit, err := c.sourceIter.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ if c.limitOptions.Since != nil && commit.Committer.When.Before(*c.limitOptions.Since) {
+ continue
+ }
+ if c.limitOptions.Until != nil && commit.Committer.When.After(*c.limitOptions.Until) {
+ continue
+ }
+ return commit, nil
+ }
+}
+
+func (c *commitLimitIter) ForEach(cb func(*Commit) error) error {
+ for {
+ commit, nextErr := c.Next()
+ if nextErr == io.EOF {
+ break
+ }
+ if nextErr != nil {
+ return nextErr
+ }
+ err := cb(commit)
+ if err == storer.ErrStop {
+ return nil
+ } else if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (c *commitLimitIter) Close() {
+ c.sourceIter.Close()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_path.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_path.go
new file mode 100644
index 00000000..c1ec8ba7
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/commit_walker_path.go
@@ -0,0 +1,167 @@
+package object
+
+import (
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+type commitPathIter struct {
+ pathFilter func(string) bool
+ sourceIter CommitIter
+ currentCommit *Commit
+ checkParent bool
+}
+
+// NewCommitPathIterFromIter returns a commit iterator which performs diffTree between
+// successive trees returned from the commit iterator from the argument. The purpose of this is
+// to find the commits that explain how the files that match the path came to be.
+// If checkParent is true then the function double checks if potential parent (next commit in a path)
+// is one of the parents in the tree (it's used by `git log --all`).
+// pathFilter is a function that takes path of file as argument and returns true if we want it
+func NewCommitPathIterFromIter(pathFilter func(string) bool, commitIter CommitIter, checkParent bool) CommitIter {
+ iterator := new(commitPathIter)
+ iterator.sourceIter = commitIter
+ iterator.pathFilter = pathFilter
+ iterator.checkParent = checkParent
+ return iterator
+}
+
+// NewCommitFileIterFromIter is kept for compatibility, can be replaced with NewCommitPathIterFromIter
+func NewCommitFileIterFromIter(fileName string, commitIter CommitIter, checkParent bool) CommitIter {
+ return NewCommitPathIterFromIter(
+ func(path string) bool {
+ return path == fileName
+ },
+ commitIter,
+ checkParent,
+ )
+}
+
+func (c *commitPathIter) Next() (*Commit, error) {
+ if c.currentCommit == nil {
+ var err error
+ c.currentCommit, err = c.sourceIter.Next()
+ if err != nil {
+ return nil, err
+ }
+ }
+ commit, commitErr := c.getNextFileCommit()
+
+ // Setting current-commit to nil to prevent unwanted states when errors are raised
+ if commitErr != nil {
+ c.currentCommit = nil
+ }
+ return commit, commitErr
+}
+
+func (c *commitPathIter) getNextFileCommit() (*Commit, error) {
+ var parentTree, currentTree *Tree
+
+ for {
+ // Parent-commit can be nil if the current-commit is the initial commit
+ parentCommit, parentCommitErr := c.sourceIter.Next()
+ if parentCommitErr != nil {
+ // If the parent-commit is beyond the initial commit, keep it nil
+ if parentCommitErr != io.EOF {
+ return nil, parentCommitErr
+ }
+ parentCommit = nil
+ }
+
+ if parentTree == nil {
+ var currTreeErr error
+ currentTree, currTreeErr = c.currentCommit.Tree()
+ if currTreeErr != nil {
+ return nil, currTreeErr
+ }
+ } else {
+ currentTree = parentTree
+ parentTree = nil
+ }
+
+ if parentCommit != nil {
+ var parentTreeErr error
+ parentTree, parentTreeErr = parentCommit.Tree()
+ if parentTreeErr != nil {
+ return nil, parentTreeErr
+ }
+ }
+
+ // Find diff between current and parent trees
+ changes, diffErr := DiffTree(currentTree, parentTree)
+ if diffErr != nil {
+ return nil, diffErr
+ }
+
+ found := c.hasFileChange(changes, parentCommit)
+
+ // Storing the current-commit in-case a change is found, and
+ // Updating the current-commit for the next-iteration
+ prevCommit := c.currentCommit
+ c.currentCommit = parentCommit
+
+ if found {
+ return prevCommit, nil
+ }
+
+ // If not matches found and if parent-commit is beyond the initial commit, then return with EOF
+ if parentCommit == nil {
+ return nil, io.EOF
+ }
+ }
+}
+
+func (c *commitPathIter) hasFileChange(changes Changes, parent *Commit) bool {
+ for _, change := range changes {
+ if !c.pathFilter(change.name()) {
+ continue
+ }
+
+ // filename matches, now check if source iterator contains all commits (from all refs)
+ if c.checkParent {
+ // Check if parent is beyond the initial commit
+ if parent == nil || isParentHash(parent.Hash, c.currentCommit) {
+ return true
+ }
+ continue
+ }
+
+ return true
+ }
+
+ return false
+}
+
+func isParentHash(hash plumbing.Hash, commit *Commit) bool {
+ for _, h := range commit.ParentHashes {
+ if h == hash {
+ return true
+ }
+ }
+ return false
+}
+
+func (c *commitPathIter) ForEach(cb func(*Commit) error) error {
+ for {
+ commit, nextErr := c.Next()
+ if nextErr == io.EOF {
+ break
+ }
+ if nextErr != nil {
+ return nextErr
+ }
+ err := cb(commit)
+ if err == storer.ErrStop {
+ return nil
+ } else if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (c *commitPathIter) Close() {
+ c.sourceIter.Close()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/difftree.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/difftree.go
new file mode 100644
index 00000000..7c222270
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/difftree.go
@@ -0,0 +1,98 @@
+package object
+
+import (
+ "bytes"
+ "context"
+
+ "github.com/go-git/go-git/v5/utils/merkletrie"
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+// DiffTree compares the content and mode of the blobs found via two
+// tree objects.
+// DiffTree does not perform rename detection, use DiffTreeWithOptions
+// instead to detect renames.
+func DiffTree(a, b *Tree) (Changes, error) {
+ return DiffTreeContext(context.Background(), a, b)
+}
+
+// DiffTreeContext compares the content and mode of the blobs found via two
+// tree objects. Provided context must be non-nil.
+// An error will be returned if context expires.
+func DiffTreeContext(ctx context.Context, a, b *Tree) (Changes, error) {
+ return DiffTreeWithOptions(ctx, a, b, nil)
+}
+
+// DiffTreeOptions are the configurable options when performing a diff tree.
+type DiffTreeOptions struct {
+ // DetectRenames is whether the diff tree will use rename detection.
+ DetectRenames bool
+ // RenameScore is the threshold to of similarity between files to consider
+ // that a pair of delete and insert are a rename. The number must be
+ // exactly between 0 and 100.
+ RenameScore uint
+ // RenameLimit is the maximum amount of files that can be compared when
+ // detecting renames. The number of comparisons that have to be performed
+ // is equal to the number of deleted files * the number of added files.
+ // That means, that if 100 files were deleted and 50 files were added, 5000
+ // file comparisons may be needed. So, if the rename limit is 50, the number
+ // of both deleted and added needs to be equal or less than 50.
+ // A value of 0 means no limit.
+ RenameLimit uint
+ // OnlyExactRenames performs only detection of exact renames and will not perform
+ // any detection of renames based on file similarity.
+ OnlyExactRenames bool
+}
+
+// DefaultDiffTreeOptions are the default and recommended options for the
+// diff tree.
+var DefaultDiffTreeOptions = &DiffTreeOptions{
+ DetectRenames: true,
+ RenameScore: 60,
+ RenameLimit: 0,
+ OnlyExactRenames: false,
+}
+
+// DiffTreeWithOptions compares the content and mode of the blobs found
+// via two tree objects with the given options. The provided context
+// must be non-nil.
+// If no options are passed, no rename detection will be performed. The
+// recommended options are DefaultDiffTreeOptions.
+// An error will be returned if the context expires.
+// This function will be deprecated and removed in v6 so the default
+// behaviour of DiffTree is to detect renames.
+func DiffTreeWithOptions(
+ ctx context.Context,
+ a, b *Tree,
+ opts *DiffTreeOptions,
+) (Changes, error) {
+ from := NewTreeRootNode(a)
+ to := NewTreeRootNode(b)
+
+ hashEqual := func(a, b noder.Hasher) bool {
+ return bytes.Equal(a.Hash(), b.Hash())
+ }
+
+ merkletrieChanges, err := merkletrie.DiffTreeContext(ctx, from, to, hashEqual)
+ if err != nil {
+ if err == merkletrie.ErrCanceled {
+ return nil, ErrCanceled
+ }
+ return nil, err
+ }
+
+ changes, err := newChanges(merkletrieChanges)
+ if err != nil {
+ return nil, err
+ }
+
+ if opts == nil {
+ opts = new(DiffTreeOptions)
+ }
+
+ if opts.DetectRenames {
+ return DetectRenames(changes, opts)
+ }
+
+ return changes, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/file.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/file.go
new file mode 100644
index 00000000..6cc5367d
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/file.go
@@ -0,0 +1,137 @@
+package object
+
+import (
+ "bytes"
+ "io"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/binary"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// File represents git file objects.
+type File struct {
+ // Name is the path of the file. It might be relative to a tree,
+ // depending of the function that generates it.
+ Name string
+ // Mode is the file mode.
+ Mode filemode.FileMode
+ // Blob with the contents of the file.
+ Blob
+}
+
+// NewFile returns a File based on the given blob object
+func NewFile(name string, m filemode.FileMode, b *Blob) *File {
+ return &File{Name: name, Mode: m, Blob: *b}
+}
+
+// Contents returns the contents of a file as a string.
+func (f *File) Contents() (content string, err error) {
+ reader, err := f.Reader()
+ if err != nil {
+ return "", err
+ }
+ defer ioutil.CheckClose(reader, &err)
+
+ buf := new(bytes.Buffer)
+ if _, err := buf.ReadFrom(reader); err != nil {
+ return "", err
+ }
+
+ return buf.String(), nil
+}
+
+// IsBinary returns if the file is binary or not
+func (f *File) IsBinary() (bin bool, err error) {
+ reader, err := f.Reader()
+ if err != nil {
+ return false, err
+ }
+ defer ioutil.CheckClose(reader, &err)
+
+ return binary.IsBinary(reader)
+}
+
+// Lines returns a slice of lines from the contents of a file, stripping
+// all end of line characters. If the last line is empty (does not end
+// in an end of line), it is also stripped.
+func (f *File) Lines() ([]string, error) {
+ content, err := f.Contents()
+ if err != nil {
+ return nil, err
+ }
+
+ splits := strings.Split(content, "\n")
+ // remove the last line if it is empty
+ if splits[len(splits)-1] == "" {
+ return splits[:len(splits)-1], nil
+ }
+
+ return splits, nil
+}
+
+// FileIter provides an iterator for the files in a tree.
+type FileIter struct {
+ s storer.EncodedObjectStorer
+ w TreeWalker
+}
+
+// NewFileIter takes a storer.EncodedObjectStorer and a Tree and returns a
+// *FileIter that iterates over all files contained in the tree, recursively.
+func NewFileIter(s storer.EncodedObjectStorer, t *Tree) *FileIter {
+ return &FileIter{s: s, w: *NewTreeWalker(t, true, nil)}
+}
+
+// Next moves the iterator to the next file and returns a pointer to it. If
+// there are no more files, it returns io.EOF.
+func (iter *FileIter) Next() (*File, error) {
+ for {
+ name, entry, err := iter.w.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ if entry.Mode == filemode.Dir || entry.Mode == filemode.Submodule {
+ continue
+ }
+
+ blob, err := GetBlob(iter.s, entry.Hash)
+ if err != nil {
+ return nil, err
+ }
+
+ return NewFile(name, entry.Mode, blob), nil
+ }
+}
+
+// ForEach call the cb function for each file contained in this iter until
+// an error happens or the end of the iter is reached. If plumbing.ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *FileIter) ForEach(cb func(*File) error) error {
+ defer iter.Close()
+
+ for {
+ f, err := iter.Next()
+ if err != nil {
+ if err == io.EOF {
+ return nil
+ }
+
+ return err
+ }
+
+ if err := cb(f); err != nil {
+ if err == storer.ErrStop {
+ return nil
+ }
+
+ return err
+ }
+ }
+}
+
+func (iter *FileIter) Close() {
+ iter.w.Close()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/merge_base.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/merge_base.go
new file mode 100644
index 00000000..b412361d
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/merge_base.go
@@ -0,0 +1,210 @@
+package object
+
+import (
+ "fmt"
+ "sort"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+// errIsReachable is thrown when first commit is an ancestor of the second
+var errIsReachable = fmt.Errorf("first is reachable from second")
+
+// MergeBase mimics the behavior of `git merge-base actual other`, returning the
+// best common ancestor between the actual and the passed one.
+// The best common ancestors can not be reached from other common ancestors.
+func (c *Commit) MergeBase(other *Commit) ([]*Commit, error) {
+ // use sortedByCommitDateDesc strategy
+ sorted := sortByCommitDateDesc(c, other)
+ newer := sorted[0]
+ older := sorted[1]
+
+ newerHistory, err := ancestorsIndex(older, newer)
+ if err == errIsReachable {
+ return []*Commit{older}, nil
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ var res []*Commit
+ inNewerHistory := isInIndexCommitFilter(newerHistory)
+ resIter := NewFilterCommitIter(older, &inNewerHistory, &inNewerHistory)
+ _ = resIter.ForEach(func(commit *Commit) error {
+ res = append(res, commit)
+ return nil
+ })
+
+ return Independents(res)
+}
+
+// IsAncestor returns true if the actual commit is ancestor of the passed one.
+// It returns an error if the history is not transversable
+// It mimics the behavior of `git merge --is-ancestor actual other`
+func (c *Commit) IsAncestor(other *Commit) (bool, error) {
+ found := false
+ iter := NewCommitPreorderIter(other, nil, nil)
+ err := iter.ForEach(func(comm *Commit) error {
+ if comm.Hash != c.Hash {
+ return nil
+ }
+
+ found = true
+ return storer.ErrStop
+ })
+
+ return found, err
+}
+
+// ancestorsIndex returns a map with the ancestors of the starting commit if the
+// excluded one is not one of them. It returns errIsReachable if the excluded commit
+// is ancestor of the starting, or another error if the history is not traversable.
+func ancestorsIndex(excluded, starting *Commit) (map[plumbing.Hash]struct{}, error) {
+ if excluded.Hash.String() == starting.Hash.String() {
+ return nil, errIsReachable
+ }
+
+ startingHistory := map[plumbing.Hash]struct{}{}
+ startingIter := NewCommitIterBSF(starting, nil, nil)
+ err := startingIter.ForEach(func(commit *Commit) error {
+ if commit.Hash == excluded.Hash {
+ return errIsReachable
+ }
+
+ startingHistory[commit.Hash] = struct{}{}
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return startingHistory, nil
+}
+
+// Independents returns a subset of the passed commits, that are not reachable the others
+// It mimics the behavior of `git merge-base --independent commit...`.
+func Independents(commits []*Commit) ([]*Commit, error) {
+ // use sortedByCommitDateDesc strategy
+ candidates := sortByCommitDateDesc(commits...)
+ candidates = removeDuplicated(candidates)
+
+ seen := map[plumbing.Hash]struct{}{}
+ var isLimit CommitFilter = func(commit *Commit) bool {
+ _, ok := seen[commit.Hash]
+ return ok
+ }
+
+ if len(candidates) < 2 {
+ return candidates, nil
+ }
+
+ pos := 0
+ for {
+ from := candidates[pos]
+ others := remove(candidates, from)
+ fromHistoryIter := NewFilterCommitIter(from, nil, &isLimit)
+ err := fromHistoryIter.ForEach(func(fromAncestor *Commit) error {
+ for _, other := range others {
+ if fromAncestor.Hash == other.Hash {
+ candidates = remove(candidates, other)
+ others = remove(others, other)
+ }
+ }
+
+ if len(candidates) == 1 {
+ return storer.ErrStop
+ }
+
+ seen[fromAncestor.Hash] = struct{}{}
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ nextPos := indexOf(candidates, from) + 1
+ if nextPos >= len(candidates) {
+ break
+ }
+
+ pos = nextPos
+ }
+
+ return candidates, nil
+}
+
+// sortByCommitDateDesc returns the passed commits, sorted by `committer.When desc`
+//
+// Following this strategy, it is tried to reduce the time needed when walking
+// the history from one commit to reach the others. It is assumed that ancestors
+// use to be committed before its descendant;
+// That way `Independents(A^, A)` will be processed as being `Independents(A, A^)`;
+// so starting by `A` it will be reached `A^` way sooner than walking from `A^`
+// to the initial commit, and then from `A` to `A^`.
+func sortByCommitDateDesc(commits ...*Commit) []*Commit {
+ sorted := make([]*Commit, len(commits))
+ copy(sorted, commits)
+ sort.Slice(sorted, func(i, j int) bool {
+ return sorted[i].Committer.When.After(sorted[j].Committer.When)
+ })
+
+ return sorted
+}
+
+// indexOf returns the first position where target was found in the passed commits
+func indexOf(commits []*Commit, target *Commit) int {
+ for i, commit := range commits {
+ if target.Hash == commit.Hash {
+ return i
+ }
+ }
+
+ return -1
+}
+
+// remove returns the passed commits excluding the commit toDelete
+func remove(commits []*Commit, toDelete *Commit) []*Commit {
+ res := make([]*Commit, len(commits))
+ j := 0
+ for _, commit := range commits {
+ if commit.Hash == toDelete.Hash {
+ continue
+ }
+
+ res[j] = commit
+ j++
+ }
+
+ return res[:j]
+}
+
+// removeDuplicated removes duplicated commits from the passed slice of commits
+func removeDuplicated(commits []*Commit) []*Commit {
+ seen := make(map[plumbing.Hash]struct{}, len(commits))
+ res := make([]*Commit, len(commits))
+ j := 0
+ for _, commit := range commits {
+ if _, ok := seen[commit.Hash]; ok {
+ continue
+ }
+
+ seen[commit.Hash] = struct{}{}
+ res[j] = commit
+ j++
+ }
+
+ return res[:j]
+}
+
+// isInIndexCommitFilter returns a commitFilter that returns true
+// if the commit is in the passed index.
+func isInIndexCommitFilter(index map[plumbing.Hash]struct{}) CommitFilter {
+ return func(c *Commit) bool {
+ _, ok := index[c.Hash]
+ return ok
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/object.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/object.go
new file mode 100644
index 00000000..13b1e91c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/object.go
@@ -0,0 +1,239 @@
+// Package object contains implementations of all Git objects and utility
+// functions to work with them.
+package object
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+// ErrUnsupportedObject trigger when a non-supported object is being decoded.
+var ErrUnsupportedObject = errors.New("unsupported object type")
+
+// Object is a generic representation of any git object. It is implemented by
+// Commit, Tree, Blob, and Tag, and includes the functions that are common to
+// them.
+//
+// Object is returned when an object can be of any type. It is frequently used
+// with a type cast to acquire the specific type of object:
+//
+// func process(obj Object) {
+// switch o := obj.(type) {
+// case *Commit:
+// // o is a Commit
+// case *Tree:
+// // o is a Tree
+// case *Blob:
+// // o is a Blob
+// case *Tag:
+// // o is a Tag
+// }
+// }
+//
+// This interface is intentionally different from plumbing.EncodedObject, which
+// is a lower level interface used by storage implementations to read and write
+// objects in its encoded form.
+type Object interface {
+ ID() plumbing.Hash
+ Type() plumbing.ObjectType
+ Decode(plumbing.EncodedObject) error
+ Encode(plumbing.EncodedObject) error
+}
+
+// GetObject gets an object from an object storer and decodes it.
+func GetObject(s storer.EncodedObjectStorer, h plumbing.Hash) (Object, error) {
+ o, err := s.EncodedObject(plumbing.AnyObject, h)
+ if err != nil {
+ return nil, err
+ }
+
+ return DecodeObject(s, o)
+}
+
+// DecodeObject decodes an encoded object into an Object and associates it to
+// the given object storer.
+func DecodeObject(s storer.EncodedObjectStorer, o plumbing.EncodedObject) (Object, error) {
+ switch o.Type() {
+ case plumbing.CommitObject:
+ return DecodeCommit(s, o)
+ case plumbing.TreeObject:
+ return DecodeTree(s, o)
+ case plumbing.BlobObject:
+ return DecodeBlob(o)
+ case plumbing.TagObject:
+ return DecodeTag(s, o)
+ default:
+ return nil, plumbing.ErrInvalidType
+ }
+}
+
+// DateFormat is the format being used in the original git implementation
+const DateFormat = "Mon Jan 02 15:04:05 2006 -0700"
+
+// Signature is used to identify who and when created a commit or tag.
+type Signature struct {
+ // Name represents a person name. It is an arbitrary string.
+ Name string
+ // Email is an email, but it cannot be assumed to be well-formed.
+ Email string
+ // When is the timestamp of the signature.
+ When time.Time
+}
+
+// Decode decodes a byte slice into a signature
+func (s *Signature) Decode(b []byte) {
+ open := bytes.LastIndexByte(b, '<')
+ close := bytes.LastIndexByte(b, '>')
+ if open == -1 || close == -1 {
+ return
+ }
+
+ if close < open {
+ return
+ }
+
+ s.Name = string(bytes.Trim(b[:open], " "))
+ s.Email = string(b[open+1 : close])
+
+ hasTime := close+2 < len(b)
+ if hasTime {
+ s.decodeTimeAndTimeZone(b[close+2:])
+ }
+}
+
+// Encode encodes a Signature into a writer.
+func (s *Signature) Encode(w io.Writer) error {
+ if _, err := fmt.Fprintf(w, "%s <%s> ", s.Name, s.Email); err != nil {
+ return err
+ }
+ if err := s.encodeTimeAndTimeZone(w); err != nil {
+ return err
+ }
+ return nil
+}
+
+var timeZoneLength = 5
+
+func (s *Signature) decodeTimeAndTimeZone(b []byte) {
+ space := bytes.IndexByte(b, ' ')
+ if space == -1 {
+ space = len(b)
+ }
+
+ ts, err := strconv.ParseInt(string(b[:space]), 10, 64)
+ if err != nil {
+ return
+ }
+
+ s.When = time.Unix(ts, 0).In(time.UTC)
+ var tzStart = space + 1
+ if tzStart >= len(b) || tzStart+timeZoneLength > len(b) {
+ return
+ }
+
+ timezone := string(b[tzStart : tzStart+timeZoneLength])
+ tzhours, err1 := strconv.ParseInt(timezone[0:3], 10, 64)
+ tzmins, err2 := strconv.ParseInt(timezone[3:], 10, 64)
+ if err1 != nil || err2 != nil {
+ return
+ }
+ if tzhours < 0 {
+ tzmins *= -1
+ }
+
+ tz := time.FixedZone("", int(tzhours*60*60+tzmins*60))
+
+ s.When = s.When.In(tz)
+}
+
+func (s *Signature) encodeTimeAndTimeZone(w io.Writer) error {
+ u := s.When.Unix()
+ if u < 0 {
+ u = 0
+ }
+ _, err := fmt.Fprintf(w, "%d %s", u, s.When.Format("-0700"))
+ return err
+}
+
+func (s *Signature) String() string {
+ return fmt.Sprintf("%s <%s>", s.Name, s.Email)
+}
+
+// ObjectIter provides an iterator for a set of objects.
+type ObjectIter struct {
+ storer.EncodedObjectIter
+ s storer.EncodedObjectStorer
+}
+
+// NewObjectIter takes a storer.EncodedObjectStorer and a
+// storer.EncodedObjectIter and returns an *ObjectIter that iterates over all
+// objects contained in the storer.EncodedObjectIter.
+func NewObjectIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *ObjectIter {
+ return &ObjectIter{iter, s}
+}
+
+// Next moves the iterator to the next object and returns a pointer to it. If
+// there are no more objects, it returns io.EOF.
+func (iter *ObjectIter) Next() (Object, error) {
+ for {
+ obj, err := iter.EncodedObjectIter.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ o, err := iter.toObject(obj)
+ if err == plumbing.ErrInvalidType {
+ continue
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ return o, nil
+ }
+}
+
+// ForEach call the cb function for each object contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *ObjectIter) ForEach(cb func(Object) error) error {
+ return iter.EncodedObjectIter.ForEach(func(obj plumbing.EncodedObject) error {
+ o, err := iter.toObject(obj)
+ if err == plumbing.ErrInvalidType {
+ return nil
+ }
+
+ if err != nil {
+ return err
+ }
+
+ return cb(o)
+ })
+}
+
+func (iter *ObjectIter) toObject(obj plumbing.EncodedObject) (Object, error) {
+ switch obj.Type() {
+ case plumbing.BlobObject:
+ blob := &Blob{}
+ return blob, blob.Decode(obj)
+ case plumbing.TreeObject:
+ tree := &Tree{s: iter.s}
+ return tree, tree.Decode(obj)
+ case plumbing.CommitObject:
+ commit := &Commit{}
+ return commit, commit.Decode(obj)
+ case plumbing.TagObject:
+ tag := &Tag{}
+ return tag, tag.Decode(obj)
+ default:
+ return nil, plumbing.ErrInvalidType
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go
new file mode 100644
index 00000000..3c61f626
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go
@@ -0,0 +1,337 @@
+package object
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ fdiff "github.com/go-git/go-git/v5/plumbing/format/diff"
+ "github.com/go-git/go-git/v5/utils/diff"
+
+ dmp "github.com/sergi/go-diff/diffmatchpatch"
+)
+
+var (
+ ErrCanceled = errors.New("operation canceled")
+)
+
+func getPatch(message string, changes ...*Change) (*Patch, error) {
+ ctx := context.Background()
+ return getPatchContext(ctx, message, changes...)
+}
+
+func getPatchContext(ctx context.Context, message string, changes ...*Change) (*Patch, error) {
+ var filePatches []fdiff.FilePatch
+ for _, c := range changes {
+ select {
+ case <-ctx.Done():
+ return nil, ErrCanceled
+ default:
+ }
+
+ fp, err := filePatchWithContext(ctx, c)
+ if err != nil {
+ return nil, err
+ }
+
+ filePatches = append(filePatches, fp)
+ }
+
+ return &Patch{message, filePatches}, nil
+}
+
+func filePatchWithContext(ctx context.Context, c *Change) (fdiff.FilePatch, error) {
+ from, to, err := c.Files()
+ if err != nil {
+ return nil, err
+ }
+ fromContent, fIsBinary, err := fileContent(from)
+ if err != nil {
+ return nil, err
+ }
+
+ toContent, tIsBinary, err := fileContent(to)
+ if err != nil {
+ return nil, err
+ }
+
+ if fIsBinary || tIsBinary {
+ return &textFilePatch{from: c.From, to: c.To}, nil
+ }
+
+ diffs := diff.Do(fromContent, toContent)
+
+ var chunks []fdiff.Chunk
+ for _, d := range diffs {
+ select {
+ case <-ctx.Done():
+ return nil, ErrCanceled
+ default:
+ }
+
+ var op fdiff.Operation
+ switch d.Type {
+ case dmp.DiffEqual:
+ op = fdiff.Equal
+ case dmp.DiffDelete:
+ op = fdiff.Delete
+ case dmp.DiffInsert:
+ op = fdiff.Add
+ }
+
+ chunks = append(chunks, &textChunk{d.Text, op})
+ }
+
+ return &textFilePatch{
+ chunks: chunks,
+ from: c.From,
+ to: c.To,
+ }, nil
+
+}
+
+func fileContent(f *File) (content string, isBinary bool, err error) {
+ if f == nil {
+ return
+ }
+
+ isBinary, err = f.IsBinary()
+ if err != nil || isBinary {
+ return
+ }
+
+ content, err = f.Contents()
+
+ return
+}
+
+// Patch is an implementation of fdiff.Patch interface
+type Patch struct {
+ message string
+ filePatches []fdiff.FilePatch
+}
+
+func (p *Patch) FilePatches() []fdiff.FilePatch {
+ return p.filePatches
+}
+
+func (p *Patch) Message() string {
+ return p.message
+}
+
+func (p *Patch) Encode(w io.Writer) error {
+ ue := fdiff.NewUnifiedEncoder(w, fdiff.DefaultContextLines)
+
+ return ue.Encode(p)
+}
+
+func (p *Patch) Stats() FileStats {
+ return getFileStatsFromFilePatches(p.FilePatches())
+}
+
+func (p *Patch) String() string {
+ buf := bytes.NewBuffer(nil)
+ err := p.Encode(buf)
+ if err != nil {
+ return fmt.Sprintf("malformed patch: %s", err.Error())
+ }
+
+ return buf.String()
+}
+
+// changeEntryWrapper is an implementation of fdiff.File interface
+type changeEntryWrapper struct {
+ ce ChangeEntry
+}
+
+func (f *changeEntryWrapper) Hash() plumbing.Hash {
+ if !f.ce.TreeEntry.Mode.IsFile() {
+ return plumbing.ZeroHash
+ }
+
+ return f.ce.TreeEntry.Hash
+}
+
+func (f *changeEntryWrapper) Mode() filemode.FileMode {
+ return f.ce.TreeEntry.Mode
+}
+func (f *changeEntryWrapper) Path() string {
+ if !f.ce.TreeEntry.Mode.IsFile() {
+ return ""
+ }
+
+ return f.ce.Name
+}
+
+func (f *changeEntryWrapper) Empty() bool {
+ return !f.ce.TreeEntry.Mode.IsFile()
+}
+
+// textFilePatch is an implementation of fdiff.FilePatch interface
+type textFilePatch struct {
+ chunks []fdiff.Chunk
+ from, to ChangeEntry
+}
+
+func (tf *textFilePatch) Files() (from fdiff.File, to fdiff.File) {
+ f := &changeEntryWrapper{tf.from}
+ t := &changeEntryWrapper{tf.to}
+
+ if !f.Empty() {
+ from = f
+ }
+
+ if !t.Empty() {
+ to = t
+ }
+
+ return
+}
+
+func (tf *textFilePatch) IsBinary() bool {
+ return len(tf.chunks) == 0
+}
+
+func (tf *textFilePatch) Chunks() []fdiff.Chunk {
+ return tf.chunks
+}
+
+// textChunk is an implementation of fdiff.Chunk interface
+type textChunk struct {
+ content string
+ op fdiff.Operation
+}
+
+func (t *textChunk) Content() string {
+ return t.content
+}
+
+func (t *textChunk) Type() fdiff.Operation {
+ return t.op
+}
+
+// FileStat stores the status of changes in content of a file.
+type FileStat struct {
+ Name string
+ Addition int
+ Deletion int
+}
+
+func (fs FileStat) String() string {
+ return printStat([]FileStat{fs})
+}
+
+// FileStats is a collection of FileStat.
+type FileStats []FileStat
+
+func (fileStats FileStats) String() string {
+ return printStat(fileStats)
+}
+
+// printStat prints the stats of changes in content of files.
+// Original implementation: https://github.com/git/git/blob/1a87c842ece327d03d08096395969aca5e0a6996/diff.c#L2615
+// Parts of the output:
+// |<+++/--->
+// example: " main.go | 10 +++++++--- "
+func printStat(fileStats []FileStat) string {
+ maxGraphWidth := uint(53)
+ maxNameLen := 0
+ maxChangeLen := 0
+
+ scaleLinear := func(it, width, max uint) uint {
+ if it == 0 || max == 0 {
+ return 0
+ }
+
+ return 1 + (it * (width - 1) / max)
+ }
+
+ for _, fs := range fileStats {
+ if len(fs.Name) > maxNameLen {
+ maxNameLen = len(fs.Name)
+ }
+
+ changes := strconv.Itoa(fs.Addition + fs.Deletion)
+ if len(changes) > maxChangeLen {
+ maxChangeLen = len(changes)
+ }
+ }
+
+ result := ""
+ for _, fs := range fileStats {
+ add := uint(fs.Addition)
+ del := uint(fs.Deletion)
+ np := maxNameLen - len(fs.Name)
+ cp := maxChangeLen - len(strconv.Itoa(fs.Addition+fs.Deletion))
+
+ total := add + del
+ if total > maxGraphWidth {
+ add = scaleLinear(add, maxGraphWidth, total)
+ del = scaleLinear(del, maxGraphWidth, total)
+ }
+
+ adds := strings.Repeat("+", int(add))
+ dels := strings.Repeat("-", int(del))
+ namePad := strings.Repeat(" ", np)
+ changePad := strings.Repeat(" ", cp)
+
+ result += fmt.Sprintf(" %s%s | %s%d %s%s\n", fs.Name, namePad, changePad, total, adds, dels)
+ }
+ return result
+}
+
+func getFileStatsFromFilePatches(filePatches []fdiff.FilePatch) FileStats {
+ var fileStats FileStats
+
+ for _, fp := range filePatches {
+ // ignore empty patches (binary files, submodule refs updates)
+ if len(fp.Chunks()) == 0 {
+ continue
+ }
+
+ cs := FileStat{}
+ from, to := fp.Files()
+ if from == nil {
+ // New File is created.
+ cs.Name = to.Path()
+ } else if to == nil {
+ // File is deleted.
+ cs.Name = from.Path()
+ } else if from.Path() != to.Path() {
+ // File is renamed.
+ cs.Name = fmt.Sprintf("%s => %s", from.Path(), to.Path())
+ } else {
+ cs.Name = from.Path()
+ }
+
+ for _, chunk := range fp.Chunks() {
+ s := chunk.Content()
+ if len(s) == 0 {
+ continue
+ }
+
+ switch chunk.Type() {
+ case fdiff.Add:
+ cs.Addition += strings.Count(s, "\n")
+ if s[len(s)-1] != '\n' {
+ cs.Addition++
+ }
+ case fdiff.Delete:
+ cs.Deletion += strings.Count(s, "\n")
+ if s[len(s)-1] != '\n' {
+ cs.Deletion++
+ }
+ }
+ }
+
+ fileStats = append(fileStats, cs)
+ }
+
+ return fileStats
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/rename.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/rename.go
new file mode 100644
index 00000000..ad2b902c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/rename.go
@@ -0,0 +1,816 @@
+package object
+
+import (
+ "errors"
+ "io"
+ "sort"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/merkletrie"
+)
+
+// DetectRenames detects the renames in the given changes on two trees with
+// the given options. It will return the given changes grouping additions and
+// deletions into modifications when possible.
+// If options is nil, the default diff tree options will be used.
+func DetectRenames(
+ changes Changes,
+ opts *DiffTreeOptions,
+) (Changes, error) {
+ if opts == nil {
+ opts = DefaultDiffTreeOptions
+ }
+
+ detector := &renameDetector{
+ renameScore: int(opts.RenameScore),
+ renameLimit: int(opts.RenameLimit),
+ onlyExact: opts.OnlyExactRenames,
+ }
+
+ for _, c := range changes {
+ action, err := c.Action()
+ if err != nil {
+ return nil, err
+ }
+
+ switch action {
+ case merkletrie.Insert:
+ detector.added = append(detector.added, c)
+ case merkletrie.Delete:
+ detector.deleted = append(detector.deleted, c)
+ default:
+ detector.modified = append(detector.modified, c)
+ }
+ }
+
+ return detector.detect()
+}
+
+// renameDetector will detect and resolve renames in a set of changes.
+// see: https://github.com/eclipse/jgit/blob/master/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
+type renameDetector struct {
+ added []*Change
+ deleted []*Change
+ modified []*Change
+
+ renameScore int
+ renameLimit int
+ onlyExact bool
+}
+
+// detectExactRenames detects matches files that were deleted with files that
+// were added where the hash is the same on both. If there are multiple targets
+// the one with the most similar path will be chosen as the rename and the
+// rest as either deletions or additions.
+func (d *renameDetector) detectExactRenames() {
+ added := groupChangesByHash(d.added)
+ deletes := groupChangesByHash(d.deleted)
+ var uniqueAdds []*Change
+ var nonUniqueAdds [][]*Change
+ var addedLeft []*Change
+
+ for _, cs := range added {
+ if len(cs) == 1 {
+ uniqueAdds = append(uniqueAdds, cs[0])
+ } else {
+ nonUniqueAdds = append(nonUniqueAdds, cs)
+ }
+ }
+
+ for _, c := range uniqueAdds {
+ hash := changeHash(c)
+ deleted := deletes[hash]
+
+ if len(deleted) == 1 {
+ if sameMode(c, deleted[0]) {
+ d.modified = append(d.modified, &Change{From: deleted[0].From, To: c.To})
+ delete(deletes, hash)
+ } else {
+ addedLeft = append(addedLeft, c)
+ }
+ } else if len(deleted) > 1 {
+ bestMatch := bestNameMatch(c, deleted)
+ if bestMatch != nil && sameMode(c, bestMatch) {
+ d.modified = append(d.modified, &Change{From: bestMatch.From, To: c.To})
+ delete(deletes, hash)
+
+ var newDeletes = make([]*Change, 0, len(deleted)-1)
+ for _, d := range deleted {
+ if d != bestMatch {
+ newDeletes = append(newDeletes, d)
+ }
+ }
+ deletes[hash] = newDeletes
+ }
+ } else {
+ addedLeft = append(addedLeft, c)
+ }
+ }
+
+ for _, added := range nonUniqueAdds {
+ hash := changeHash(added[0])
+ deleted := deletes[hash]
+
+ if len(deleted) == 1 {
+ deleted := deleted[0]
+ bestMatch := bestNameMatch(deleted, added)
+ if bestMatch != nil && sameMode(deleted, bestMatch) {
+ d.modified = append(d.modified, &Change{From: deleted.From, To: bestMatch.To})
+ delete(deletes, hash)
+
+ for _, c := range added {
+ if c != bestMatch {
+ addedLeft = append(addedLeft, c)
+ }
+ }
+ } else {
+ addedLeft = append(addedLeft, added...)
+ }
+ } else if len(deleted) > 1 {
+ maxSize := len(deleted) * len(added)
+ if d.renameLimit > 0 && d.renameLimit < maxSize {
+ maxSize = d.renameLimit
+ }
+
+ matrix := make(similarityMatrix, 0, maxSize)
+
+ for delIdx, del := range deleted {
+ deletedName := changeName(del)
+
+ for addIdx, add := range added {
+ addedName := changeName(add)
+
+ score := nameSimilarityScore(addedName, deletedName)
+ matrix = append(matrix, similarityPair{added: addIdx, deleted: delIdx, score: score})
+
+ if len(matrix) >= maxSize {
+ break
+ }
+ }
+
+ if len(matrix) >= maxSize {
+ break
+ }
+ }
+
+ sort.Stable(matrix)
+
+ usedAdds := make(map[*Change]struct{})
+ usedDeletes := make(map[*Change]struct{})
+ for i := len(matrix) - 1; i >= 0; i-- {
+ del := deleted[matrix[i].deleted]
+ add := added[matrix[i].added]
+
+ if add == nil || del == nil {
+ // it was already matched
+ continue
+ }
+
+ usedAdds[add] = struct{}{}
+ usedDeletes[del] = struct{}{}
+ d.modified = append(d.modified, &Change{From: del.From, To: add.To})
+ added[matrix[i].added] = nil
+ deleted[matrix[i].deleted] = nil
+ }
+
+ for _, c := range added {
+ if _, ok := usedAdds[c]; !ok && c != nil {
+ addedLeft = append(addedLeft, c)
+ }
+ }
+
+ var newDeletes = make([]*Change, 0, len(deleted)-len(usedDeletes))
+ for _, c := range deleted {
+ if _, ok := usedDeletes[c]; !ok && c != nil {
+ newDeletes = append(newDeletes, c)
+ }
+ }
+ deletes[hash] = newDeletes
+ } else {
+ addedLeft = append(addedLeft, added...)
+ }
+ }
+
+ d.added = addedLeft
+ d.deleted = nil
+ for _, dels := range deletes {
+ d.deleted = append(d.deleted, dels...)
+ }
+}
+
+// detectContentRenames detects renames based on the similarity of the content
+// in the files by building a matrix of pairs between sources and destinations
+// and matching by the highest score.
+// see: https://github.com/eclipse/jgit/blob/master/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
+func (d *renameDetector) detectContentRenames() error {
+ cnt := max(len(d.added), len(d.deleted))
+ if d.renameLimit > 0 && cnt > d.renameLimit {
+ return nil
+ }
+
+ srcs, dsts := d.deleted, d.added
+ matrix, err := buildSimilarityMatrix(srcs, dsts, d.renameScore)
+ if err != nil {
+ return err
+ }
+ renames := make([]*Change, 0, min(len(matrix), len(dsts)))
+
+ // Match rename pairs on a first come, first serve basis until
+ // we have looked at everything that is above the minimum score.
+ for i := len(matrix) - 1; i >= 0; i-- {
+ pair := matrix[i]
+ src := srcs[pair.deleted]
+ dst := dsts[pair.added]
+
+ if dst == nil || src == nil {
+ // It was already matched before
+ continue
+ }
+
+ renames = append(renames, &Change{From: src.From, To: dst.To})
+
+ // Claim destination and source as matched
+ dsts[pair.added] = nil
+ srcs[pair.deleted] = nil
+ }
+
+ d.modified = append(d.modified, renames...)
+ d.added = compactChanges(dsts)
+ d.deleted = compactChanges(srcs)
+
+ return nil
+}
+
+func (d *renameDetector) detect() (Changes, error) {
+ if len(d.added) > 0 && len(d.deleted) > 0 {
+ d.detectExactRenames()
+
+ if !d.onlyExact {
+ if err := d.detectContentRenames(); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ result := make(Changes, 0, len(d.added)+len(d.deleted)+len(d.modified))
+ result = append(result, d.added...)
+ result = append(result, d.deleted...)
+ result = append(result, d.modified...)
+
+ sort.Stable(result)
+
+ return result, nil
+}
+
+func bestNameMatch(change *Change, changes []*Change) *Change {
+ var best *Change
+ var bestScore int
+
+ cname := changeName(change)
+
+ for _, c := range changes {
+ score := nameSimilarityScore(cname, changeName(c))
+ if score > bestScore {
+ bestScore = score
+ best = c
+ }
+ }
+
+ return best
+}
+
+func nameSimilarityScore(a, b string) int {
+ aDirLen := strings.LastIndexByte(a, '/') + 1
+ bDirLen := strings.LastIndexByte(b, '/') + 1
+
+ dirMin := min(aDirLen, bDirLen)
+ dirMax := max(aDirLen, bDirLen)
+
+ var dirScoreLtr, dirScoreRtl int
+ if dirMax == 0 {
+ dirScoreLtr = 100
+ dirScoreRtl = 100
+ } else {
+ var dirSim int
+
+ for ; dirSim < dirMin; dirSim++ {
+ if a[dirSim] != b[dirSim] {
+ break
+ }
+ }
+
+ dirScoreLtr = dirSim * 100 / dirMax
+
+ if dirScoreLtr == 100 {
+ dirScoreRtl = 100
+ } else {
+ for dirSim = 0; dirSim < dirMin; dirSim++ {
+ if a[aDirLen-1-dirSim] != b[bDirLen-1-dirSim] {
+ break
+ }
+ }
+ dirScoreRtl = dirSim * 100 / dirMax
+ }
+ }
+
+ fileMin := min(len(a)-aDirLen, len(b)-bDirLen)
+ fileMax := max(len(a)-aDirLen, len(b)-bDirLen)
+
+ fileSim := 0
+ for ; fileSim < fileMin; fileSim++ {
+ if a[len(a)-1-fileSim] != b[len(b)-1-fileSim] {
+ break
+ }
+ }
+ fileScore := fileSim * 100 / fileMax
+
+ return (((dirScoreLtr + dirScoreRtl) * 25) + (fileScore * 50)) / 100
+}
+
+func changeName(c *Change) string {
+ if c.To != empty {
+ return c.To.Name
+ }
+ return c.From.Name
+}
+
+func changeHash(c *Change) plumbing.Hash {
+ if c.To != empty {
+ return c.To.TreeEntry.Hash
+ }
+
+ return c.From.TreeEntry.Hash
+}
+
+func changeMode(c *Change) filemode.FileMode {
+ if c.To != empty {
+ return c.To.TreeEntry.Mode
+ }
+
+ return c.From.TreeEntry.Mode
+}
+
+func sameMode(a, b *Change) bool {
+ return changeMode(a) == changeMode(b)
+}
+
+func groupChangesByHash(changes []*Change) map[plumbing.Hash][]*Change {
+ var result = make(map[plumbing.Hash][]*Change)
+ for _, c := range changes {
+ hash := changeHash(c)
+ result[hash] = append(result[hash], c)
+ }
+ return result
+}
+
+type similarityMatrix []similarityPair
+
+func (m similarityMatrix) Len() int { return len(m) }
+func (m similarityMatrix) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
+func (m similarityMatrix) Less(i, j int) bool {
+ if m[i].score == m[j].score {
+ if m[i].added == m[j].added {
+ return m[i].deleted < m[j].deleted
+ }
+ return m[i].added < m[j].added
+ }
+ return m[i].score < m[j].score
+}
+
+type similarityPair struct {
+ // index of the added file
+ added int
+ // index of the deleted file
+ deleted int
+ // similarity score
+ score int
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func min(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+
+const maxMatrixSize = 10000
+
+func buildSimilarityMatrix(srcs, dsts []*Change, renameScore int) (similarityMatrix, error) {
+ // Allocate for the worst-case scenario where every pair has a score
+ // that we need to consider. We might not need that many.
+ matrixSize := len(srcs) * len(dsts)
+ if matrixSize > maxMatrixSize {
+ matrixSize = maxMatrixSize
+ }
+ matrix := make(similarityMatrix, 0, matrixSize)
+ srcSizes := make([]int64, len(srcs))
+ dstSizes := make([]int64, len(dsts))
+ dstTooLarge := make(map[int]bool)
+
+ // Consider each pair of files, if the score is above the minimum
+ // threshold we need to record that scoring in the matrix so we can
+ // later find the best matches.
+outerLoop:
+ for srcIdx, src := range srcs {
+ if changeMode(src) != filemode.Regular {
+ continue
+ }
+
+ // Declare the from file and the similarity index here to be able to
+ // reuse it inside the inner loop. The reason to not initialize them
+ // here is so we can skip the initialization in case they happen to
+ // not be needed later. They will be initialized inside the inner
+ // loop if and only if they're needed and reused in subsequent passes.
+ var from *File
+ var s *similarityIndex
+ var err error
+ for dstIdx, dst := range dsts {
+ if changeMode(dst) != filemode.Regular {
+ continue
+ }
+
+ if dstTooLarge[dstIdx] {
+ continue
+ }
+
+ var to *File
+ srcSize := srcSizes[srcIdx]
+ if srcSize == 0 {
+ from, _, err = src.Files()
+ if err != nil {
+ return nil, err
+ }
+ srcSize = from.Size + 1
+ srcSizes[srcIdx] = srcSize
+ }
+
+ dstSize := dstSizes[dstIdx]
+ if dstSize == 0 {
+ _, to, err = dst.Files()
+ if err != nil {
+ return nil, err
+ }
+ dstSize = to.Size + 1
+ dstSizes[dstIdx] = dstSize
+ }
+
+ min, max := srcSize, dstSize
+ if dstSize < srcSize {
+ min = dstSize
+ max = srcSize
+ }
+
+ if int(min*100/max) < renameScore {
+ // File sizes are too different to be a match
+ continue
+ }
+
+ if s == nil {
+ s, err = fileSimilarityIndex(from)
+ if err != nil {
+ if err == errIndexFull {
+ continue outerLoop
+ }
+ return nil, err
+ }
+ }
+
+ if to == nil {
+ _, to, err = dst.Files()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ di, err := fileSimilarityIndex(to)
+ if err != nil {
+ if err == errIndexFull {
+ dstTooLarge[dstIdx] = true
+ }
+
+ return nil, err
+ }
+
+ contentScore := s.score(di, 10000)
+ // The name score returns a value between 0 and 100, so we need to
+ // convert it to the same range as the content score.
+ nameScore := nameSimilarityScore(src.From.Name, dst.To.Name) * 100
+ score := (contentScore*99 + nameScore*1) / 10000
+
+ if score < renameScore {
+ continue
+ }
+
+ matrix = append(matrix, similarityPair{added: dstIdx, deleted: srcIdx, score: score})
+ }
+ }
+
+ sort.Stable(matrix)
+
+ return matrix, nil
+}
+
+func compactChanges(changes []*Change) []*Change {
+ var result []*Change
+ for _, c := range changes {
+ if c != nil {
+ result = append(result, c)
+ }
+ }
+ return result
+}
+
+const (
+ keyShift = 32
+ maxCountValue = (1 << keyShift) - 1
+)
+
+var errIndexFull = errors.New("index is full")
+
+// similarityIndex is an index structure of lines/blocks in one file.
+// This structure can be used to compute an approximation of the similarity
+// between two files.
+// To save space in memory, this index uses a space efficient encoding which
+// will not exceed 1MiB per instance. The index starts out at a smaller size
+// (closer to 2KiB), but may grow as more distinct blocks within the scanned
+// file are discovered.
+// see: https://github.com/eclipse/jgit/blob/master/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java
+type similarityIndex struct {
+ hashed uint64
+ // number of non-zero entries in hashes
+ numHashes int
+ growAt int
+ hashes []keyCountPair
+ hashBits int
+}
+
+func fileSimilarityIndex(f *File) (*similarityIndex, error) {
+ idx := newSimilarityIndex()
+ if err := idx.hash(f); err != nil {
+ return nil, err
+ }
+
+ sort.Stable(keyCountPairs(idx.hashes))
+
+ return idx, nil
+}
+
+func newSimilarityIndex() *similarityIndex {
+ return &similarityIndex{
+ hashBits: 8,
+ hashes: make([]keyCountPair, 1<<8),
+ growAt: shouldGrowAt(8),
+ }
+}
+
+func (i *similarityIndex) hash(f *File) error {
+ isBin, err := f.IsBinary()
+ if err != nil {
+ return err
+ }
+
+ r, err := f.Reader()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(r, &err)
+
+ return i.hashContent(r, f.Size, isBin)
+}
+
+func (i *similarityIndex) hashContent(r io.Reader, size int64, isBin bool) error {
+ var buf = make([]byte, 4096)
+ var ptr, cnt int
+ remaining := size
+
+ for 0 < remaining {
+ hash := 5381
+ var blockHashedCnt uint64
+
+ // Hash one line or block, whatever happens first
+ n := int64(0)
+ for {
+ if ptr == cnt {
+ ptr = 0
+ var err error
+ cnt, err = io.ReadFull(r, buf)
+ if err != nil && err != io.ErrUnexpectedEOF {
+ return err
+ }
+
+ if cnt == 0 {
+ return io.EOF
+ }
+ }
+ n++
+ c := buf[ptr] & 0xff
+ ptr++
+
+ // Ignore CR in CRLF sequence if it's text
+ if !isBin && c == '\r' && ptr < cnt && buf[ptr] == '\n' {
+ continue
+ }
+ blockHashedCnt++
+
+ if c == '\n' {
+ break
+ }
+
+ hash = (hash << 5) + hash + int(c)
+
+ if n >= 64 || n >= remaining {
+ break
+ }
+ }
+ i.hashed += blockHashedCnt
+ if err := i.add(hash, blockHashedCnt); err != nil {
+ return err
+ }
+ remaining -= n
+ }
+
+ return nil
+}
+
+// score computes the similarity score between this index and another one.
+// A region of a file is defined as a line in a text file or a fixed-size
+// block in a binary file. To prepare an index, each region in the file is
+// hashed; the values and counts of hashes are retained in a sorted table.
+// Define the similarity fraction F as the count of matching regions between
+// the two files divided between the maximum count of regions in either file.
+// The similarity score is F multiplied by the maxScore constant, yielding a
+// range [0, maxScore]. It is defined as maxScore for the degenerate case of
+// two empty files.
+// The similarity score is symmetrical; i.e. a.score(b) == b.score(a).
+func (i *similarityIndex) score(other *similarityIndex, maxScore int) int {
+ var maxHashed = i.hashed
+ if maxHashed < other.hashed {
+ maxHashed = other.hashed
+ }
+ if maxHashed == 0 {
+ return maxScore
+ }
+
+ return int(i.common(other) * uint64(maxScore) / maxHashed)
+}
+
+func (i *similarityIndex) common(dst *similarityIndex) uint64 {
+ srcIdx, dstIdx := 0, 0
+ if i.numHashes == 0 || dst.numHashes == 0 {
+ return 0
+ }
+
+ var common uint64
+ srcKey, dstKey := i.hashes[srcIdx].key(), dst.hashes[dstIdx].key()
+
+ for {
+ if srcKey == dstKey {
+ srcCnt, dstCnt := i.hashes[srcIdx].count(), dst.hashes[dstIdx].count()
+ if srcCnt < dstCnt {
+ common += srcCnt
+ } else {
+ common += dstCnt
+ }
+
+ srcIdx++
+ if srcIdx == len(i.hashes) {
+ break
+ }
+ srcKey = i.hashes[srcIdx].key()
+
+ dstIdx++
+ if dstIdx == len(dst.hashes) {
+ break
+ }
+ dstKey = dst.hashes[dstIdx].key()
+ } else if srcKey < dstKey {
+ // Region of src that is not in dst
+ srcIdx++
+ if srcIdx == len(i.hashes) {
+ break
+ }
+ srcKey = i.hashes[srcIdx].key()
+ } else {
+ // Region of dst that is not in src
+ dstIdx++
+ if dstIdx == len(dst.hashes) {
+ break
+ }
+ dstKey = dst.hashes[dstIdx].key()
+ }
+ }
+
+ return common
+}
+
+func (i *similarityIndex) add(key int, cnt uint64) error {
+ key = int(uint32(key) * 0x9e370001 >> 1)
+
+ j := i.slot(key)
+ for {
+ v := i.hashes[j]
+ if v == 0 {
+ // It's an empty slot, so we can store it here.
+ if i.growAt <= i.numHashes {
+ if err := i.grow(); err != nil {
+ return err
+ }
+ j = i.slot(key)
+ continue
+ }
+
+ var err error
+ i.hashes[j], err = newKeyCountPair(key, cnt)
+ if err != nil {
+ return err
+ }
+ i.numHashes++
+ return nil
+ } else if v.key() == key {
+ // It's the same key, so increment the counter.
+ var err error
+ i.hashes[j], err = newKeyCountPair(key, v.count()+cnt)
+ return err
+ } else if j+1 >= len(i.hashes) {
+ j = 0
+ } else {
+ j++
+ }
+ }
+}
+
+type keyCountPair uint64
+
+func newKeyCountPair(key int, cnt uint64) (keyCountPair, error) {
+ if cnt > maxCountValue {
+ return 0, errIndexFull
+ }
+
+ return keyCountPair((uint64(key) << keyShift) | cnt), nil
+}
+
+func (p keyCountPair) key() int {
+ return int(p >> keyShift)
+}
+
+func (p keyCountPair) count() uint64 {
+ return uint64(p) & maxCountValue
+}
+
+func (i *similarityIndex) slot(key int) int {
+ // We use 31 - hashBits because the upper bit was already forced
+ // to be 0 and we want the remaining high bits to be used as the
+ // table slot.
+ return int(uint32(key) >> uint(31-i.hashBits))
+}
+
+func shouldGrowAt(hashBits int) int {
+ return (1 << uint(hashBits)) * (hashBits - 3) / hashBits
+}
+
+func (i *similarityIndex) grow() error {
+ if i.hashBits == 30 {
+ return errIndexFull
+ }
+
+ old := i.hashes
+
+ i.hashBits++
+ i.growAt = shouldGrowAt(i.hashBits)
+
+ // TODO(erizocosmico): find a way to check if it will OOM and return
+ // errIndexFull instead.
+ i.hashes = make([]keyCountPair, 1<= len(i.hashes) {
+ j = 0
+ }
+ }
+ i.hashes[j] = v
+ }
+ }
+
+ return nil
+}
+
+type keyCountPairs []keyCountPair
+
+func (p keyCountPairs) Len() int { return len(p) }
+func (p keyCountPairs) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p keyCountPairs) Less(i, j int) bool { return p[i] < p[j] }
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/signature.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/signature.go
new file mode 100644
index 00000000..91cf371f
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/signature.go
@@ -0,0 +1,101 @@
+package object
+
+import "bytes"
+
+const (
+ signatureTypeUnknown signatureType = iota
+ signatureTypeOpenPGP
+ signatureTypeX509
+ signatureTypeSSH
+)
+
+var (
+ // openPGPSignatureFormat is the format of an OpenPGP signature.
+ openPGPSignatureFormat = signatureFormat{
+ []byte("-----BEGIN PGP SIGNATURE-----"),
+ []byte("-----BEGIN PGP MESSAGE-----"),
+ }
+ // x509SignatureFormat is the format of an X509 signature, which is
+ // a PKCS#7 (S/MIME) signature.
+ x509SignatureFormat = signatureFormat{
+ []byte("-----BEGIN CERTIFICATE-----"),
+ }
+
+ // sshSignatureFormat is the format of an SSH signature.
+ sshSignatureFormat = signatureFormat{
+ []byte("-----BEGIN SSH SIGNATURE-----"),
+ }
+)
+
+var (
+ // knownSignatureFormats is a map of known signature formats, indexed by
+ // their signatureType.
+ knownSignatureFormats = map[signatureType]signatureFormat{
+ signatureTypeOpenPGP: openPGPSignatureFormat,
+ signatureTypeX509: x509SignatureFormat,
+ signatureTypeSSH: sshSignatureFormat,
+ }
+)
+
+// signatureType represents the type of the signature.
+type signatureType int8
+
+// signatureFormat represents the beginning of a signature.
+type signatureFormat [][]byte
+
+// typeForSignature returns the type of the signature based on its format.
+func typeForSignature(b []byte) signatureType {
+ for t, i := range knownSignatureFormats {
+ for _, begin := range i {
+ if bytes.HasPrefix(b, begin) {
+ return t
+ }
+ }
+ }
+ return signatureTypeUnknown
+}
+
+// parseSignedBytes returns the position of the last signature block found in
+// the given bytes. If no signature block is found, it returns -1.
+//
+// When multiple signature blocks are found, the position of the last one is
+// returned. Any tailing bytes after this signature block start should be
+// considered part of the signature.
+//
+// Given this, it would be safe to use the returned position to split the bytes
+// into two parts: the first part containing the message, the second part
+// containing the signature.
+//
+// Example:
+//
+// message := []byte(`Message with signature
+//
+// -----BEGIN SSH SIGNATURE-----
+// ...`)
+//
+// var signature string
+// if pos, _ := parseSignedBytes(message); pos != -1 {
+// signature = string(message[pos:])
+// message = message[:pos]
+// }
+//
+// This logic is on par with git's gpg-interface.c:parse_signed_buffer().
+// https://github.com/git/git/blob/7c2ef319c52c4997256f5807564523dfd4acdfc7/gpg-interface.c#L668
+func parseSignedBytes(b []byte) (int, signatureType) {
+ var n, match = 0, -1
+ var t signatureType
+ for n < len(b) {
+ var i = b[n:]
+ if st := typeForSignature(i); st != signatureTypeUnknown {
+ match = n
+ t = st
+ }
+ if eol := bytes.IndexByte(i, '\n'); eol >= 0 {
+ n += eol + 1
+ continue
+ }
+ // If we reach this point, we've reached the end.
+ break
+ }
+ return match, t
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/tag.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/tag.go
new file mode 100644
index 00000000..cf46c08e
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/tag.go
@@ -0,0 +1,330 @@
+package object
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+
+ "github.com/ProtonMail/go-crypto/openpgp"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+// Tag represents an annotated tag object. It points to a single git object of
+// any type, but tags typically are applied to commit or blob objects. It
+// provides a reference that associates the target with a tag name. It also
+// contains meta-information about the tag, including the tagger, tag date and
+// message.
+//
+// Note that this is not used for lightweight tags.
+//
+// https://git-scm.com/book/en/v2/Git-Internals-Git-References#Tags
+type Tag struct {
+ // Hash of the tag.
+ Hash plumbing.Hash
+ // Name of the tag.
+ Name string
+ // Tagger is the one who created the tag.
+ Tagger Signature
+ // Message is an arbitrary text message.
+ Message string
+ // PGPSignature is the PGP signature of the tag.
+ PGPSignature string
+ // TargetType is the object type of the target.
+ TargetType plumbing.ObjectType
+ // Target is the hash of the target object.
+ Target plumbing.Hash
+
+ s storer.EncodedObjectStorer
+}
+
+// GetTag gets a tag from an object storer and decodes it.
+func GetTag(s storer.EncodedObjectStorer, h plumbing.Hash) (*Tag, error) {
+ o, err := s.EncodedObject(plumbing.TagObject, h)
+ if err != nil {
+ return nil, err
+ }
+
+ return DecodeTag(s, o)
+}
+
+// DecodeTag decodes an encoded object into a *Commit and associates it to the
+// given object storer.
+func DecodeTag(s storer.EncodedObjectStorer, o plumbing.EncodedObject) (*Tag, error) {
+ t := &Tag{s: s}
+ if err := t.Decode(o); err != nil {
+ return nil, err
+ }
+
+ return t, nil
+}
+
+// ID returns the object ID of the tag, not the object that the tag references.
+// The returned value will always match the current value of Tag.Hash.
+//
+// ID is present to fulfill the Object interface.
+func (t *Tag) ID() plumbing.Hash {
+ return t.Hash
+}
+
+// Type returns the type of object. It always returns plumbing.TagObject.
+//
+// Type is present to fulfill the Object interface.
+func (t *Tag) Type() plumbing.ObjectType {
+ return plumbing.TagObject
+}
+
+// Decode transforms a plumbing.EncodedObject into a Tag struct.
+func (t *Tag) Decode(o plumbing.EncodedObject) (err error) {
+ if o.Type() != plumbing.TagObject {
+ return ErrUnsupportedObject
+ }
+
+ t.Hash = o.Hash()
+
+ reader, err := o.Reader()
+ if err != nil {
+ return err
+ }
+ defer ioutil.CheckClose(reader, &err)
+
+ r := sync.GetBufioReader(reader)
+ defer sync.PutBufioReader(r)
+
+ for {
+ var line []byte
+ line, err = r.ReadBytes('\n')
+ if err != nil && err != io.EOF {
+ return err
+ }
+
+ line = bytes.TrimSpace(line)
+ if len(line) == 0 {
+ break // Start of message
+ }
+
+ split := bytes.SplitN(line, []byte{' '}, 2)
+ switch string(split[0]) {
+ case "object":
+ t.Target = plumbing.NewHash(string(split[1]))
+ case "type":
+ t.TargetType, err = plumbing.ParseObjectType(string(split[1]))
+ if err != nil {
+ return err
+ }
+ case "tag":
+ t.Name = string(split[1])
+ case "tagger":
+ t.Tagger.Decode(split[1])
+ }
+
+ if err == io.EOF {
+ return nil
+ }
+ }
+
+ data, err := io.ReadAll(r)
+ if err != nil {
+ return err
+ }
+ if sm, _ := parseSignedBytes(data); sm >= 0 {
+ t.PGPSignature = string(data[sm:])
+ data = data[:sm]
+ }
+ t.Message = string(data)
+
+ return nil
+}
+
+// Encode transforms a Tag into a plumbing.EncodedObject.
+func (t *Tag) Encode(o plumbing.EncodedObject) error {
+ return t.encode(o, true)
+}
+
+// EncodeWithoutSignature export a Tag into a plumbing.EncodedObject without the signature (correspond to the payload of the PGP signature).
+func (t *Tag) EncodeWithoutSignature(o plumbing.EncodedObject) error {
+ return t.encode(o, false)
+}
+
+func (t *Tag) encode(o plumbing.EncodedObject, includeSig bool) (err error) {
+ o.SetType(plumbing.TagObject)
+ w, err := o.Writer()
+ if err != nil {
+ return err
+ }
+ defer ioutil.CheckClose(w, &err)
+
+ if _, err = fmt.Fprintf(w,
+ "object %s\ntype %s\ntag %s\ntagger ",
+ t.Target.String(), t.TargetType.Bytes(), t.Name); err != nil {
+ return err
+ }
+
+ if err = t.Tagger.Encode(w); err != nil {
+ return err
+ }
+
+ if _, err = fmt.Fprint(w, "\n\n"); err != nil {
+ return err
+ }
+
+ if _, err = fmt.Fprint(w, t.Message); err != nil {
+ return err
+ }
+
+ // Note that this is highly sensitive to what it sent along in the message.
+ // Message *always* needs to end with a newline, or else the message and the
+ // signature will be concatenated into a corrupt object. Since this is a
+ // lower-level method, we assume you know what you are doing and have already
+ // done the needful on the message in the caller.
+ if includeSig {
+ if _, err = fmt.Fprint(w, t.PGPSignature); err != nil {
+ return err
+ }
+ }
+
+ return err
+}
+
+// Commit returns the commit pointed to by the tag. If the tag points to a
+// different type of object ErrUnsupportedObject will be returned.
+func (t *Tag) Commit() (*Commit, error) {
+ if t.TargetType != plumbing.CommitObject {
+ return nil, ErrUnsupportedObject
+ }
+
+ o, err := t.s.EncodedObject(plumbing.CommitObject, t.Target)
+ if err != nil {
+ return nil, err
+ }
+
+ return DecodeCommit(t.s, o)
+}
+
+// Tree returns the tree pointed to by the tag. If the tag points to a commit
+// object the tree of that commit will be returned. If the tag does not point
+// to a commit or tree object ErrUnsupportedObject will be returned.
+func (t *Tag) Tree() (*Tree, error) {
+ switch t.TargetType {
+ case plumbing.CommitObject:
+ c, err := t.Commit()
+ if err != nil {
+ return nil, err
+ }
+
+ return c.Tree()
+ case plumbing.TreeObject:
+ return GetTree(t.s, t.Target)
+ default:
+ return nil, ErrUnsupportedObject
+ }
+}
+
+// Blob returns the blob pointed to by the tag. If the tag points to a
+// different type of object ErrUnsupportedObject will be returned.
+func (t *Tag) Blob() (*Blob, error) {
+ if t.TargetType != plumbing.BlobObject {
+ return nil, ErrUnsupportedObject
+ }
+
+ return GetBlob(t.s, t.Target)
+}
+
+// Object returns the object pointed to by the tag.
+func (t *Tag) Object() (Object, error) {
+ o, err := t.s.EncodedObject(t.TargetType, t.Target)
+ if err != nil {
+ return nil, err
+ }
+
+ return DecodeObject(t.s, o)
+}
+
+// String returns the meta information contained in the tag as a formatted
+// string.
+func (t *Tag) String() string {
+ obj, _ := t.Object()
+
+ return fmt.Sprintf(
+ "%s %s\nTagger: %s\nDate: %s\n\n%s\n%s",
+ plumbing.TagObject, t.Name, t.Tagger.String(), t.Tagger.When.Format(DateFormat),
+ t.Message, objectAsString(obj),
+ )
+}
+
+// Verify performs PGP verification of the tag with a provided armored
+// keyring and returns openpgp.Entity associated with verifying key on success.
+func (t *Tag) Verify(armoredKeyRing string) (*openpgp.Entity, error) {
+ keyRingReader := strings.NewReader(armoredKeyRing)
+ keyring, err := openpgp.ReadArmoredKeyRing(keyRingReader)
+ if err != nil {
+ return nil, err
+ }
+
+ // Extract signature.
+ signature := strings.NewReader(t.PGPSignature)
+
+ encoded := &plumbing.MemoryObject{}
+ // Encode tag components, excluding signature and get a reader object.
+ if err := t.EncodeWithoutSignature(encoded); err != nil {
+ return nil, err
+ }
+ er, err := encoded.Reader()
+ if err != nil {
+ return nil, err
+ }
+
+ return openpgp.CheckArmoredDetachedSignature(keyring, er, signature, nil)
+}
+
+// TagIter provides an iterator for a set of tags.
+type TagIter struct {
+ storer.EncodedObjectIter
+ s storer.EncodedObjectStorer
+}
+
+// NewTagIter takes a storer.EncodedObjectStorer and a
+// storer.EncodedObjectIter and returns a *TagIter that iterates over all
+// tags contained in the storer.EncodedObjectIter.
+//
+// Any non-tag object returned by the storer.EncodedObjectIter is skipped.
+func NewTagIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *TagIter {
+ return &TagIter{iter, s}
+}
+
+// Next moves the iterator to the next tag and returns a pointer to it. If
+// there are no more tags, it returns io.EOF.
+func (iter *TagIter) Next() (*Tag, error) {
+ obj, err := iter.EncodedObjectIter.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ return DecodeTag(iter.s, obj)
+}
+
+// ForEach call the cb function for each tag contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *TagIter) ForEach(cb func(*Tag) error) error {
+ return iter.EncodedObjectIter.ForEach(func(obj plumbing.EncodedObject) error {
+ t, err := DecodeTag(iter.s, obj)
+ if err != nil {
+ return err
+ }
+
+ return cb(t)
+ })
+}
+
+func objectAsString(obj Object) string {
+ switch o := obj.(type) {
+ case *Commit:
+ return o.String()
+ default:
+ return ""
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/tree.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/tree.go
new file mode 100644
index 00000000..0fd0e513
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/tree.go
@@ -0,0 +1,557 @@
+package object
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "path"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+const (
+ maxTreeDepth = 1024
+ startingStackSize = 8
+)
+
+// New errors defined by this package.
+var (
+ ErrMaxTreeDepth = errors.New("maximum tree depth exceeded")
+ ErrFileNotFound = errors.New("file not found")
+ ErrDirectoryNotFound = errors.New("directory not found")
+ ErrEntryNotFound = errors.New("entry not found")
+ ErrEntriesNotSorted = errors.New("entries in tree are not sorted")
+)
+
+// Tree is basically like a directory - it references a bunch of other trees
+// and/or blobs (i.e. files and sub-directories)
+type Tree struct {
+ Entries []TreeEntry
+ Hash plumbing.Hash
+
+ s storer.EncodedObjectStorer
+ m map[string]*TreeEntry
+ t map[string]*Tree // tree path cache
+}
+
+// GetTree gets a tree from an object storer and decodes it.
+func GetTree(s storer.EncodedObjectStorer, h plumbing.Hash) (*Tree, error) {
+ o, err := s.EncodedObject(plumbing.TreeObject, h)
+ if err != nil {
+ return nil, err
+ }
+
+ return DecodeTree(s, o)
+}
+
+// DecodeTree decodes an encoded object into a *Tree and associates it to the
+// given object storer.
+func DecodeTree(s storer.EncodedObjectStorer, o plumbing.EncodedObject) (*Tree, error) {
+ t := &Tree{s: s}
+ if err := t.Decode(o); err != nil {
+ return nil, err
+ }
+
+ return t, nil
+}
+
+// TreeEntry represents a file
+type TreeEntry struct {
+ Name string
+ Mode filemode.FileMode
+ Hash plumbing.Hash
+}
+
+// File returns the hash of the file identified by the `path` argument.
+// The path is interpreted as relative to the tree receiver.
+func (t *Tree) File(path string) (*File, error) {
+ e, err := t.FindEntry(path)
+ if err != nil {
+ return nil, ErrFileNotFound
+ }
+
+ blob, err := GetBlob(t.s, e.Hash)
+ if err != nil {
+ if err == plumbing.ErrObjectNotFound {
+ return nil, ErrFileNotFound
+ }
+ return nil, err
+ }
+
+ return NewFile(path, e.Mode, blob), nil
+}
+
+// Size returns the plaintext size of an object, without reading it
+// into memory.
+func (t *Tree) Size(path string) (int64, error) {
+ e, err := t.FindEntry(path)
+ if err != nil {
+ return 0, ErrEntryNotFound
+ }
+
+ return t.s.EncodedObjectSize(e.Hash)
+}
+
+// Tree returns the tree identified by the `path` argument.
+// The path is interpreted as relative to the tree receiver.
+func (t *Tree) Tree(path string) (*Tree, error) {
+ e, err := t.FindEntry(path)
+ if err != nil {
+ return nil, ErrDirectoryNotFound
+ }
+
+ tree, err := GetTree(t.s, e.Hash)
+ if err == plumbing.ErrObjectNotFound {
+ return nil, ErrDirectoryNotFound
+ }
+
+ return tree, err
+}
+
+// TreeEntryFile returns the *File for a given *TreeEntry.
+func (t *Tree) TreeEntryFile(e *TreeEntry) (*File, error) {
+ blob, err := GetBlob(t.s, e.Hash)
+ if err != nil {
+ return nil, err
+ }
+
+ return NewFile(e.Name, e.Mode, blob), nil
+}
+
+// FindEntry search a TreeEntry in this tree or any subtree.
+func (t *Tree) FindEntry(path string) (*TreeEntry, error) {
+ if t.t == nil {
+ t.t = make(map[string]*Tree)
+ }
+
+ pathParts := strings.Split(path, "/")
+ startingTree := t
+ pathCurrent := ""
+
+ // search for the longest path in the tree path cache
+ for i := len(pathParts) - 1; i > 1; i-- {
+ path := filepath.Join(pathParts[:i]...)
+
+ tree, ok := t.t[path]
+ if ok {
+ startingTree = tree
+ pathParts = pathParts[i:]
+ pathCurrent = path
+
+ break
+ }
+ }
+
+ var tree *Tree
+ var err error
+ for tree = startingTree; len(pathParts) > 1; pathParts = pathParts[1:] {
+ if tree, err = tree.dir(pathParts[0]); err != nil {
+ return nil, err
+ }
+
+ pathCurrent = filepath.Join(pathCurrent, pathParts[0])
+ t.t[pathCurrent] = tree
+ }
+
+ return tree.entry(pathParts[0])
+}
+
+func (t *Tree) dir(baseName string) (*Tree, error) {
+ entry, err := t.entry(baseName)
+ if err != nil {
+ return nil, ErrDirectoryNotFound
+ }
+
+ obj, err := t.s.EncodedObject(plumbing.TreeObject, entry.Hash)
+ if err != nil {
+ return nil, err
+ }
+
+ tree := &Tree{s: t.s}
+ err = tree.Decode(obj)
+
+ return tree, err
+}
+
+func (t *Tree) entry(baseName string) (*TreeEntry, error) {
+ if t.m == nil {
+ t.buildMap()
+ }
+
+ entry, ok := t.m[baseName]
+ if !ok {
+ return nil, ErrEntryNotFound
+ }
+
+ return entry, nil
+}
+
+// Files returns a FileIter allowing to iterate over the Tree
+func (t *Tree) Files() *FileIter {
+ return NewFileIter(t.s, t)
+}
+
+// ID returns the object ID of the tree. The returned value will always match
+// the current value of Tree.Hash.
+//
+// ID is present to fulfill the Object interface.
+func (t *Tree) ID() plumbing.Hash {
+ return t.Hash
+}
+
+// Type returns the type of object. It always returns plumbing.TreeObject.
+func (t *Tree) Type() plumbing.ObjectType {
+ return plumbing.TreeObject
+}
+
+// Decode transform an plumbing.EncodedObject into a Tree struct
+func (t *Tree) Decode(o plumbing.EncodedObject) (err error) {
+ if o.Type() != plumbing.TreeObject {
+ return ErrUnsupportedObject
+ }
+
+ t.Hash = o.Hash()
+ if o.Size() == 0 {
+ return nil
+ }
+
+ t.Entries = nil
+ t.m = nil
+
+ reader, err := o.Reader()
+ if err != nil {
+ return err
+ }
+ defer ioutil.CheckClose(reader, &err)
+
+ r := sync.GetBufioReader(reader)
+ defer sync.PutBufioReader(r)
+
+ for {
+ str, err := r.ReadString(' ')
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+
+ return err
+ }
+ str = str[:len(str)-1] // strip last byte (' ')
+
+ mode, err := filemode.New(str)
+ if err != nil {
+ return err
+ }
+
+ name, err := r.ReadString(0)
+ if err != nil && err != io.EOF {
+ return err
+ }
+
+ var hash plumbing.Hash
+ if _, err = io.ReadFull(r, hash[:]); err != nil {
+ return err
+ }
+
+ baseName := name[:len(name)-1]
+ t.Entries = append(t.Entries, TreeEntry{
+ Hash: hash,
+ Mode: mode,
+ Name: baseName,
+ })
+ }
+
+ return nil
+}
+
+type TreeEntrySorter []TreeEntry
+
+func (s TreeEntrySorter) Len() int {
+ return len(s)
+}
+
+func (s TreeEntrySorter) Less(i, j int) bool {
+ name1 := s[i].Name
+ name2 := s[j].Name
+ if s[i].Mode == filemode.Dir {
+ name1 += "/"
+ }
+ if s[j].Mode == filemode.Dir {
+ name2 += "/"
+ }
+ return name1 < name2
+}
+
+func (s TreeEntrySorter) Swap(i, j int) {
+ s[i], s[j] = s[j], s[i]
+}
+
+// Encode transforms a Tree into a plumbing.EncodedObject.
+func (t *Tree) Encode(o plumbing.EncodedObject) (err error) {
+ o.SetType(plumbing.TreeObject)
+ w, err := o.Writer()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(w, &err)
+
+ if !sort.IsSorted(TreeEntrySorter(t.Entries)) {
+ return ErrEntriesNotSorted
+ }
+
+ for _, entry := range t.Entries {
+ if strings.IndexByte(entry.Name, 0) != -1 {
+ return fmt.Errorf("malformed filename %q", entry.Name)
+ }
+ if _, err = fmt.Fprintf(w, "%o %s", entry.Mode, entry.Name); err != nil {
+ return err
+ }
+
+ if _, err = w.Write([]byte{0x00}); err != nil {
+ return err
+ }
+
+ if _, err = w.Write(entry.Hash[:]); err != nil {
+ return err
+ }
+ }
+
+ return err
+}
+
+func (t *Tree) buildMap() {
+ t.m = make(map[string]*TreeEntry)
+ for i := 0; i < len(t.Entries); i++ {
+ t.m[t.Entries[i].Name] = &t.Entries[i]
+ }
+}
+
+// Diff returns a list of changes between this tree and the provided one
+func (t *Tree) Diff(to *Tree) (Changes, error) {
+ return t.DiffContext(context.Background(), to)
+}
+
+// DiffContext returns a list of changes between this tree and the provided one
+// Error will be returned if context expires. Provided context must be non nil.
+//
+// NOTE: Since version 5.1.0 the renames are correctly handled, the settings
+// used are the recommended options DefaultDiffTreeOptions.
+func (t *Tree) DiffContext(ctx context.Context, to *Tree) (Changes, error) {
+ return DiffTreeWithOptions(ctx, t, to, DefaultDiffTreeOptions)
+}
+
+// Patch returns a slice of Patch objects with all the changes between trees
+// in chunks. This representation can be used to create several diff outputs.
+func (t *Tree) Patch(to *Tree) (*Patch, error) {
+ return t.PatchContext(context.Background(), to)
+}
+
+// PatchContext returns a slice of Patch objects with all the changes between
+// trees in chunks. This representation can be used to create several diff
+// outputs. If context expires, an error will be returned. Provided context must
+// be non-nil.
+//
+// NOTE: Since version 5.1.0 the renames are correctly handled, the settings
+// used are the recommended options DefaultDiffTreeOptions.
+func (t *Tree) PatchContext(ctx context.Context, to *Tree) (*Patch, error) {
+ changes, err := t.DiffContext(ctx, to)
+ if err != nil {
+ return nil, err
+ }
+
+ return changes.PatchContext(ctx)
+}
+
+// treeEntryIter facilitates iterating through the TreeEntry objects in a Tree.
+type treeEntryIter struct {
+ t *Tree
+ pos int
+}
+
+func (iter *treeEntryIter) Next() (TreeEntry, error) {
+ if iter.pos >= len(iter.t.Entries) {
+ return TreeEntry{}, io.EOF
+ }
+ iter.pos++
+ return iter.t.Entries[iter.pos-1], nil
+}
+
+// TreeWalker provides a means of walking through all of the entries in a Tree.
+type TreeWalker struct {
+ stack []*treeEntryIter
+ base string
+ recursive bool
+ seen map[plumbing.Hash]bool
+
+ s storer.EncodedObjectStorer
+ t *Tree
+}
+
+// NewTreeWalker returns a new TreeWalker for the given tree.
+//
+// It is the caller's responsibility to call Close() when finished with the
+// tree walker.
+func NewTreeWalker(t *Tree, recursive bool, seen map[plumbing.Hash]bool) *TreeWalker {
+ stack := make([]*treeEntryIter, 0, startingStackSize)
+ stack = append(stack, &treeEntryIter{t, 0})
+
+ return &TreeWalker{
+ stack: stack,
+ recursive: recursive,
+ seen: seen,
+
+ s: t.s,
+ t: t,
+ }
+}
+
+// Next returns the next object from the tree. Objects are returned in order
+// and subtrees are included. After the last object has been returned further
+// calls to Next() will return io.EOF.
+//
+// In the current implementation any objects which cannot be found in the
+// underlying repository will be skipped automatically. It is possible that this
+// may change in future versions.
+func (w *TreeWalker) Next() (name string, entry TreeEntry, err error) {
+ var obj *Tree
+ for {
+ current := len(w.stack) - 1
+ if current < 0 {
+ // Nothing left on the stack so we're finished
+ err = io.EOF
+ return
+ }
+
+ if current > maxTreeDepth {
+ // We're probably following bad data or some self-referencing tree
+ err = ErrMaxTreeDepth
+ return
+ }
+
+ entry, err = w.stack[current].Next()
+ if err == io.EOF {
+ // Finished with the current tree, move back up to the parent
+ w.stack = w.stack[:current]
+ w.base, _ = path.Split(w.base)
+ w.base = strings.TrimSuffix(w.base, "/")
+ continue
+ }
+
+ if err != nil {
+ return
+ }
+
+ if w.seen[entry.Hash] {
+ continue
+ }
+
+ if entry.Mode == filemode.Dir {
+ obj, err = GetTree(w.s, entry.Hash)
+ }
+
+ name = simpleJoin(w.base, entry.Name)
+
+ if err != nil {
+ err = io.EOF
+ return
+ }
+
+ break
+ }
+
+ if !w.recursive {
+ return
+ }
+
+ if obj != nil {
+ w.stack = append(w.stack, &treeEntryIter{obj, 0})
+ w.base = simpleJoin(w.base, entry.Name)
+ }
+
+ return
+}
+
+// Tree returns the tree that the tree walker most recently operated on.
+func (w *TreeWalker) Tree() *Tree {
+ current := len(w.stack) - 1
+ if w.stack[current].pos == 0 {
+ current--
+ }
+
+ if current < 0 {
+ return nil
+ }
+
+ return w.stack[current].t
+}
+
+// Close releases any resources used by the TreeWalker.
+func (w *TreeWalker) Close() {
+ w.stack = nil
+}
+
+// TreeIter provides an iterator for a set of trees.
+type TreeIter struct {
+ storer.EncodedObjectIter
+ s storer.EncodedObjectStorer
+}
+
+// NewTreeIter takes a storer.EncodedObjectStorer and a
+// storer.EncodedObjectIter and returns a *TreeIter that iterates over all
+// tree contained in the storer.EncodedObjectIter.
+//
+// Any non-tree object returned by the storer.EncodedObjectIter is skipped.
+func NewTreeIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *TreeIter {
+ return &TreeIter{iter, s}
+}
+
+// Next moves the iterator to the next tree and returns a pointer to it. If
+// there are no more trees, it returns io.EOF.
+func (iter *TreeIter) Next() (*Tree, error) {
+ for {
+ obj, err := iter.EncodedObjectIter.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ if obj.Type() != plumbing.TreeObject {
+ continue
+ }
+
+ return DecodeTree(iter.s, obj)
+ }
+}
+
+// ForEach call the cb function for each tree contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *TreeIter) ForEach(cb func(*Tree) error) error {
+ return iter.EncodedObjectIter.ForEach(func(obj plumbing.EncodedObject) error {
+ if obj.Type() != plumbing.TreeObject {
+ return nil
+ }
+
+ t, err := DecodeTree(iter.s, obj)
+ if err != nil {
+ return err
+ }
+
+ return cb(t)
+ })
+}
+
+func simpleJoin(parent, child string) string {
+ if len(parent) > 0 {
+ return parent + "/" + child
+ }
+ return child
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/treenoder.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/treenoder.go
new file mode 100644
index 00000000..2adb6452
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/treenoder.go
@@ -0,0 +1,142 @@
+package object
+
+import (
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+// A treenoder is a helper type that wraps git trees into merkletrie
+// noders.
+//
+// As a merkletrie noder doesn't understand the concept of modes (e.g.
+// file permissions), the treenoder includes the mode of the git tree in
+// the hash, so changes in the modes will be detected as modifications
+// to the file contents by the merkletrie difftree algorithm. This is
+// consistent with how the "git diff-tree" command works.
+type treeNoder struct {
+ parent *Tree // the root node is its own parent
+ name string // empty string for the root node
+ mode filemode.FileMode
+ hash plumbing.Hash
+ children []noder.Noder // memoized
+}
+
+// NewTreeRootNode returns the root node of a Tree
+func NewTreeRootNode(t *Tree) noder.Noder {
+ if t == nil {
+ return &treeNoder{}
+ }
+
+ return &treeNoder{
+ parent: t,
+ name: "",
+ mode: filemode.Dir,
+ hash: t.Hash,
+ }
+}
+
+func (t *treeNoder) Skip() bool {
+ return false
+}
+
+func (t *treeNoder) isRoot() bool {
+ return t.name == ""
+}
+
+func (t *treeNoder) String() string {
+ return "treeNoder <" + t.name + ">"
+}
+
+func (t *treeNoder) Hash() []byte {
+ if t.mode == filemode.Deprecated {
+ return append(t.hash[:], filemode.Regular.Bytes()...)
+ }
+ return append(t.hash[:], t.mode.Bytes()...)
+}
+
+func (t *treeNoder) Name() string {
+ return t.name
+}
+
+func (t *treeNoder) IsDir() bool {
+ return t.mode == filemode.Dir
+}
+
+// Children will return the children of a treenoder as treenoders,
+// building them from the children of the wrapped git tree.
+func (t *treeNoder) Children() ([]noder.Noder, error) {
+ if t.mode != filemode.Dir {
+ return noder.NoChildren, nil
+ }
+
+ // children are memoized for efficiency
+ if t.children != nil {
+ return t.children, nil
+ }
+
+ // the parent of the returned children will be ourself as a tree if
+ // we are a not the root treenoder. The root is special as it
+ // is is own parent.
+ parent := t.parent
+ if !t.isRoot() {
+ var err error
+ if parent, err = t.parent.Tree(t.name); err != nil {
+ return nil, err
+ }
+ }
+
+ var err error
+ t.children, err = transformChildren(parent)
+ return t.children, err
+}
+
+// Returns the children of a tree as treenoders.
+// Efficiency is key here.
+func transformChildren(t *Tree) ([]noder.Noder, error) {
+ var err error
+ var e TreeEntry
+
+ // there will be more tree entries than children in the tree,
+ // due to submodules and empty directories, but I think it is still
+ // worth it to pre-allocate the whole array now, even if sometimes
+ // is bigger than needed.
+ ret := make([]noder.Noder, 0, len(t.Entries))
+
+ walker := NewTreeWalker(t, false, nil) // don't recurse
+ // don't defer walker.Close() for efficiency reasons.
+ for {
+ _, e, err = walker.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ walker.Close()
+ return nil, err
+ }
+
+ ret = append(ret, &treeNoder{
+ parent: t,
+ name: e.Name,
+ mode: e.Mode,
+ hash: e.Hash,
+ })
+ }
+ walker.Close()
+
+ return ret, nil
+}
+
+// len(t.tree.Entries) != the number of elements walked by treewalker
+// for some reason because of empty directories, submodules, etc, so we
+// have to walk here.
+func (t *treeNoder) NumChildren() (int, error) {
+ children, err := t.Children()
+ if err != nil {
+ return 0, err
+ }
+
+ return len(children), nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs.go
new file mode 100644
index 00000000..f93ad304
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs.go
@@ -0,0 +1,211 @@
+package packp
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/storage/memory"
+)
+
+// AdvRefs values represent the information transmitted on an
+// advertised-refs message. Values from this type are not zero-value
+// safe, use the New function instead.
+type AdvRefs struct {
+ // Prefix stores prefix payloads.
+ //
+ // When using this message over (smart) HTTP, you have to add a pktline
+ // before the whole thing with the following payload:
+ //
+ // '# service=$servicename" LF
+ //
+ // Moreover, some (all) git HTTP smart servers will send a flush-pkt
+ // just after the first pkt-line.
+ //
+ // To accommodate both situations, the Prefix field allow you to store
+ // any data you want to send before the actual pktlines. It will also
+ // be filled up with whatever is found on the line.
+ Prefix [][]byte
+ // Head stores the resolved HEAD reference if present.
+ // This can be present with git-upload-pack, not with git-receive-pack.
+ Head *plumbing.Hash
+ // Capabilities are the capabilities.
+ Capabilities *capability.List
+ // References are the hash references.
+ References map[string]plumbing.Hash
+ // Peeled are the peeled hash references.
+ Peeled map[string]plumbing.Hash
+ // Shallows are the shallow object ids.
+ Shallows []plumbing.Hash
+}
+
+// NewAdvRefs returns a pointer to a new AdvRefs value, ready to be used.
+func NewAdvRefs() *AdvRefs {
+ return &AdvRefs{
+ Prefix: [][]byte{},
+ Capabilities: capability.NewList(),
+ References: make(map[string]plumbing.Hash),
+ Peeled: make(map[string]plumbing.Hash),
+ Shallows: []plumbing.Hash{},
+ }
+}
+
+func (a *AdvRefs) AddReference(r *plumbing.Reference) error {
+ switch r.Type() {
+ case plumbing.SymbolicReference:
+ v := fmt.Sprintf("%s:%s", r.Name().String(), r.Target().String())
+ return a.Capabilities.Add(capability.SymRef, v)
+ case plumbing.HashReference:
+ a.References[r.Name().String()] = r.Hash()
+ default:
+ return plumbing.ErrInvalidType
+ }
+
+ return nil
+}
+
+func (a *AdvRefs) AllReferences() (memory.ReferenceStorage, error) {
+ s := memory.ReferenceStorage{}
+ if err := a.addRefs(s); err != nil {
+ return s, plumbing.NewUnexpectedError(err)
+ }
+
+ return s, nil
+}
+
+func (a *AdvRefs) addRefs(s storer.ReferenceStorer) error {
+ for name, hash := range a.References {
+ ref := plumbing.NewReferenceFromStrings(name, hash.String())
+ if err := s.SetReference(ref); err != nil {
+ return err
+ }
+ }
+
+ if a.supportSymrefs() {
+ return a.addSymbolicRefs(s)
+ }
+
+ return a.resolveHead(s)
+}
+
+// If the server does not support symrefs capability,
+// we need to guess the reference where HEAD is pointing to.
+//
+// Git versions prior to 1.8.4.3 has an special procedure to get
+// the reference where is pointing to HEAD:
+// - Check if a reference called master exists. If exists and it
+// has the same hash as HEAD hash, we can say that HEAD is pointing to master
+// - If master does not exists or does not have the same hash as HEAD,
+// order references and check in that order if that reference has the same
+// hash than HEAD. If yes, set HEAD pointing to that branch hash
+// - If no reference is found, throw an error
+func (a *AdvRefs) resolveHead(s storer.ReferenceStorer) error {
+ if a.Head == nil {
+ return nil
+ }
+
+ ref, err := s.Reference(plumbing.Master)
+
+ // check first if HEAD is pointing to master
+ if err == nil {
+ ok, err := a.createHeadIfCorrectReference(ref, s)
+ if err != nil {
+ return err
+ }
+
+ if ok {
+ return nil
+ }
+ }
+
+ if err != nil && err != plumbing.ErrReferenceNotFound {
+ return err
+ }
+
+ // From here we are trying to guess the branch that HEAD is pointing
+ refIter, err := s.IterReferences()
+ if err != nil {
+ return err
+ }
+
+ var refNames []string
+ err = refIter.ForEach(func(r *plumbing.Reference) error {
+ refNames = append(refNames, string(r.Name()))
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ sort.Strings(refNames)
+
+ var headSet bool
+ for _, refName := range refNames {
+ ref, err := s.Reference(plumbing.ReferenceName(refName))
+ if err != nil {
+ return err
+ }
+ ok, err := a.createHeadIfCorrectReference(ref, s)
+ if err != nil {
+ return err
+ }
+ if ok {
+ headSet = true
+ break
+ }
+ }
+
+ if !headSet {
+ return plumbing.ErrReferenceNotFound
+ }
+
+ return nil
+}
+
+func (a *AdvRefs) createHeadIfCorrectReference(
+ reference *plumbing.Reference,
+ s storer.ReferenceStorer) (bool, error) {
+ if reference.Hash() == *a.Head {
+ headRef := plumbing.NewSymbolicReference(plumbing.HEAD, reference.Name())
+ if err := s.SetReference(headRef); err != nil {
+ return false, err
+ }
+
+ return true, nil
+ }
+
+ return false, nil
+}
+
+func (a *AdvRefs) addSymbolicRefs(s storer.ReferenceStorer) error {
+ for _, symref := range a.Capabilities.Get(capability.SymRef) {
+ chunks := strings.Split(symref, ":")
+ if len(chunks) != 2 {
+ err := fmt.Errorf("bad number of `:` in symref value (%q)", symref)
+ return plumbing.NewUnexpectedError(err)
+ }
+ name := plumbing.ReferenceName(chunks[0])
+ target := plumbing.ReferenceName(chunks[1])
+ ref := plumbing.NewSymbolicReference(name, target)
+ if err := s.SetReference(ref); err != nil {
+ return nil
+ }
+ }
+
+ return nil
+}
+
+func (a *AdvRefs) supportSymrefs() bool {
+ return a.Capabilities.Supports(capability.SymRef)
+}
+
+// IsEmpty returns true if doesn't contain any reference.
+func (a *AdvRefs) IsEmpty() bool {
+ return a.Head == nil &&
+ len(a.References) == 0 &&
+ len(a.Peeled) == 0 &&
+ len(a.Shallows) == 0
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_decode.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_decode.go
new file mode 100644
index 00000000..f8d26a28
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_decode.go
@@ -0,0 +1,289 @@
+package packp
+
+import (
+ "bytes"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+// Decode reads the next advertised-refs message form its input and
+// stores it in the AdvRefs.
+func (a *AdvRefs) Decode(r io.Reader) error {
+ d := newAdvRefsDecoder(r)
+ return d.Decode(a)
+}
+
+type advRefsDecoder struct {
+ s *pktline.Scanner // a pkt-line scanner from the input stream
+ line []byte // current pkt-line contents, use parser.nextLine() to make it advance
+ nLine int // current pkt-line number for debugging, begins at 1
+ hash plumbing.Hash // last hash read
+ err error // sticky error, use the parser.error() method to fill this out
+ data *AdvRefs // parsed data is stored here
+}
+
+var (
+ // ErrEmptyAdvRefs is returned by Decode if it gets an empty advertised
+ // references message.
+ ErrEmptyAdvRefs = errors.New("empty advertised-ref message")
+ // ErrEmptyInput is returned by Decode if the input is empty.
+ ErrEmptyInput = errors.New("empty input")
+)
+
+func newAdvRefsDecoder(r io.Reader) *advRefsDecoder {
+ return &advRefsDecoder{
+ s: pktline.NewScanner(r),
+ }
+}
+
+func (d *advRefsDecoder) Decode(v *AdvRefs) error {
+ d.data = v
+
+ for state := decodePrefix; state != nil; {
+ state = state(d)
+ }
+
+ return d.err
+}
+
+type decoderStateFn func(*advRefsDecoder) decoderStateFn
+
+// fills out the parser sticky error
+func (d *advRefsDecoder) error(format string, a ...interface{}) {
+ msg := fmt.Sprintf(
+ "pkt-line %d: %s", d.nLine,
+ fmt.Sprintf(format, a...),
+ )
+
+ d.err = NewErrUnexpectedData(msg, d.line)
+}
+
+// Reads a new pkt-line from the scanner, makes its payload available as
+// p.line and increments p.nLine. A successful invocation returns true,
+// otherwise, false is returned and the sticky error is filled out
+// accordingly. Trims eols at the end of the payloads.
+func (d *advRefsDecoder) nextLine() bool {
+ d.nLine++
+
+ if !d.s.Scan() {
+ if d.err = d.s.Err(); d.err != nil {
+ return false
+ }
+
+ if d.nLine == 1 {
+ d.err = ErrEmptyInput
+ return false
+ }
+
+ d.error("EOF")
+ return false
+ }
+
+ d.line = d.s.Bytes()
+ d.line = bytes.TrimSuffix(d.line, eol)
+
+ return true
+}
+
+// The HTTP smart prefix is often followed by a flush-pkt.
+func decodePrefix(d *advRefsDecoder) decoderStateFn {
+ if ok := d.nextLine(); !ok {
+ return nil
+ }
+
+ if !isPrefix(d.line) {
+ return decodeFirstHash
+ }
+
+ tmp := make([]byte, len(d.line))
+ copy(tmp, d.line)
+ d.data.Prefix = append(d.data.Prefix, tmp)
+ if ok := d.nextLine(); !ok {
+ return nil
+ }
+
+ if !isFlush(d.line) {
+ return decodeFirstHash
+ }
+
+ d.data.Prefix = append(d.data.Prefix, pktline.Flush)
+ if ok := d.nextLine(); !ok {
+ return nil
+ }
+
+ return decodeFirstHash
+}
+
+func isPrefix(payload []byte) bool {
+ return len(payload) > 0 && payload[0] == '#'
+}
+
+// If the first hash is zero, then a no-refs is coming. Otherwise, a
+// list-of-refs is coming, and the hash will be followed by the first
+// advertised ref.
+func decodeFirstHash(p *advRefsDecoder) decoderStateFn {
+ // If the repository is empty, we receive a flush here (HTTP).
+ if isFlush(p.line) {
+ p.err = ErrEmptyAdvRefs
+ return nil
+ }
+
+ // TODO: Use object-format (when available) for hash size. Git 2.41+
+ if len(p.line) < hashSize {
+ p.error("cannot read hash, pkt-line too short")
+ return nil
+ }
+
+ if _, err := hex.Decode(p.hash[:], p.line[:hashSize]); err != nil {
+ p.error("invalid hash text: %s", err)
+ return nil
+ }
+
+ p.line = p.line[hashSize:]
+
+ if p.hash.IsZero() {
+ return decodeSkipNoRefs
+ }
+
+ return decodeFirstRef
+}
+
+// Skips SP "capabilities^{}" NUL
+func decodeSkipNoRefs(p *advRefsDecoder) decoderStateFn {
+ if len(p.line) < len(noHeadMark) {
+ p.error("too short zero-id ref")
+ return nil
+ }
+
+ if !bytes.HasPrefix(p.line, noHeadMark) {
+ p.error("malformed zero-id ref")
+ return nil
+ }
+
+ p.line = p.line[len(noHeadMark):]
+
+ return decodeCaps
+}
+
+// decode the refname, expects SP refname NULL
+func decodeFirstRef(l *advRefsDecoder) decoderStateFn {
+ if len(l.line) < 3 {
+ l.error("line too short after hash")
+ return nil
+ }
+
+ if !bytes.HasPrefix(l.line, sp) {
+ l.error("no space after hash")
+ return nil
+ }
+ l.line = l.line[1:]
+
+ chunks := bytes.SplitN(l.line, null, 2)
+ if len(chunks) < 2 {
+ l.error("NULL not found")
+ return nil
+ }
+ ref := chunks[0]
+ l.line = chunks[1]
+
+ if bytes.Equal(ref, []byte(head)) {
+ l.data.Head = &l.hash
+ } else {
+ l.data.References[string(ref)] = l.hash
+ }
+
+ return decodeCaps
+}
+
+func decodeCaps(p *advRefsDecoder) decoderStateFn {
+ if err := p.data.Capabilities.Decode(p.line); err != nil {
+ p.error("invalid capabilities: %s", err)
+ return nil
+ }
+
+ return decodeOtherRefs
+}
+
+// The refs are either tips (obj-id SP refname) or a peeled (obj-id SP refname^{}).
+// If there are no refs, then there might be a shallow or flush-ptk.
+func decodeOtherRefs(p *advRefsDecoder) decoderStateFn {
+ if ok := p.nextLine(); !ok {
+ return nil
+ }
+
+ if bytes.HasPrefix(p.line, shallow) {
+ return decodeShallow
+ }
+
+ if len(p.line) == 0 {
+ return nil
+ }
+
+ saveTo := p.data.References
+ if bytes.HasSuffix(p.line, peeled) {
+ p.line = bytes.TrimSuffix(p.line, peeled)
+ saveTo = p.data.Peeled
+ }
+
+ ref, hash, err := readRef(p.line)
+ if err != nil {
+ p.error("%s", err)
+ return nil
+ }
+ saveTo[ref] = hash
+
+ return decodeOtherRefs
+}
+
+// Reads a ref-name
+func readRef(data []byte) (string, plumbing.Hash, error) {
+ chunks := bytes.Split(data, sp)
+ switch {
+ case len(chunks) == 1:
+ return "", plumbing.ZeroHash, fmt.Errorf("malformed ref data: no space was found")
+ case len(chunks) > 2:
+ return "", plumbing.ZeroHash, fmt.Errorf("malformed ref data: more than one space found")
+ default:
+ return string(chunks[1]), plumbing.NewHash(string(chunks[0])), nil
+ }
+}
+
+// Keeps reading shallows until a flush-pkt is found
+func decodeShallow(p *advRefsDecoder) decoderStateFn {
+ if !bytes.HasPrefix(p.line, shallow) {
+ p.error("malformed shallow prefix, found %q... instead", p.line[:len(shallow)])
+ return nil
+ }
+ p.line = bytes.TrimPrefix(p.line, shallow)
+
+ if len(p.line) != hashSize {
+ p.error(fmt.Sprintf(
+ "malformed shallow hash: wrong length, expected 40 bytes, read %d bytes",
+ len(p.line)))
+ return nil
+ }
+
+ text := p.line[:hashSize]
+ var h plumbing.Hash
+ if _, err := hex.Decode(h[:], text); err != nil {
+ p.error("invalid hash text: %s", err)
+ return nil
+ }
+
+ p.data.Shallows = append(p.data.Shallows, h)
+
+ if ok := p.nextLine(); !ok {
+ return nil
+ }
+
+ if len(p.line) == 0 {
+ return nil // successful parse of the advertised-refs message
+ }
+
+ return decodeShallow
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_encode.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_encode.go
new file mode 100644
index 00000000..fb9bd883
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/advrefs_encode.go
@@ -0,0 +1,176 @@
+package packp
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "sort"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+)
+
+// Encode writes the AdvRefs encoding to a writer.
+//
+// All the payloads will end with a newline character. Capabilities,
+// references and shallows are written in alphabetical order, except for
+// peeled references that always follow their corresponding references.
+func (a *AdvRefs) Encode(w io.Writer) error {
+ e := newAdvRefsEncoder(w)
+ return e.Encode(a)
+}
+
+type advRefsEncoder struct {
+ data *AdvRefs // data to encode
+ pe *pktline.Encoder // where to write the encoded data
+ firstRefName string // reference name to encode in the first pkt-line (HEAD if present)
+ firstRefHash plumbing.Hash // hash referenced to encode in the first pkt-line (HEAD if present)
+ sortedRefs []string // hash references to encode ordered by increasing order
+ err error // sticky error
+
+}
+
+func newAdvRefsEncoder(w io.Writer) *advRefsEncoder {
+ return &advRefsEncoder{
+ pe: pktline.NewEncoder(w),
+ }
+}
+
+func (e *advRefsEncoder) Encode(v *AdvRefs) error {
+ e.data = v
+ e.sortRefs()
+ e.setFirstRef()
+
+ for state := encodePrefix; state != nil; {
+ state = state(e)
+ }
+
+ return e.err
+}
+
+func (e *advRefsEncoder) sortRefs() {
+ if len(e.data.References) > 0 {
+ refs := make([]string, 0, len(e.data.References))
+ for refName := range e.data.References {
+ refs = append(refs, refName)
+ }
+
+ sort.Strings(refs)
+ e.sortedRefs = refs
+ }
+}
+
+func (e *advRefsEncoder) setFirstRef() {
+ if e.data.Head != nil {
+ e.firstRefName = head
+ e.firstRefHash = *e.data.Head
+ return
+ }
+
+ if len(e.sortedRefs) > 0 {
+ refName := e.sortedRefs[0]
+ e.firstRefName = refName
+ e.firstRefHash = e.data.References[refName]
+ }
+}
+
+type encoderStateFn func(*advRefsEncoder) encoderStateFn
+
+func encodePrefix(e *advRefsEncoder) encoderStateFn {
+ for _, p := range e.data.Prefix {
+ if bytes.Equal(p, pktline.Flush) {
+ if e.err = e.pe.Flush(); e.err != nil {
+ return nil
+ }
+ continue
+ }
+ if e.err = e.pe.Encodef("%s\n", string(p)); e.err != nil {
+ return nil
+ }
+ }
+
+ return encodeFirstLine
+}
+
+// Adds the first pkt-line payload: head hash, head ref and capabilities.
+// If HEAD ref is not found, the first reference ordered in increasing order will be used.
+// If there aren't HEAD neither refs, the first line will be "PKT-LINE(zero-id SP "capabilities^{}" NUL capability-list)".
+// See: https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt
+// See: https://github.com/git/git/blob/master/Documentation/technical/protocol-common.txt
+func encodeFirstLine(e *advRefsEncoder) encoderStateFn {
+ const formatFirstLine = "%s %s\x00%s\n"
+ var firstLine string
+ capabilities := formatCaps(e.data.Capabilities)
+
+ if e.firstRefName == "" {
+ firstLine = fmt.Sprintf(formatFirstLine, plumbing.ZeroHash.String(), "capabilities^{}", capabilities)
+ } else {
+ firstLine = fmt.Sprintf(formatFirstLine, e.firstRefHash.String(), e.firstRefName, capabilities)
+
+ }
+
+ if e.err = e.pe.EncodeString(firstLine); e.err != nil {
+ return nil
+ }
+
+ return encodeRefs
+}
+
+func formatCaps(c *capability.List) string {
+ if c == nil {
+ return ""
+ }
+
+ return c.String()
+}
+
+// Adds the (sorted) refs: hash SP refname EOL
+// and their peeled refs if any.
+func encodeRefs(e *advRefsEncoder) encoderStateFn {
+ for _, r := range e.sortedRefs {
+ if r == e.firstRefName {
+ continue
+ }
+
+ hash := e.data.References[r]
+ if e.err = e.pe.Encodef("%s %s\n", hash.String(), r); e.err != nil {
+ return nil
+ }
+
+ if hash, ok := e.data.Peeled[r]; ok {
+ if e.err = e.pe.Encodef("%s %s^{}\n", hash.String(), r); e.err != nil {
+ return nil
+ }
+ }
+ }
+
+ return encodeShallow
+}
+
+// Adds the (sorted) shallows: "shallow" SP hash EOL
+func encodeShallow(e *advRefsEncoder) encoderStateFn {
+ sorted := sortShallows(e.data.Shallows)
+ for _, hash := range sorted {
+ if e.err = e.pe.Encodef("shallow %s\n", hash); e.err != nil {
+ return nil
+ }
+ }
+
+ return encodeFlush
+}
+
+func sortShallows(c []plumbing.Hash) []string {
+ ret := []string{}
+ for _, h := range c {
+ ret = append(ret, h.String())
+ }
+ sort.Strings(ret)
+
+ return ret
+}
+
+func encodeFlush(e *advRefsEncoder) encoderStateFn {
+ e.err = e.pe.Flush()
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/capability.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/capability.go
new file mode 100644
index 00000000..b52e8a49
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/capability.go
@@ -0,0 +1,272 @@
+// Package capability defines the server and client capabilities.
+package capability
+
+import (
+ "fmt"
+ "os"
+)
+
+// Capability describes a server or client capability.
+type Capability string
+
+func (n Capability) String() string {
+ return string(n)
+}
+
+const (
+ // MultiACK capability allows the server to return "ACK obj-id continue" as
+ // soon as it finds a commit that it can use as a common base, between the
+ // client's wants and the client's have set.
+ //
+ // By sending this early, the server can potentially head off the client
+ // from walking any further down that particular branch of the client's
+ // repository history. The client may still need to walk down other
+ // branches, sending have lines for those, until the server has a
+ // complete cut across the DAG, or the client has said "done".
+ //
+ // Without multi_ack, a client sends have lines in --date-order until
+ // the server has found a common base. That means the client will send
+ // have lines that are already known by the server to be common, because
+ // they overlap in time with another branch that the server hasn't found
+ // a common base on yet.
+ //
+ // For example suppose the client has commits in caps that the server
+ // doesn't and the server has commits in lower case that the client
+ // doesn't, as in the following diagram:
+ //
+ // +---- u ---------------------- x
+ // / +----- y
+ // / /
+ // a -- b -- c -- d -- E -- F
+ // \
+ // +--- Q -- R -- S
+ //
+ // If the client wants x,y and starts out by saying have F,S, the server
+ // doesn't know what F,S is. Eventually the client says "have d" and
+ // the server sends "ACK d continue" to let the client know to stop
+ // walking down that line (so don't send c-b-a), but it's not done yet,
+ // it needs a base for x. The client keeps going with S-R-Q, until a
+ // gets reached, at which point the server has a clear base and it all
+ // ends.
+ //
+ // Without multi_ack the client would have sent that c-b-a chain anyway,
+ // interleaved with S-R-Q.
+ MultiACK Capability = "multi_ack"
+ // MultiACKDetailed is an extension of multi_ack that permits client to
+ // better understand the server's in-memory state.
+ MultiACKDetailed Capability = "multi_ack_detailed"
+ // NoDone should only be used with the smart HTTP protocol. If
+ // multi_ack_detailed and no-done are both present, then the sender is
+ // free to immediately send a pack following its first "ACK obj-id ready"
+ // message.
+ //
+ // Without no-done in the smart HTTP protocol, the server session would
+ // end and the client has to make another trip to send "done" before
+ // the server can send the pack. no-done removes the last round and
+ // thus slightly reduces latency.
+ NoDone Capability = "no-done"
+ // ThinPack is one with deltas which reference base objects not
+ // contained within the pack (but are known to exist at the receiving
+ // end). This can reduce the network traffic significantly, but it
+ // requires the receiving end to know how to "thicken" these packs by
+ // adding the missing bases to the pack.
+ //
+ // The upload-pack server advertises 'thin-pack' when it can generate
+ // and send a thin pack. A client requests the 'thin-pack' capability
+ // when it understands how to "thicken" it, notifying the server that
+ // it can receive such a pack. A client MUST NOT request the
+ // 'thin-pack' capability if it cannot turn a thin pack into a
+ // self-contained pack.
+ //
+ // Receive-pack, on the other hand, is assumed by default to be able to
+ // handle thin packs, but can ask the client not to use the feature by
+ // advertising the 'no-thin' capability. A client MUST NOT send a thin
+ // pack if the server advertises the 'no-thin' capability.
+ //
+ // The reasons for this asymmetry are historical. The receive-pack
+ // program did not exist until after the invention of thin packs, so
+ // historically the reference implementation of receive-pack always
+ // understood thin packs. Adding 'no-thin' later allowed receive-pack
+ // to disable the feature in a backwards-compatible manner.
+ ThinPack Capability = "thin-pack"
+ // Sideband means that server can send, and client understand multiplexed
+ // progress reports and error info interleaved with the packfile itself.
+ //
+ // These two options are mutually exclusive. A modern client always
+ // favors Sideband64k.
+ //
+ // Either mode indicates that the packfile data will be streamed broken
+ // up into packets of up to either 1000 bytes in the case of 'side_band',
+ // or 65520 bytes in the case of 'side_band_64k'. Each packet is made up
+ // of a leading 4-byte pkt-line length of how much data is in the packet,
+ // followed by a 1-byte stream code, followed by the actual data.
+ //
+ // The stream code can be one of:
+ //
+ // 1 - pack data
+ // 2 - progress messages
+ // 3 - fatal error message just before stream aborts
+ //
+ // The "side-band-64k" capability came about as a way for newer clients
+ // that can handle much larger packets to request packets that are
+ // actually crammed nearly full, while maintaining backward compatibility
+ // for the older clients.
+ //
+ // Further, with side-band and its up to 1000-byte messages, it's actually
+ // 999 bytes of payload and 1 byte for the stream code. With side-band-64k,
+ // same deal, you have up to 65519 bytes of data and 1 byte for the stream
+ // code.
+ //
+ // The client MUST send only maximum of one of "side-band" and "side-
+ // band-64k". Server MUST diagnose it as an error if client requests
+ // both.
+ Sideband Capability = "side-band"
+ Sideband64k Capability = "side-band-64k"
+ // OFSDelta server can send, and client understand PACKv2 with delta
+ // referring to its base by position in pack rather than by an obj-id. That
+ // is, they can send/read OBJ_OFS_DELTA (aka type 6) in a packfile.
+ OFSDelta Capability = "ofs-delta"
+ // Agent the server may optionally send this capability to notify the client
+ // that the server is running version `X`. The client may optionally return
+ // its own agent string by responding with an `agent=Y` capability (but it
+ // MUST NOT do so if the server did not mention the agent capability). The
+ // `X` and `Y` strings may contain any printable ASCII characters except
+ // space (i.e., the byte range 32 < x < 127), and are typically of the form
+ // "package/version" (e.g., "git/1.8.3.1"). The agent strings are purely
+ // informative for statistics and debugging purposes, and MUST NOT be used
+ // to programmatically assume the presence or absence of particular features.
+ Agent Capability = "agent"
+ // Shallow capability adds "deepen", "shallow" and "unshallow" commands to
+ // the fetch-pack/upload-pack protocol so clients can request shallow
+ // clones.
+ Shallow Capability = "shallow"
+ // DeepenSince adds "deepen-since" command to fetch-pack/upload-pack
+ // protocol so the client can request shallow clones that are cut at a
+ // specific time, instead of depth. Internally it's equivalent of doing
+ // "rev-list --max-age=" on the server side. "deepen-since"
+ // cannot be used with "deepen".
+ DeepenSince Capability = "deepen-since"
+ // DeepenNot adds "deepen-not" command to fetch-pack/upload-pack
+ // protocol so the client can request shallow clones that are cut at a
+ // specific revision, instead of depth. Internally it's equivalent of
+ // doing "rev-list --not " on the server side. "deepen-not"
+ // cannot be used with "deepen", but can be used with "deepen-since".
+ DeepenNot Capability = "deepen-not"
+ // DeepenRelative if this capability is requested by the client, the
+ // semantics of "deepen" command is changed. The "depth" argument is the
+ // depth from the current shallow boundary, instead of the depth from
+ // remote refs.
+ DeepenRelative Capability = "deepen-relative"
+ // NoProgress the client was started with "git clone -q" or something, and
+ // doesn't want that side band 2. Basically the client just says "I do not
+ // wish to receive stream 2 on sideband, so do not send it to me, and if
+ // you did, I will drop it on the floor anyway". However, the sideband
+ // channel 3 is still used for error responses.
+ NoProgress Capability = "no-progress"
+ // IncludeTag capability is about sending annotated tags if we are
+ // sending objects they point to. If we pack an object to the client, and
+ // a tag object points exactly at that object, we pack the tag object too.
+ // In general this allows a client to get all new annotated tags when it
+ // fetches a branch, in a single network connection.
+ //
+ // Clients MAY always send include-tag, hardcoding it into a request when
+ // the server advertises this capability. The decision for a client to
+ // request include-tag only has to do with the client's desires for tag
+ // data, whether or not a server had advertised objects in the
+ // refs/tags/* namespace.
+ //
+ // Servers MUST pack the tags if their referrant is packed and the client
+ // has requested include-tags.
+ //
+ // Clients MUST be prepared for the case where a server has ignored
+ // include-tag and has not actually sent tags in the pack. In such
+ // cases the client SHOULD issue a subsequent fetch to acquire the tags
+ // that include-tag would have otherwise given the client.
+ //
+ // The server SHOULD send include-tag, if it supports it, regardless
+ // of whether or not there are tags available.
+ IncludeTag Capability = "include-tag"
+ // ReportStatus the receive-pack process can receive a 'report-status'
+ // capability, which tells it that the client wants a report of what
+ // happened after a packfile upload and reference update. If the pushing
+ // client requests this capability, after unpacking and updating references
+ // the server will respond with whether the packfile unpacked successfully
+ // and if each reference was updated successfully. If any of those were not
+ // successful, it will send back an error message. See pack-protocol.txt
+ // for example messages.
+ ReportStatus Capability = "report-status"
+ // DeleteRefs If the server sends back this capability, it means that
+ // it is capable of accepting a zero-id value as the target
+ // value of a reference update. It is not sent back by the client, it
+ // simply informs the client that it can be sent zero-id values
+ // to delete references
+ DeleteRefs Capability = "delete-refs"
+ // Quiet If the receive-pack server advertises this capability, it is
+ // capable of silencing human-readable progress output which otherwise may
+ // be shown when processing the received pack. A send-pack client should
+ // respond with the 'quiet' capability to suppress server-side progress
+ // reporting if the local progress reporting is also being suppressed
+ // (e.g., via `push -q`, or if stderr does not go to a tty).
+ Quiet Capability = "quiet"
+ // Atomic If the server sends this capability it is capable of accepting
+ // atomic pushes. If the pushing client requests this capability, the server
+ // will update the refs in one atomic transaction. Either all refs are
+ // updated or none.
+ Atomic Capability = "atomic"
+ // PushOptions If the server sends this capability it is able to accept
+ // push options after the update commands have been sent, but before the
+ // packfile is streamed. If the pushing client requests this capability,
+ // the server will pass the options to the pre- and post- receive hooks
+ // that process this push request.
+ PushOptions Capability = "push-options"
+ // AllowTipSHA1InWant if the upload-pack server advertises this capability,
+ // fetch-pack may send "want" lines with SHA-1s that exist at the server but
+ // are not advertised by upload-pack.
+ AllowTipSHA1InWant Capability = "allow-tip-sha1-in-want"
+ // AllowReachableSHA1InWant if the upload-pack server advertises this
+ // capability, fetch-pack may send "want" lines with SHA-1s that exist at
+ // the server but are not advertised by upload-pack.
+ AllowReachableSHA1InWant Capability = "allow-reachable-sha1-in-want"
+ // PushCert the receive-pack server that advertises this capability is
+ // willing to accept a signed push certificate, and asks the to be
+ // included in the push certificate. A send-pack client MUST NOT
+ // send a push-cert packet unless the receive-pack server advertises
+ // this capability.
+ PushCert Capability = "push-cert"
+ // SymRef symbolic reference support for better negotiation.
+ SymRef Capability = "symref"
+ // ObjectFormat takes a hash algorithm as an argument, indicates that the
+ // server supports the given hash algorithms.
+ ObjectFormat Capability = "object-format"
+ // Filter if present, fetch-pack may send "filter" commands to request a
+ // partial clone or partial fetch and request that the server omit various objects from the packfile
+ Filter Capability = "filter"
+)
+
+const userAgent = "go-git/5.x"
+
+// DefaultAgent provides the user agent string.
+func DefaultAgent() string {
+ if envUserAgent, ok := os.LookupEnv("GO_GIT_USER_AGENT_EXTRA"); ok {
+ return fmt.Sprintf("%s %s", userAgent, envUserAgent)
+ }
+ return userAgent
+}
+
+var known = map[Capability]bool{
+ MultiACK: true, MultiACKDetailed: true, NoDone: true, ThinPack: true,
+ Sideband: true, Sideband64k: true, OFSDelta: true, Agent: true,
+ Shallow: true, DeepenSince: true, DeepenNot: true, DeepenRelative: true,
+ NoProgress: true, IncludeTag: true, ReportStatus: true, DeleteRefs: true,
+ Quiet: true, Atomic: true, PushOptions: true, AllowTipSHA1InWant: true,
+ AllowReachableSHA1InWant: true, PushCert: true, SymRef: true,
+ ObjectFormat: true, Filter: true,
+}
+
+var requiresArgument = map[Capability]bool{
+ Agent: true, PushCert: true, SymRef: true, ObjectFormat: true,
+}
+
+var multipleArgument = map[Capability]bool{
+ SymRef: true,
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/list.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/list.go
new file mode 100644
index 00000000..553d81cb
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/list.go
@@ -0,0 +1,195 @@
+package capability
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "strings"
+)
+
+var (
+ // ErrArgumentsRequired is returned if no arguments are giving with a
+ // capability that requires arguments
+ ErrArgumentsRequired = errors.New("arguments required")
+ // ErrArguments is returned if arguments are given with a capabilities that
+ // not supports arguments
+ ErrArguments = errors.New("arguments not allowed")
+ // ErrEmptyArgument is returned when an empty value is given
+ ErrEmptyArgument = errors.New("empty argument")
+ // ErrMultipleArguments multiple argument given to a capabilities that not
+ // support it
+ ErrMultipleArguments = errors.New("multiple arguments not allowed")
+)
+
+// List represents a list of capabilities
+type List struct {
+ m map[Capability]*entry
+ sort []string
+}
+
+type entry struct {
+ Name Capability
+ Values []string
+}
+
+// NewList returns a new List of capabilities
+func NewList() *List {
+ return &List{
+ m: make(map[Capability]*entry),
+ }
+}
+
+// IsEmpty returns true if the List is empty
+func (l *List) IsEmpty() bool {
+ return len(l.sort) == 0
+}
+
+// Decode decodes list of capabilities from raw into the list
+func (l *List) Decode(raw []byte) error {
+ // git 1.x receive pack used to send a leading space on its
+ // git-receive-pack capabilities announcement. We just trim space to be
+ // tolerant to space changes in different versions.
+ raw = bytes.TrimSpace(raw)
+
+ if len(raw) == 0 {
+ return nil
+ }
+
+ for _, data := range bytes.Split(raw, []byte{' '}) {
+ pair := bytes.SplitN(data, []byte{'='}, 2)
+
+ c := Capability(pair[0])
+ if len(pair) == 1 {
+ if err := l.Add(c); err != nil {
+ return err
+ }
+
+ continue
+ }
+
+ if err := l.Add(c, string(pair[1])); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Get returns the values for a capability
+func (l *List) Get(capability Capability) []string {
+ if _, ok := l.m[capability]; !ok {
+ return nil
+ }
+
+ return l.m[capability].Values
+}
+
+// Set sets a capability removing the previous values
+func (l *List) Set(capability Capability, values ...string) error {
+ if _, ok := l.m[capability]; ok {
+ l.m[capability].Values = l.m[capability].Values[:0]
+ }
+ return l.Add(capability, values...)
+}
+
+// Add adds a capability, values are optional
+func (l *List) Add(c Capability, values ...string) error {
+ if err := l.validate(c, values); err != nil {
+ return err
+ }
+
+ if !l.Supports(c) {
+ l.m[c] = &entry{Name: c}
+ l.sort = append(l.sort, c.String())
+ }
+
+ if len(values) == 0 {
+ return nil
+ }
+
+ if known[c] && !multipleArgument[c] && len(l.m[c].Values) > 0 {
+ return ErrMultipleArguments
+ }
+
+ l.m[c].Values = append(l.m[c].Values, values...)
+ return nil
+}
+
+func (l *List) validateNoEmptyArgs(values []string) error {
+ for _, v := range values {
+ if v == "" {
+ return ErrEmptyArgument
+ }
+ }
+ return nil
+}
+
+func (l *List) validate(c Capability, values []string) error {
+ if !known[c] {
+ return l.validateNoEmptyArgs(values)
+ }
+ if requiresArgument[c] && len(values) == 0 {
+ return ErrArgumentsRequired
+ }
+
+ if !requiresArgument[c] && len(values) != 0 {
+ return ErrArguments
+ }
+
+ if !multipleArgument[c] && len(values) > 1 {
+ return ErrMultipleArguments
+ }
+ return l.validateNoEmptyArgs(values)
+}
+
+// Supports returns true if capability is present
+func (l *List) Supports(capability Capability) bool {
+ _, ok := l.m[capability]
+ return ok
+}
+
+// Delete deletes a capability from the List
+func (l *List) Delete(capability Capability) {
+ if !l.Supports(capability) {
+ return
+ }
+
+ delete(l.m, capability)
+ for i, c := range l.sort {
+ if c != string(capability) {
+ continue
+ }
+
+ l.sort = append(l.sort[:i], l.sort[i+1:]...)
+ return
+ }
+}
+
+// All returns a slice with all defined capabilities.
+func (l *List) All() []Capability {
+ var cs []Capability
+ for _, key := range l.sort {
+ cs = append(cs, Capability(key))
+ }
+
+ return cs
+}
+
+// String generates the capabilities strings, the capabilities are sorted in
+// insertion order
+func (l *List) String() string {
+ var o []string
+ for _, key := range l.sort {
+ cap := l.m[Capability(key)]
+ if len(cap.Values) == 0 {
+ o = append(o, key)
+ continue
+ }
+
+ for _, value := range cap.Values {
+ o = append(o, fmt.Sprintf("%s=%s", key, value))
+ }
+ }
+
+ return strings.Join(o, " ")
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/common.go
new file mode 100644
index 00000000..a858323e
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/common.go
@@ -0,0 +1,74 @@
+package packp
+
+import (
+ "fmt"
+)
+
+type stateFn func() stateFn
+
+const (
+ // common
+ hashSize = 40
+
+ // advrefs
+ head = "HEAD"
+ noHead = "capabilities^{}"
+)
+
+var (
+ // common
+ sp = []byte(" ")
+ eol = []byte("\n")
+
+ // advertised-refs
+ null = []byte("\x00")
+ peeled = []byte("^{}")
+ noHeadMark = []byte(" capabilities^{}\x00")
+
+ // upload-request
+ want = []byte("want ")
+ shallow = []byte("shallow ")
+ deepen = []byte("deepen")
+ deepenCommits = []byte("deepen ")
+ deepenSince = []byte("deepen-since ")
+ deepenReference = []byte("deepen-not ")
+
+ // shallow-update
+ unshallow = []byte("unshallow ")
+
+ // server-response
+ ack = []byte("ACK")
+ nak = []byte("NAK")
+
+ // updreq
+ shallowNoSp = []byte("shallow")
+)
+
+func isFlush(payload []byte) bool {
+ return len(payload) == 0
+}
+
+var (
+ // ErrNilWriter is returned when a nil writer is passed to the encoder.
+ ErrNilWriter = fmt.Errorf("nil writer")
+)
+
+// ErrUnexpectedData represents an unexpected data decoding a message
+type ErrUnexpectedData struct {
+ Msg string
+ Data []byte
+}
+
+// NewErrUnexpectedData returns a new ErrUnexpectedData containing the data and
+// the message given
+func NewErrUnexpectedData(msg string, data []byte) error {
+ return &ErrUnexpectedData{Msg: msg, Data: data}
+}
+
+func (err *ErrUnexpectedData) Error() string {
+ if len(err.Data) == 0 {
+ return err.Msg
+ }
+
+ return fmt.Sprintf("%s (%s)", err.Msg, err.Data)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/doc.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/doc.go
new file mode 100644
index 00000000..4950d1d6
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/doc.go
@@ -0,0 +1,724 @@
+package packp
+
+/*
+
+A nice way to trace the real data transmitted and received by git, use:
+
+GIT_TRACE_PACKET=true git ls-remote http://github.com/src-d/go-git
+GIT_TRACE_PACKET=true git clone http://github.com/src-d/go-git
+
+Here follows a copy of the current protocol specification at the time of
+this writing.
+
+(Please notice that most http git servers will add a flush-pkt after the
+first pkt-line when using HTTP smart.)
+
+
+Documentation Common to Pack and Http Protocols
+===============================================
+
+ABNF Notation
+-------------
+
+ABNF notation as described by RFC 5234 is used within the protocol documents,
+except the following replacement core rules are used:
+----
+ HEXDIG = DIGIT / "a" / "b" / "c" / "d" / "e" / "f"
+----
+
+We also define the following common rules:
+----
+ NUL = %x00
+ zero-id = 40*"0"
+ obj-id = 40*(HEXDIGIT)
+
+ refname = "HEAD"
+ refname /= "refs/"
+----
+
+A refname is a hierarchical octet string beginning with "refs/" and
+not violating the 'git-check-ref-format' command's validation rules.
+More specifically, they:
+
+. They can include slash `/` for hierarchical (directory)
+ grouping, but no slash-separated component can begin with a
+ dot `.`.
+
+. They must contain at least one `/`. This enforces the presence of a
+ category like `heads/`, `tags/` etc. but the actual names are not
+ restricted.
+
+. They cannot have two consecutive dots `..` anywhere.
+
+. They cannot have ASCII control characters (i.e. bytes whose
+ values are lower than \040, or \177 `DEL`), space, tilde `~`,
+ caret `^`, colon `:`, question-mark `?`, asterisk `*`,
+ or open bracket `[` anywhere.
+
+. They cannot end with a slash `/` or a dot `.`.
+
+. They cannot end with the sequence `.lock`.
+
+. They cannot contain a sequence `@{`.
+
+. They cannot contain a `\\`.
+
+
+pkt-line Format
+---------------
+
+Much (but not all) of the payload is described around pkt-lines.
+
+A pkt-line is a variable length binary string. The first four bytes
+of the line, the pkt-len, indicates the total length of the line,
+in hexadecimal. The pkt-len includes the 4 bytes used to contain
+the length's hexadecimal representation.
+
+A pkt-line MAY contain binary data, so implementors MUST ensure
+pkt-line parsing/formatting routines are 8-bit clean.
+
+A non-binary line SHOULD BE terminated by an LF, which if present
+MUST be included in the total length. Receivers MUST treat pkt-lines
+with non-binary data the same whether or not they contain the trailing
+LF (stripping the LF if present, and not complaining when it is
+missing).
+
+The maximum length of a pkt-line's data component is 65516 bytes.
+Implementations MUST NOT send pkt-line whose length exceeds 65520
+(65516 bytes of payload + 4 bytes of length data).
+
+Implementations SHOULD NOT send an empty pkt-line ("0004").
+
+A pkt-line with a length field of 0 ("0000"), called a flush-pkt,
+is a special case and MUST be handled differently than an empty
+pkt-line ("0004").
+
+----
+ pkt-line = data-pkt / flush-pkt
+
+ data-pkt = pkt-len pkt-payload
+ pkt-len = 4*(HEXDIG)
+ pkt-payload = (pkt-len - 4)*(OCTET)
+
+ flush-pkt = "0000"
+----
+
+Examples (as C-style strings):
+
+----
+ pkt-line actual value
+ ---------------------------------
+ "0006a\n" "a\n"
+ "0005a" "a"
+ "000bfoobar\n" "foobar\n"
+ "0004" ""
+----
+
+Packfile transfer protocols
+===========================
+
+Git supports transferring data in packfiles over the ssh://, git://, http:// and
+file:// transports. There exist two sets of protocols, one for pushing
+data from a client to a server and another for fetching data from a
+server to a client. The three transports (ssh, git, file) use the same
+protocol to transfer data. http is documented in http-protocol.txt.
+
+The processes invoked in the canonical Git implementation are 'upload-pack'
+on the server side and 'fetch-pack' on the client side for fetching data;
+then 'receive-pack' on the server and 'send-pack' on the client for pushing
+data. The protocol functions to have a server tell a client what is
+currently on the server, then for the two to negotiate the smallest amount
+of data to send in order to fully update one or the other.
+
+pkt-line Format
+---------------
+
+The descriptions below build on the pkt-line format described in
+protocol-common.txt. When the grammar indicate `PKT-LINE(...)`, unless
+otherwise noted the usual pkt-line LF rules apply: the sender SHOULD
+include a LF, but the receiver MUST NOT complain if it is not present.
+
+Transports
+----------
+There are three transports over which the packfile protocol is
+initiated. The Git transport is a simple, unauthenticated server that
+takes the command (almost always 'upload-pack', though Git
+servers can be configured to be globally writable, in which 'receive-
+pack' initiation is also allowed) with which the client wishes to
+communicate and executes it and connects it to the requesting
+process.
+
+In the SSH transport, the client just runs the 'upload-pack'
+or 'receive-pack' process on the server over the SSH protocol and then
+communicates with that invoked process over the SSH connection.
+
+The file:// transport runs the 'upload-pack' or 'receive-pack'
+process locally and communicates with it over a pipe.
+
+Git Transport
+-------------
+
+The Git transport starts off by sending the command and repository
+on the wire using the pkt-line format, followed by a NUL byte and a
+hostname parameter, terminated by a NUL byte.
+
+ 0032git-upload-pack /project.git\0host=myserver.com\0
+
+--
+ git-proto-request = request-command SP pathname NUL [ host-parameter NUL ]
+ request-command = "git-upload-pack" / "git-receive-pack" /
+ "git-upload-archive" ; case sensitive
+ pathname = *( %x01-ff ) ; exclude NUL
+ host-parameter = "host=" hostname [ ":" port ]
+--
+
+Only host-parameter is allowed in the git-proto-request. Clients
+MUST NOT attempt to send additional parameters. It is used for the
+git-daemon name based virtual hosting. See --interpolated-path
+option to git daemon, with the %H/%CH format characters.
+
+Basically what the Git client is doing to connect to an 'upload-pack'
+process on the server side over the Git protocol is this:
+
+ $ echo -e -n \
+ "0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" |
+ nc -v example.com 9418
+
+If the server refuses the request for some reasons, it could abort
+gracefully with an error message.
+
+----
+ error-line = PKT-LINE("ERR" SP explanation-text)
+----
+
+
+SSH Transport
+-------------
+
+Initiating the upload-pack or receive-pack processes over SSH is
+executing the binary on the server via SSH remote execution.
+It is basically equivalent to running this:
+
+ $ ssh git.example.com "git-upload-pack '/project.git'"
+
+For a server to support Git pushing and pulling for a given user over
+SSH, that user needs to be able to execute one or both of those
+commands via the SSH shell that they are provided on login. On some
+systems, that shell access is limited to only being able to run those
+two commands, or even just one of them.
+
+In an ssh:// format URI, it's absolute in the URI, so the '/' after
+the host name (or port number) is sent as an argument, which is then
+read by the remote git-upload-pack exactly as is, so it's effectively
+an absolute path in the remote filesystem.
+
+ git clone ssh://user@example.com/project.git
+ |
+ v
+ ssh user@example.com "git-upload-pack '/project.git'"
+
+In a "user@host:path" format URI, its relative to the user's home
+directory, because the Git client will run:
+
+ git clone user@example.com:project.git
+ |
+ v
+ ssh user@example.com "git-upload-pack 'project.git'"
+
+The exception is if a '~' is used, in which case
+we execute it without the leading '/'.
+
+ ssh://user@example.com/~alice/project.git,
+ |
+ v
+ ssh user@example.com "git-upload-pack '~alice/project.git'"
+
+A few things to remember here:
+
+- The "command name" is spelled with dash (e.g. git-upload-pack), but
+ this can be overridden by the client;
+
+- The repository path is always quoted with single quotes.
+
+Fetching Data From a Server
+---------------------------
+
+When one Git repository wants to get data that a second repository
+has, the first can 'fetch' from the second. This operation determines
+what data the server has that the client does not then streams that
+data down to the client in packfile format.
+
+
+Reference Discovery
+-------------------
+
+When the client initially connects the server will immediately respond
+with a listing of each reference it has (all branches and tags) along
+with the object name that each reference currently points to.
+
+ $ echo -e -n "0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" |
+ nc -v example.com 9418
+ 00887217a7c7e582c46cec22a130adf4b9d7d950fba0 HEAD\0multi_ack thin-pack
+ side-band side-band-64k ofs-delta shallow no-progress include-tag
+ 00441d3fcd5ced445d1abc402225c0b8a1299641f497 refs/heads/integration
+ 003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 refs/heads/master
+ 003cb88d2441cac0977faf98efc80305012112238d9d refs/tags/v0.9
+ 003c525128480b96c89e6418b1e40909bf6c5b2d580f refs/tags/v1.0
+ 003fe92df48743b7bc7d26bcaabfddde0a1e20cae47c refs/tags/v1.0^{}
+ 0000
+
+The returned response is a pkt-line stream describing each ref and
+its current value. The stream MUST be sorted by name according to
+the C locale ordering.
+
+If HEAD is a valid ref, HEAD MUST appear as the first advertised
+ref. If HEAD is not a valid ref, HEAD MUST NOT appear in the
+advertisement list at all, but other refs may still appear.
+
+The stream MUST include capability declarations behind a NUL on the
+first ref. The peeled value of a ref (that is "ref^{}") MUST be
+immediately after the ref itself, if presented. A conforming server
+MUST peel the ref if it's an annotated tag.
+
+----
+ advertised-refs = (no-refs / list-of-refs)
+ *shallow
+ flush-pkt
+
+ no-refs = PKT-LINE(zero-id SP "capabilities^{}"
+ NUL capability-list)
+
+ list-of-refs = first-ref *other-ref
+ first-ref = PKT-LINE(obj-id SP refname
+ NUL capability-list)
+
+ other-ref = PKT-LINE(other-tip / other-peeled)
+ other-tip = obj-id SP refname
+ other-peeled = obj-id SP refname "^{}"
+
+ shallow = PKT-LINE("shallow" SP obj-id)
+
+ capability-list = capability *(SP capability)
+ capability = 1*(LC_ALPHA / DIGIT / "-" / "_")
+ LC_ALPHA = %x61-7A
+----
+
+Server and client MUST use lowercase for obj-id, both MUST treat obj-id
+as case-insensitive.
+
+See protocol-capabilities.txt for a list of allowed server capabilities
+and descriptions.
+
+Packfile Negotiation
+--------------------
+After reference and capabilities discovery, the client can decide to
+terminate the connection by sending a flush-pkt, telling the server it can
+now gracefully terminate, and disconnect, when it does not need any pack
+data. This can happen with the ls-remote command, and also can happen when
+the client already is up-to-date.
+
+Otherwise, it enters the negotiation phase, where the client and
+server determine what the minimal packfile necessary for transport is,
+by telling the server what objects it wants, its shallow objects
+(if any), and the maximum commit depth it wants (if any). The client
+will also send a list of the capabilities it wants to be in effect,
+out of what the server said it could do with the first 'want' line.
+
+----
+ upload-request = want-list
+ *shallow-line
+ *1depth-request
+ flush-pkt
+
+ want-list = first-want
+ *additional-want
+
+ shallow-line = PKT-LINE("shallow" SP obj-id)
+
+ depth-request = PKT-LINE("deepen" SP depth) /
+ PKT-LINE("deepen-since" SP timestamp) /
+ PKT-LINE("deepen-not" SP ref)
+
+ first-want = PKT-LINE("want" SP obj-id SP capability-list)
+ additional-want = PKT-LINE("want" SP obj-id)
+
+ depth = 1*DIGIT
+----
+
+Clients MUST send all the obj-ids it wants from the reference
+discovery phase as 'want' lines. Clients MUST send at least one
+'want' command in the request body. Clients MUST NOT mention an
+obj-id in a 'want' command which did not appear in the response
+obtained through ref discovery.
+
+The client MUST write all obj-ids which it only has shallow copies
+of (meaning that it does not have the parents of a commit) as
+'shallow' lines so that the server is aware of the limitations of
+the client's history.
+
+The client now sends the maximum commit history depth it wants for
+this transaction, which is the number of commits it wants from the
+tip of the history, if any, as a 'deepen' line. A depth of 0 is the
+same as not making a depth request. The client does not want to receive
+any commits beyond this depth, nor does it want objects needed only to
+complete those commits. Commits whose parents are not received as a
+result are defined as shallow and marked as such in the server. This
+information is sent back to the client in the next step.
+
+Once all the 'want's and 'shallow's (and optional 'deepen') are
+transferred, clients MUST send a flush-pkt, to tell the server side
+that it is done sending the list.
+
+Otherwise, if the client sent a positive depth request, the server
+will determine which commits will and will not be shallow and
+send this information to the client. If the client did not request
+a positive depth, this step is skipped.
+
+----
+ shallow-update = *shallow-line
+ *unshallow-line
+ flush-pkt
+
+ shallow-line = PKT-LINE("shallow" SP obj-id)
+
+ unshallow-line = PKT-LINE("unshallow" SP obj-id)
+----
+
+If the client has requested a positive depth, the server will compute
+the set of commits which are no deeper than the desired depth. The set
+of commits start at the client's wants.
+
+The server writes 'shallow' lines for each
+commit whose parents will not be sent as a result. The server writes
+an 'unshallow' line for each commit which the client has indicated is
+shallow, but is no longer shallow at the currently requested depth
+(that is, its parents will now be sent). The server MUST NOT mark
+as unshallow anything which the client has not indicated was shallow.
+
+Now the client will send a list of the obj-ids it has using 'have'
+lines, so the server can make a packfile that only contains the objects
+that the client needs. In multi_ack mode, the canonical implementation
+will send up to 32 of these at a time, then will send a flush-pkt. The
+canonical implementation will skip ahead and send the next 32 immediately,
+so that there is always a block of 32 "in-flight on the wire" at a time.
+
+----
+ upload-haves = have-list
+ compute-end
+
+ have-list = *have-line
+ have-line = PKT-LINE("have" SP obj-id)
+ compute-end = flush-pkt / PKT-LINE("done")
+----
+
+If the server reads 'have' lines, it then will respond by ACKing any
+of the obj-ids the client said it had that the server also has. The
+server will ACK obj-ids differently depending on which ack mode is
+chosen by the client.
+
+In multi_ack mode:
+
+ * the server will respond with 'ACK obj-id continue' for any common
+ commits.
+
+ * once the server has found an acceptable common base commit and is
+ ready to make a packfile, it will blindly ACK all 'have' obj-ids
+ back to the client.
+
+ * the server will then send a 'NAK' and then wait for another response
+ from the client - either a 'done' or another list of 'have' lines.
+
+In multi_ack_detailed mode:
+
+ * the server will differentiate the ACKs where it is signaling
+ that it is ready to send data with 'ACK obj-id ready' lines, and
+ signals the identified common commits with 'ACK obj-id common' lines.
+
+Without either multi_ack or multi_ack_detailed:
+
+ * upload-pack sends "ACK obj-id" on the first common object it finds.
+ After that it says nothing until the client gives it a "done".
+
+ * upload-pack sends "NAK" on a flush-pkt if no common object
+ has been found yet. If one has been found, and thus an ACK
+ was already sent, it's silent on the flush-pkt.
+
+After the client has gotten enough ACK responses that it can determine
+that the server has enough information to send an efficient packfile
+(in the canonical implementation, this is determined when it has received
+enough ACKs that it can color everything left in the --date-order queue
+as common with the server, or the --date-order queue is empty), or the
+client determines that it wants to give up (in the canonical implementation,
+this is determined when the client sends 256 'have' lines without getting
+any of them ACKed by the server - meaning there is nothing in common and
+the server should just send all of its objects), then the client will send
+a 'done' command. The 'done' command signals to the server that the client
+is ready to receive its packfile data.
+
+However, the 256 limit *only* turns on in the canonical client
+implementation if we have received at least one "ACK %s continue"
+during a prior round. This helps to ensure that at least one common
+ancestor is found before we give up entirely.
+
+Once the 'done' line is read from the client, the server will either
+send a final 'ACK obj-id' or it will send a 'NAK'. 'obj-id' is the object
+name of the last commit determined to be common. The server only sends
+ACK after 'done' if there is at least one common base and multi_ack or
+multi_ack_detailed is enabled. The server always sends NAK after 'done'
+if there is no common base found.
+
+Then the server will start sending its packfile data.
+
+----
+ server-response = *ack_multi ack / nak
+ ack_multi = PKT-LINE("ACK" SP obj-id ack_status)
+ ack_status = "continue" / "common" / "ready"
+ ack = PKT-LINE("ACK" SP obj-id)
+ nak = PKT-LINE("NAK")
+----
+
+A simple clone may look like this (with no 'have' lines):
+
+----
+ C: 0054want 74730d410fcb6603ace96f1dc55ea6196122532d multi_ack \
+ side-band-64k ofs-delta\n
+ C: 0032want 7d1665144a3a975c05f1f43902ddaf084e784dbe\n
+ C: 0032want 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a\n
+ C: 0032want 7e47fe2bd8d01d481f44d7af0531bd93d3b21c01\n
+ C: 0032want 74730d410fcb6603ace96f1dc55ea6196122532d\n
+ C: 0000
+ C: 0009done\n
+
+ S: 0008NAK\n
+ S: [PACKFILE]
+----
+
+An incremental update (fetch) response might look like this:
+
+----
+ C: 0054want 74730d410fcb6603ace96f1dc55ea6196122532d multi_ack \
+ side-band-64k ofs-delta\n
+ C: 0032want 7d1665144a3a975c05f1f43902ddaf084e784dbe\n
+ C: 0032want 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a\n
+ C: 0000
+ C: 0032have 7e47fe2bd8d01d481f44d7af0531bd93d3b21c01\n
+ C: [30 more have lines]
+ C: 0032have 74730d410fcb6603ace96f1dc55ea6196122532d\n
+ C: 0000
+
+ S: 003aACK 7e47fe2bd8d01d481f44d7af0531bd93d3b21c01 continue\n
+ S: 003aACK 74730d410fcb6603ace96f1dc55ea6196122532d continue\n
+ S: 0008NAK\n
+
+ C: 0009done\n
+
+ S: 0031ACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
+ S: [PACKFILE]
+----
+
+
+Packfile Data
+-------------
+
+Now that the client and server have finished negotiation about what
+the minimal amount of data that needs to be sent to the client is, the server
+will construct and send the required data in packfile format.
+
+See pack-format.txt for what the packfile itself actually looks like.
+
+If 'side-band' or 'side-band-64k' capabilities have been specified by
+the client, the server will send the packfile data multiplexed.
+
+Each packet starting with the packet-line length of the amount of data
+that follows, followed by a single byte specifying the sideband the
+following data is coming in on.
+
+In 'side-band' mode, it will send up to 999 data bytes plus 1 control
+code, for a total of up to 1000 bytes in a pkt-line. In 'side-band-64k'
+mode it will send up to 65519 data bytes plus 1 control code, for a
+total of up to 65520 bytes in a pkt-line.
+
+The sideband byte will be a '1', '2' or a '3'. Sideband '1' will contain
+packfile data, sideband '2' will be used for progress information that the
+client will generally print to stderr and sideband '3' is used for error
+information.
+
+If no 'side-band' capability was specified, the server will stream the
+entire packfile without multiplexing.
+
+
+Pushing Data To a Server
+------------------------
+
+Pushing data to a server will invoke the 'receive-pack' process on the
+server, which will allow the client to tell it which references it should
+update and then send all the data the server will need for those new
+references to be complete. Once all the data is received and validated,
+the server will then update its references to what the client specified.
+
+Authentication
+--------------
+
+The protocol itself contains no authentication mechanisms. That is to be
+handled by the transport, such as SSH, before the 'receive-pack' process is
+invoked. If 'receive-pack' is configured over the Git transport, those
+repositories will be writable by anyone who can access that port (9418) as
+that transport is unauthenticated.
+
+Reference Discovery
+-------------------
+
+The reference discovery phase is done nearly the same way as it is in the
+fetching protocol. Each reference obj-id and name on the server is sent
+in packet-line format to the client, followed by a flush-pkt. The only
+real difference is that the capability listing is different - the only
+possible values are 'report-status', 'delete-refs', 'ofs-delta' and
+'push-options'.
+
+Reference Update Request and Packfile Transfer
+----------------------------------------------
+
+Once the client knows what references the server is at, it can send a
+list of reference update requests. For each reference on the server
+that it wants to update, it sends a line listing the obj-id currently on
+the server, the obj-id the client would like to update it to and the name
+of the reference.
+
+This list is followed by a flush-pkt. Then the push options are transmitted
+one per packet followed by another flush-pkt. After that the packfile that
+should contain all the objects that the server will need to complete the new
+references will be sent.
+
+----
+ update-request = *shallow ( command-list | push-cert ) [packfile]
+
+ shallow = PKT-LINE("shallow" SP obj-id)
+
+ command-list = PKT-LINE(command NUL capability-list)
+ *PKT-LINE(command)
+ flush-pkt
+
+ command = create / delete / update
+ create = zero-id SP new-id SP name
+ delete = old-id SP zero-id SP name
+ update = old-id SP new-id SP name
+
+ old-id = obj-id
+ new-id = obj-id
+
+ push-cert = PKT-LINE("push-cert" NUL capability-list LF)
+ PKT-LINE("certificate version 0.1" LF)
+ PKT-LINE("pusher" SP ident LF)
+ PKT-LINE("pushee" SP url LF)
+ PKT-LINE("nonce" SP nonce LF)
+ PKT-LINE(LF)
+ *PKT-LINE(command LF)
+ *PKT-LINE(gpg-signature-lines LF)
+ PKT-LINE("push-cert-end" LF)
+
+ packfile = "PACK" 28*(OCTET)
+----
+
+If the receiving end does not support delete-refs, the sending end MUST
+NOT ask for delete command.
+
+If the receiving end does not support push-cert, the sending end
+MUST NOT send a push-cert command. When a push-cert command is
+sent, command-list MUST NOT be sent; the commands recorded in the
+push certificate is used instead.
+
+The packfile MUST NOT be sent if the only command used is 'delete'.
+
+A packfile MUST be sent if either create or update command is used,
+even if the server already has all the necessary objects. In this
+case the client MUST send an empty packfile. The only time this
+is likely to happen is if the client is creating
+a new branch or a tag that points to an existing obj-id.
+
+The server will receive the packfile, unpack it, then validate each
+reference that is being updated that it hasn't changed while the request
+was being processed (the obj-id is still the same as the old-id), and
+it will run any update hooks to make sure that the update is acceptable.
+If all of that is fine, the server will then update the references.
+
+Push Certificate
+----------------
+
+A push certificate begins with a set of header lines. After the
+header and an empty line, the protocol commands follow, one per
+line. Note that the trailing LF in push-cert PKT-LINEs is _not_
+optional; it must be present.
+
+Currently, the following header fields are defined:
+
+`pusher` ident::
+ Identify the GPG key in "Human Readable Name "
+ format.
+
+`pushee` url::
+ The repository URL (anonymized, if the URL contains
+ authentication material) the user who ran `git push`
+ intended to push into.
+
+`nonce` nonce::
+ The 'nonce' string the receiving repository asked the
+ pushing user to include in the certificate, to prevent
+ replay attacks.
+
+The GPG signature lines are a detached signature for the contents
+recorded in the push certificate before the signature block begins.
+The detached signature is used to certify that the commands were
+given by the pusher, who must be the signer.
+
+Report Status
+-------------
+
+After receiving the pack data from the sender, the receiver sends a
+report if 'report-status' capability is in effect.
+It is a short listing of what happened in that update. It will first
+list the status of the packfile unpacking as either 'unpack ok' or
+'unpack [error]'. Then it will list the status for each of the references
+that it tried to update. Each line is either 'ok [refname]' if the
+update was successful, or 'ng [refname] [error]' if the update was not.
+
+----
+ report-status = unpack-status
+ 1*(command-status)
+ flush-pkt
+
+ unpack-status = PKT-LINE("unpack" SP unpack-result)
+ unpack-result = "ok" / error-msg
+
+ command-status = command-ok / command-fail
+ command-ok = PKT-LINE("ok" SP refname)
+ command-fail = PKT-LINE("ng" SP refname SP error-msg)
+
+ error-msg = 1*(OCTECT) ; where not "ok"
+----
+
+Updates can be unsuccessful for a number of reasons. The reference can have
+changed since the reference discovery phase was originally sent, meaning
+someone pushed in the meantime. The reference being pushed could be a
+non-fast-forward reference and the update hooks or configuration could be
+set to not allow that, etc. Also, some references can be updated while others
+can be rejected.
+
+An example client/server communication might look like this:
+
+----
+ S: 007c74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/local\0report-status delete-refs ofs-delta\n
+ S: 003e7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug\n
+ S: 003f74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/master\n
+ S: 003f74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/team\n
+ S: 0000
+
+ C: 003e7d1665144a3a975c05f1f43902ddaf084e784dbe 74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/debug\n
+ C: 003e74730d410fcb6603ace96f1dc55ea6196122532d 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a refs/heads/master\n
+ C: 0000
+ C: [PACKDATA]
+
+ S: 000eunpack ok\n
+ S: 0018ok refs/heads/debug\n
+ S: 002ang refs/heads/master non-fast-forward\n
+----
+*/
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/gitproto.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/gitproto.go
new file mode 100644
index 00000000..0b7ff8f8
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/gitproto.go
@@ -0,0 +1,120 @@
+package packp
+
+import (
+ "fmt"
+ "io"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+var (
+ // ErrInvalidGitProtoRequest is returned by Decode if the input is not a
+ // valid git protocol request.
+ ErrInvalidGitProtoRequest = fmt.Errorf("invalid git protocol request")
+)
+
+// GitProtoRequest is a command request for the git protocol.
+// It is used to send the command, endpoint, and extra parameters to the
+// remote.
+// See https://git-scm.com/docs/pack-protocol#_git_transport
+type GitProtoRequest struct {
+ RequestCommand string
+ Pathname string
+
+ // Optional
+ Host string
+
+ // Optional
+ ExtraParams []string
+}
+
+// validate validates the request.
+func (g *GitProtoRequest) validate() error {
+ if g.RequestCommand == "" {
+ return fmt.Errorf("%w: empty request command", ErrInvalidGitProtoRequest)
+ }
+
+ if g.Pathname == "" {
+ return fmt.Errorf("%w: empty pathname", ErrInvalidGitProtoRequest)
+ }
+
+ return nil
+}
+
+// Encode encodes the request into the writer.
+func (g *GitProtoRequest) Encode(w io.Writer) error {
+ if w == nil {
+ return ErrNilWriter
+ }
+
+ if err := g.validate(); err != nil {
+ return err
+ }
+
+ p := pktline.NewEncoder(w)
+ req := fmt.Sprintf("%s %s\x00", g.RequestCommand, g.Pathname)
+ if host := g.Host; host != "" {
+ req += fmt.Sprintf("host=%s\x00", host)
+ }
+
+ if len(g.ExtraParams) > 0 {
+ req += "\x00"
+ for _, param := range g.ExtraParams {
+ req += param + "\x00"
+ }
+ }
+
+ if err := p.Encode([]byte(req)); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// Decode decodes the request from the reader.
+func (g *GitProtoRequest) Decode(r io.Reader) error {
+ s := pktline.NewScanner(r)
+ if !s.Scan() {
+ err := s.Err()
+ if err == nil {
+ return ErrInvalidGitProtoRequest
+ }
+ return err
+ }
+
+ line := string(s.Bytes())
+ if len(line) == 0 {
+ return io.EOF
+ }
+
+ if line[len(line)-1] != 0 {
+ return fmt.Errorf("%w: missing null terminator", ErrInvalidGitProtoRequest)
+ }
+
+ parts := strings.SplitN(line, " ", 2)
+ if len(parts) != 2 {
+ return fmt.Errorf("%w: short request", ErrInvalidGitProtoRequest)
+ }
+
+ g.RequestCommand = parts[0]
+ params := strings.Split(parts[1], string(null))
+ if len(params) < 1 {
+ return fmt.Errorf("%w: missing pathname", ErrInvalidGitProtoRequest)
+ }
+
+ g.Pathname = params[0]
+ if len(params) > 1 {
+ g.Host = strings.TrimPrefix(params[1], "host=")
+ }
+
+ if len(params) > 2 {
+ for _, param := range params[2:] {
+ if param != "" {
+ g.ExtraParams = append(g.ExtraParams, param)
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/report_status.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/report_status.go
new file mode 100644
index 00000000..e2a0a108
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/report_status.go
@@ -0,0 +1,165 @@
+package packp
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+const (
+ ok = "ok"
+)
+
+// ReportStatus is a report status message, as used in the git-receive-pack
+// process whenever the 'report-status' capability is negotiated.
+type ReportStatus struct {
+ UnpackStatus string
+ CommandStatuses []*CommandStatus
+}
+
+// NewReportStatus creates a new ReportStatus message.
+func NewReportStatus() *ReportStatus {
+ return &ReportStatus{}
+}
+
+// Error returns the first error if any.
+func (s *ReportStatus) Error() error {
+ if s.UnpackStatus != ok {
+ return fmt.Errorf("unpack error: %s", s.UnpackStatus)
+ }
+
+ for _, s := range s.CommandStatuses {
+ if err := s.Error(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Encode writes the report status to a writer.
+func (s *ReportStatus) Encode(w io.Writer) error {
+ e := pktline.NewEncoder(w)
+ if err := e.Encodef("unpack %s\n", s.UnpackStatus); err != nil {
+ return err
+ }
+
+ for _, cs := range s.CommandStatuses {
+ if err := cs.encode(w); err != nil {
+ return err
+ }
+ }
+
+ return e.Flush()
+}
+
+// Decode reads from the given reader and decodes a report-status message. It
+// does not read more input than what is needed to fill the report status.
+func (s *ReportStatus) Decode(r io.Reader) error {
+ scan := pktline.NewScanner(r)
+ if err := s.scanFirstLine(scan); err != nil {
+ return err
+ }
+
+ if err := s.decodeReportStatus(scan.Bytes()); err != nil {
+ return err
+ }
+
+ flushed := false
+ for scan.Scan() {
+ b := scan.Bytes()
+ if isFlush(b) {
+ flushed = true
+ break
+ }
+
+ if err := s.decodeCommandStatus(b); err != nil {
+ return err
+ }
+ }
+
+ if !flushed {
+ return fmt.Errorf("missing flush")
+ }
+
+ return scan.Err()
+}
+
+func (s *ReportStatus) scanFirstLine(scan *pktline.Scanner) error {
+ if scan.Scan() {
+ return nil
+ }
+
+ if scan.Err() != nil {
+ return scan.Err()
+ }
+
+ return io.ErrUnexpectedEOF
+}
+
+func (s *ReportStatus) decodeReportStatus(b []byte) error {
+ if isFlush(b) {
+ return fmt.Errorf("premature flush")
+ }
+
+ b = bytes.TrimSuffix(b, eol)
+
+ line := string(b)
+ fields := strings.SplitN(line, " ", 2)
+ if len(fields) != 2 || fields[0] != "unpack" {
+ return fmt.Errorf("malformed unpack status: %s", line)
+ }
+
+ s.UnpackStatus = fields[1]
+ return nil
+}
+
+func (s *ReportStatus) decodeCommandStatus(b []byte) error {
+ b = bytes.TrimSuffix(b, eol)
+
+ line := string(b)
+ fields := strings.SplitN(line, " ", 3)
+ status := ok
+ if len(fields) == 3 && fields[0] == "ng" {
+ status = fields[2]
+ } else if len(fields) != 2 || fields[0] != "ok" {
+ return fmt.Errorf("malformed command status: %s", line)
+ }
+
+ cs := &CommandStatus{
+ ReferenceName: plumbing.ReferenceName(fields[1]),
+ Status: status,
+ }
+ s.CommandStatuses = append(s.CommandStatuses, cs)
+ return nil
+}
+
+// CommandStatus is the status of a reference in a report status.
+// See ReportStatus struct.
+type CommandStatus struct {
+ ReferenceName plumbing.ReferenceName
+ Status string
+}
+
+// Error returns the error, if any.
+func (s *CommandStatus) Error() error {
+ if s.Status == ok {
+ return nil
+ }
+
+ return fmt.Errorf("command error on %s: %s",
+ s.ReferenceName.String(), s.Status)
+}
+
+func (s *CommandStatus) encode(w io.Writer) error {
+ e := pktline.NewEncoder(w)
+ if s.Error() == nil {
+ return e.Encodef("ok %s\n", s.ReferenceName.String())
+ }
+
+ return e.Encodef("ng %s %s\n", s.ReferenceName.String(), s.Status)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/shallowupd.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/shallowupd.go
new file mode 100644
index 00000000..fe4fe688
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/shallowupd.go
@@ -0,0 +1,92 @@
+package packp
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+const (
+ shallowLineLen = 48
+ unshallowLineLen = 50
+)
+
+type ShallowUpdate struct {
+ Shallows []plumbing.Hash
+ Unshallows []plumbing.Hash
+}
+
+func (r *ShallowUpdate) Decode(reader io.Reader) error {
+ s := pktline.NewScanner(reader)
+
+ for s.Scan() {
+ line := s.Bytes()
+ line = bytes.TrimSpace(line)
+
+ var err error
+ switch {
+ case bytes.HasPrefix(line, shallow):
+ err = r.decodeShallowLine(line)
+ case bytes.HasPrefix(line, unshallow):
+ err = r.decodeUnshallowLine(line)
+ case bytes.Equal(line, pktline.Flush):
+ return nil
+ }
+
+ if err != nil {
+ return err
+ }
+ }
+
+ return s.Err()
+}
+
+func (r *ShallowUpdate) decodeShallowLine(line []byte) error {
+ hash, err := r.decodeLine(line, shallow, shallowLineLen)
+ if err != nil {
+ return err
+ }
+
+ r.Shallows = append(r.Shallows, hash)
+ return nil
+}
+
+func (r *ShallowUpdate) decodeUnshallowLine(line []byte) error {
+ hash, err := r.decodeLine(line, unshallow, unshallowLineLen)
+ if err != nil {
+ return err
+ }
+
+ r.Unshallows = append(r.Unshallows, hash)
+ return nil
+}
+
+func (r *ShallowUpdate) decodeLine(line, prefix []byte, expLen int) (plumbing.Hash, error) {
+ if len(line) != expLen {
+ return plumbing.ZeroHash, fmt.Errorf("malformed %s%q", prefix, line)
+ }
+
+ raw := string(line[expLen-40 : expLen])
+ return plumbing.NewHash(raw), nil
+}
+
+func (r *ShallowUpdate) Encode(w io.Writer) error {
+ e := pktline.NewEncoder(w)
+
+ for _, h := range r.Shallows {
+ if err := e.Encodef("%s%s\n", shallow, h.String()); err != nil {
+ return err
+ }
+ }
+
+ for _, h := range r.Unshallows {
+ if err := e.Encodef("%s%s\n", unshallow, h.String()); err != nil {
+ return err
+ }
+ }
+
+ return e.Flush()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/common.go
new file mode 100644
index 00000000..de500128
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/common.go
@@ -0,0 +1,33 @@
+package sideband
+
+// Type sideband type "side-band" or "side-band-64k"
+type Type int8
+
+const (
+ // Sideband legacy sideband type up to 1000-byte messages
+ Sideband Type = iota
+ // Sideband64k sideband type up to 65519-byte messages
+ Sideband64k Type = iota
+
+ // MaxPackedSize for Sideband type
+ MaxPackedSize = 1000
+ // MaxPackedSize64k for Sideband64k type
+ MaxPackedSize64k = 65520
+)
+
+// Channel sideband channel
+type Channel byte
+
+// WithPayload encode the payload as a message
+func (ch Channel) WithPayload(payload []byte) []byte {
+ return append([]byte{byte(ch)}, payload...)
+}
+
+const (
+ // PackData packfile content
+ PackData Channel = 1
+ // ProgressMessage progress messages
+ ProgressMessage Channel = 2
+ // ErrorMessage fatal error message just before stream aborts
+ ErrorMessage Channel = 3
+)
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/demux.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/demux.go
new file mode 100644
index 00000000..0116f962
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/demux.go
@@ -0,0 +1,148 @@
+package sideband
+
+import (
+ "errors"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+// ErrMaxPackedExceeded returned by Read, if the maximum packed size is exceeded
+var ErrMaxPackedExceeded = errors.New("max. packed size exceeded")
+
+// Progress where the progress information is stored
+type Progress interface {
+ io.Writer
+}
+
+// Demuxer demultiplexes the progress reports and error info interleaved with the
+// packfile itself.
+//
+// A sideband has three different channels the main one, called PackData, contains
+// the packfile data; the ErrorMessage channel, that contains server errors; and
+// the last one, ProgressMessage channel, containing information about the ongoing
+// task happening in the server (optional, can be suppressed sending NoProgress
+// or Quiet capabilities to the server)
+//
+// In order to demultiplex the data stream, method `Read` should be called to
+// retrieve the PackData channel, the incoming data from the ProgressMessage is
+// written at `Progress` (if any), if any message is retrieved from the
+// ErrorMessage channel an error is returned and we can assume that the
+// connection has been closed.
+type Demuxer struct {
+ t Type
+ r io.Reader
+ s *pktline.Scanner
+
+ max int
+ pending []byte
+
+ // Progress is where the progress messages are stored
+ Progress Progress
+}
+
+// NewDemuxer returns a new Demuxer for the given t and read from r
+func NewDemuxer(t Type, r io.Reader) *Demuxer {
+ max := MaxPackedSize64k
+ if t == Sideband {
+ max = MaxPackedSize
+ }
+
+ return &Demuxer{
+ t: t,
+ r: r,
+ max: max,
+ s: pktline.NewScanner(r),
+ }
+}
+
+// Read reads up to len(p) bytes from the PackData channel into p, an error can
+// be return if an error happens when reading or if a message is sent in the
+// ErrorMessage channel.
+//
+// When a ProgressMessage is read, is not copy to b, instead of this is written
+// to the Progress
+func (d *Demuxer) Read(b []byte) (n int, err error) {
+ var read, req int
+
+ req = len(b)
+ for read < req {
+ n, err := d.doRead(b[read:req])
+ read += n
+
+ if err != nil {
+ return read, err
+ }
+ }
+
+ return read, nil
+}
+
+func (d *Demuxer) doRead(b []byte) (int, error) {
+ read, err := d.nextPackData()
+ size := len(read)
+ wanted := len(b)
+
+ if size > wanted {
+ d.pending = read[wanted:]
+ }
+
+ if wanted > size {
+ wanted = size
+ }
+
+ size = copy(b, read[:wanted])
+ return size, err
+}
+
+func (d *Demuxer) nextPackData() ([]byte, error) {
+ content := d.getPending()
+ if len(content) != 0 {
+ return content, nil
+ }
+
+ if !d.s.Scan() {
+ if err := d.s.Err(); err != nil {
+ return nil, err
+ }
+
+ return nil, io.EOF
+ }
+
+ content = d.s.Bytes()
+
+ size := len(content)
+ if size == 0 {
+ return nil, nil
+ } else if size > d.max {
+ return nil, ErrMaxPackedExceeded
+ }
+
+ switch Channel(content[0]) {
+ case PackData:
+ return content[1:], nil
+ case ProgressMessage:
+ if d.Progress != nil {
+ _, err := d.Progress.Write(content[1:])
+ return nil, err
+ }
+ case ErrorMessage:
+ return nil, fmt.Errorf("unexpected error: %s", content[1:])
+ default:
+ return nil, fmt.Errorf("unknown channel %s", content)
+ }
+
+ return nil, nil
+}
+
+func (d *Demuxer) getPending() (b []byte) {
+ if len(d.pending) == 0 {
+ return nil
+ }
+
+ content := d.pending
+ d.pending = nil
+
+ return content
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/doc.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/doc.go
new file mode 100644
index 00000000..c5d24295
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/doc.go
@@ -0,0 +1,31 @@
+// Package sideband implements a sideband mutiplex/demultiplexer
+package sideband
+
+// If 'side-band' or 'side-band-64k' capabilities have been specified by
+// the client, the server will send the packfile data multiplexed.
+//
+// Either mode indicates that the packfile data will be streamed broken
+// up into packets of up to either 1000 bytes in the case of 'side_band',
+// or 65520 bytes in the case of 'side_band_64k'. Each packet is made up
+// of a leading 4-byte pkt-line length of how much data is in the packet,
+// followed by a 1-byte stream code, followed by the actual data.
+//
+// The stream code can be one of:
+//
+// 1 - pack data
+// 2 - progress messages
+// 3 - fatal error message just before stream aborts
+//
+// The "side-band-64k" capability came about as a way for newer clients
+// that can handle much larger packets to request packets that are
+// actually crammed nearly full, while maintaining backward compatibility
+// for the older clients.
+//
+// Further, with side-band and its up to 1000-byte messages, it's actually
+// 999 bytes of payload and 1 byte for the stream code. With side-band-64k,
+// same deal, you have up to 65519 bytes of data and 1 byte for the stream
+// code.
+//
+// The client MUST send only maximum of one of "side-band" and "side-
+// band-64k". Server MUST diagnose it as an error if client requests
+// both.
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/muxer.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/muxer.go
new file mode 100644
index 00000000..d51ac826
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband/muxer.go
@@ -0,0 +1,65 @@
+package sideband
+
+import (
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+// Muxer multiplex the packfile along with the progress messages and the error
+// information. The multiplex is perform using pktline format.
+type Muxer struct {
+ max int
+ e *pktline.Encoder
+}
+
+const chLen = 1
+
+// NewMuxer returns a new Muxer for the given t that writes on w.
+//
+// If t is equal to `Sideband` the max pack size is set to MaxPackedSize, in any
+// other value is given, max pack is set to MaxPackedSize64k, that is the
+// maximum length of a line in pktline format.
+func NewMuxer(t Type, w io.Writer) *Muxer {
+ max := MaxPackedSize64k
+ if t == Sideband {
+ max = MaxPackedSize
+ }
+
+ return &Muxer{
+ max: max - chLen,
+ e: pktline.NewEncoder(w),
+ }
+}
+
+// Write writes p in the PackData channel
+func (m *Muxer) Write(p []byte) (int, error) {
+ return m.WriteChannel(PackData, p)
+}
+
+// WriteChannel writes p in the given channel. This method can be used with any
+// channel, but is recommend use it only for the ProgressMessage and
+// ErrorMessage channels and use Write for the PackData channel
+func (m *Muxer) WriteChannel(t Channel, p []byte) (int, error) {
+ wrote := 0
+ size := len(p)
+ for wrote < size {
+ n, err := m.doWrite(t, p[wrote:])
+ wrote += n
+
+ if err != nil {
+ return wrote, err
+ }
+ }
+
+ return wrote, nil
+}
+
+func (m *Muxer) doWrite(ch Channel, p []byte) (int, error) {
+ sz := len(p)
+ if sz > m.max {
+ sz = m.max
+ }
+
+ return sz, m.e.Encode(ch.WithPayload(p[:sz]))
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/srvresp.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/srvresp.go
new file mode 100644
index 00000000..a9ddb538
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/srvresp.go
@@ -0,0 +1,141 @@
+package packp
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+const ackLineLen = 44
+
+// ServerResponse object acknowledgement from upload-pack service
+type ServerResponse struct {
+ ACKs []plumbing.Hash
+}
+
+// Decode decodes the response into the struct, isMultiACK should be true, if
+// the request was done with multi_ack or multi_ack_detailed capabilities.
+func (r *ServerResponse) Decode(reader *bufio.Reader, isMultiACK bool) error {
+ s := pktline.NewScanner(reader)
+
+ for s.Scan() {
+ line := s.Bytes()
+
+ if err := r.decodeLine(line); err != nil {
+ return err
+ }
+
+ // we need to detect when the end of a response header and the beginning
+ // of a packfile header happened, some requests to the git daemon
+ // produces a duplicate ACK header even when multi_ack is not supported.
+ stop, err := r.stopReading(reader)
+ if err != nil {
+ return err
+ }
+
+ if stop {
+ break
+ }
+ }
+
+ // isMultiACK is true when the remote server advertises the related
+ // capabilities when they are not in transport.UnsupportedCapabilities.
+ //
+ // Users may decide to remove multi_ack and multi_ack_detailed from the
+ // unsupported capabilities list, which allows them to do initial clones
+ // from Azure DevOps.
+ //
+ // Follow-up fetches may error, therefore errors are wrapped with additional
+ // information highlighting that this capabilities are not supported by go-git.
+ //
+ // TODO: Implement support for multi_ack or multi_ack_detailed responses.
+ err := s.Err()
+ if err != nil && isMultiACK {
+ return fmt.Errorf("multi_ack and multi_ack_detailed are not supported: %w", err)
+ }
+
+ return err
+}
+
+// stopReading detects when a valid command such as ACK or NAK is found to be
+// read in the buffer without moving the read pointer.
+func (r *ServerResponse) stopReading(reader *bufio.Reader) (bool, error) {
+ ahead, err := reader.Peek(7)
+ if err == io.EOF {
+ return true, nil
+ }
+
+ if err != nil {
+ return false, err
+ }
+
+ if len(ahead) > 4 && r.isValidCommand(ahead[0:3]) {
+ return false, nil
+ }
+
+ if len(ahead) == 7 && r.isValidCommand(ahead[4:]) {
+ return false, nil
+ }
+
+ return true, nil
+}
+
+func (r *ServerResponse) isValidCommand(b []byte) bool {
+ commands := [][]byte{ack, nak}
+ for _, c := range commands {
+ if bytes.Equal(b, c) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (r *ServerResponse) decodeLine(line []byte) error {
+ if len(line) == 0 {
+ return fmt.Errorf("unexpected flush")
+ }
+
+ if len(line) >= 3 {
+ if bytes.Equal(line[0:3], ack) {
+ return r.decodeACKLine(line)
+ }
+
+ if bytes.Equal(line[0:3], nak) {
+ return nil
+ }
+ }
+
+ return fmt.Errorf("unexpected content %q", string(line))
+}
+
+func (r *ServerResponse) decodeACKLine(line []byte) error {
+ if len(line) < ackLineLen {
+ return fmt.Errorf("malformed ACK %q", line)
+ }
+
+ sp := bytes.Index(line, []byte(" "))
+ h := plumbing.NewHash(string(line[sp+1 : sp+41]))
+ r.ACKs = append(r.ACKs, h)
+ return nil
+}
+
+// Encode encodes the ServerResponse into a writer.
+func (r *ServerResponse) Encode(w io.Writer, isMultiACK bool) error {
+ if len(r.ACKs) > 1 && !isMultiACK {
+ // For further information, refer to comments in the Decode func above.
+ return errors.New("multi_ack and multi_ack_detailed are not supported")
+ }
+
+ e := pktline.NewEncoder(w)
+ if len(r.ACKs) == 0 {
+ return e.Encodef("%s\n", nak)
+ }
+
+ return e.Encodef("%s %s\n", ack, r.ACKs[0].String())
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq.go
new file mode 100644
index 00000000..344f8c7e
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq.go
@@ -0,0 +1,168 @@
+package packp
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+)
+
+// UploadRequest values represent the information transmitted on a
+// upload-request message. Values from this type are not zero-value
+// safe, use the New function instead.
+// This is a low level type, use UploadPackRequest instead.
+type UploadRequest struct {
+ Capabilities *capability.List
+ Wants []plumbing.Hash
+ Shallows []plumbing.Hash
+ Depth Depth
+}
+
+// Depth values stores the desired depth of the requested packfile: see
+// DepthCommit, DepthSince and DepthReference.
+type Depth interface {
+ isDepth()
+ IsZero() bool
+}
+
+// DepthCommits values stores the maximum number of requested commits in
+// the packfile. Zero means infinite. A negative value will have
+// undefined consequences.
+type DepthCommits int
+
+func (d DepthCommits) isDepth() {}
+
+func (d DepthCommits) IsZero() bool {
+ return d == 0
+}
+
+// DepthSince values requests only commits newer than the specified time.
+type DepthSince time.Time
+
+func (d DepthSince) isDepth() {}
+
+func (d DepthSince) IsZero() bool {
+ return time.Time(d).IsZero()
+}
+
+// DepthReference requests only commits not to found in the specified reference.
+type DepthReference string
+
+func (d DepthReference) isDepth() {}
+
+func (d DepthReference) IsZero() bool {
+ return string(d) == ""
+}
+
+// NewUploadRequest returns a pointer to a new UploadRequest value, ready to be
+// used. It has no capabilities, wants or shallows and an infinite depth. Please
+// note that to encode an upload-request it has to have at least one wanted hash.
+func NewUploadRequest() *UploadRequest {
+ return &UploadRequest{
+ Capabilities: capability.NewList(),
+ Wants: []plumbing.Hash{},
+ Shallows: []plumbing.Hash{},
+ Depth: DepthCommits(0),
+ }
+}
+
+// NewUploadRequestFromCapabilities returns a pointer to a new UploadRequest
+// value, the request capabilities are filled with the most optimal ones, based
+// on the adv value (advertised capabilities), the UploadRequest generated it
+// has no wants or shallows and an infinite depth.
+func NewUploadRequestFromCapabilities(adv *capability.List) *UploadRequest {
+ r := NewUploadRequest()
+
+ if adv.Supports(capability.MultiACKDetailed) {
+ r.Capabilities.Set(capability.MultiACKDetailed)
+ } else if adv.Supports(capability.MultiACK) {
+ r.Capabilities.Set(capability.MultiACK)
+ }
+
+ if adv.Supports(capability.Sideband64k) {
+ r.Capabilities.Set(capability.Sideband64k)
+ } else if adv.Supports(capability.Sideband) {
+ r.Capabilities.Set(capability.Sideband)
+ }
+
+ if adv.Supports(capability.ThinPack) {
+ r.Capabilities.Set(capability.ThinPack)
+ }
+
+ if adv.Supports(capability.OFSDelta) {
+ r.Capabilities.Set(capability.OFSDelta)
+ }
+
+ if adv.Supports(capability.Agent) {
+ r.Capabilities.Set(capability.Agent, capability.DefaultAgent())
+ }
+
+ return r
+}
+
+// Validate validates the content of UploadRequest, following the next rules:
+// - Wants MUST have at least one reference
+// - capability.Shallow MUST be present if Shallows is not empty
+// - is a non-zero DepthCommits is given capability.Shallow MUST be present
+// - is a DepthSince is given capability.Shallow MUST be present
+// - is a DepthReference is given capability.DeepenNot MUST be present
+// - MUST contain only maximum of one of capability.Sideband and capability.Sideband64k
+// - MUST contain only maximum of one of capability.MultiACK and capability.MultiACKDetailed
+func (req *UploadRequest) Validate() error {
+ if len(req.Wants) == 0 {
+ return fmt.Errorf("want can't be empty")
+ }
+
+ if err := req.validateRequiredCapabilities(); err != nil {
+ return err
+ }
+
+ if err := req.validateConflictCapabilities(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (req *UploadRequest) validateRequiredCapabilities() error {
+ msg := "missing capability %s"
+
+ if len(req.Shallows) != 0 && !req.Capabilities.Supports(capability.Shallow) {
+ return fmt.Errorf(msg, capability.Shallow)
+ }
+
+ switch req.Depth.(type) {
+ case DepthCommits:
+ if req.Depth != DepthCommits(0) {
+ if !req.Capabilities.Supports(capability.Shallow) {
+ return fmt.Errorf(msg, capability.Shallow)
+ }
+ }
+ case DepthSince:
+ if !req.Capabilities.Supports(capability.DeepenSince) {
+ return fmt.Errorf(msg, capability.DeepenSince)
+ }
+ case DepthReference:
+ if !req.Capabilities.Supports(capability.DeepenNot) {
+ return fmt.Errorf(msg, capability.DeepenNot)
+ }
+ }
+
+ return nil
+}
+
+func (req *UploadRequest) validateConflictCapabilities() error {
+ msg := "capabilities %s and %s are mutually exclusive"
+ if req.Capabilities.Supports(capability.Sideband) &&
+ req.Capabilities.Supports(capability.Sideband64k) {
+ return fmt.Errorf(msg, capability.Sideband, capability.Sideband64k)
+ }
+
+ if req.Capabilities.Supports(capability.MultiACK) &&
+ req.Capabilities.Supports(capability.MultiACKDetailed) {
+ return fmt.Errorf(msg, capability.MultiACK, capability.MultiACKDetailed)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_decode.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_decode.go
new file mode 100644
index 00000000..3da29985
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_decode.go
@@ -0,0 +1,257 @@
+package packp
+
+import (
+ "bytes"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "strconv"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+// Decode reads the next upload-request form its input and
+// stores it in the UploadRequest.
+func (req *UploadRequest) Decode(r io.Reader) error {
+ d := newUlReqDecoder(r)
+ return d.Decode(req)
+}
+
+type ulReqDecoder struct {
+ s *pktline.Scanner // a pkt-line scanner from the input stream
+ line []byte // current pkt-line contents, use parser.nextLine() to make it advance
+ nLine int // current pkt-line number for debugging, begins at 1
+ err error // sticky error, use the parser.error() method to fill this out
+ data *UploadRequest // parsed data is stored here
+}
+
+func newUlReqDecoder(r io.Reader) *ulReqDecoder {
+ return &ulReqDecoder{
+ s: pktline.NewScanner(r),
+ }
+}
+
+func (d *ulReqDecoder) Decode(v *UploadRequest) error {
+ d.data = v
+
+ for state := d.decodeFirstWant; state != nil; {
+ state = state()
+ }
+
+ return d.err
+}
+
+// fills out the parser sticky error
+func (d *ulReqDecoder) error(format string, a ...interface{}) {
+ msg := fmt.Sprintf(
+ "pkt-line %d: %s", d.nLine,
+ fmt.Sprintf(format, a...),
+ )
+
+ d.err = NewErrUnexpectedData(msg, d.line)
+}
+
+// Reads a new pkt-line from the scanner, makes its payload available as
+// p.line and increments p.nLine. A successful invocation returns true,
+// otherwise, false is returned and the sticky error is filled out
+// accordingly. Trims eols at the end of the payloads.
+func (d *ulReqDecoder) nextLine() bool {
+ d.nLine++
+
+ if !d.s.Scan() {
+ if d.err = d.s.Err(); d.err != nil {
+ return false
+ }
+
+ d.error("EOF")
+ return false
+ }
+
+ d.line = d.s.Bytes()
+ d.line = bytes.TrimSuffix(d.line, eol)
+
+ return true
+}
+
+// Expected format: want [ capabilities]
+func (d *ulReqDecoder) decodeFirstWant() stateFn {
+ if ok := d.nextLine(); !ok {
+ return nil
+ }
+
+ if !bytes.HasPrefix(d.line, want) {
+ d.error("missing 'want ' prefix")
+ return nil
+ }
+ d.line = bytes.TrimPrefix(d.line, want)
+
+ hash, ok := d.readHash()
+ if !ok {
+ return nil
+ }
+ d.data.Wants = append(d.data.Wants, hash)
+
+ return d.decodeCaps
+}
+
+func (d *ulReqDecoder) readHash() (plumbing.Hash, bool) {
+ if len(d.line) < hashSize {
+ d.err = fmt.Errorf("malformed hash: %v", d.line)
+ return plumbing.ZeroHash, false
+ }
+
+ var hash plumbing.Hash
+ if _, err := hex.Decode(hash[:], d.line[:hashSize]); err != nil {
+ d.error("invalid hash text: %s", err)
+ return plumbing.ZeroHash, false
+ }
+ d.line = d.line[hashSize:]
+
+ return hash, true
+}
+
+// Expected format: sp cap1 sp cap2 sp cap3...
+func (d *ulReqDecoder) decodeCaps() stateFn {
+ d.line = bytes.TrimPrefix(d.line, sp)
+ if err := d.data.Capabilities.Decode(d.line); err != nil {
+ d.error("invalid capabilities: %s", err)
+ }
+
+ return d.decodeOtherWants
+}
+
+// Expected format: want
+func (d *ulReqDecoder) decodeOtherWants() stateFn {
+ if ok := d.nextLine(); !ok {
+ return nil
+ }
+
+ if bytes.HasPrefix(d.line, shallow) {
+ return d.decodeShallow
+ }
+
+ if bytes.HasPrefix(d.line, deepen) {
+ return d.decodeDeepen
+ }
+
+ if len(d.line) == 0 {
+ return nil
+ }
+
+ if !bytes.HasPrefix(d.line, want) {
+ d.error("unexpected payload while expecting a want: %q", d.line)
+ return nil
+ }
+ d.line = bytes.TrimPrefix(d.line, want)
+
+ hash, ok := d.readHash()
+ if !ok {
+ return nil
+ }
+ d.data.Wants = append(d.data.Wants, hash)
+
+ return d.decodeOtherWants
+}
+
+// Expected format: shallow
+func (d *ulReqDecoder) decodeShallow() stateFn {
+ if bytes.HasPrefix(d.line, deepen) {
+ return d.decodeDeepen
+ }
+
+ if len(d.line) == 0 {
+ return nil
+ }
+
+ if !bytes.HasPrefix(d.line, shallow) {
+ d.error("unexpected payload while expecting a shallow: %q", d.line)
+ return nil
+ }
+ d.line = bytes.TrimPrefix(d.line, shallow)
+
+ hash, ok := d.readHash()
+ if !ok {
+ return nil
+ }
+ d.data.Shallows = append(d.data.Shallows, hash)
+
+ if ok := d.nextLine(); !ok {
+ return nil
+ }
+
+ return d.decodeShallow
+}
+
+// Expected format: deepen / deepen-since / deepen-not [
+func (d *ulReqDecoder) decodeDeepen() stateFn {
+ if bytes.HasPrefix(d.line, deepenCommits) {
+ return d.decodeDeepenCommits
+ }
+
+ if bytes.HasPrefix(d.line, deepenSince) {
+ return d.decodeDeepenSince
+ }
+
+ if bytes.HasPrefix(d.line, deepenReference) {
+ return d.decodeDeepenReference
+ }
+
+ if len(d.line) == 0 {
+ return nil
+ }
+
+ d.error("unexpected deepen specification: %q", d.line)
+ return nil
+}
+
+func (d *ulReqDecoder) decodeDeepenCommits() stateFn {
+ d.line = bytes.TrimPrefix(d.line, deepenCommits)
+
+ var n int
+ if n, d.err = strconv.Atoi(string(d.line)); d.err != nil {
+ return nil
+ }
+ if n < 0 {
+ d.err = fmt.Errorf("negative depth")
+ return nil
+ }
+ d.data.Depth = DepthCommits(n)
+
+ return d.decodeFlush
+}
+
+func (d *ulReqDecoder) decodeDeepenSince() stateFn {
+ d.line = bytes.TrimPrefix(d.line, deepenSince)
+
+ var secs int64
+ secs, d.err = strconv.ParseInt(string(d.line), 10, 64)
+ if d.err != nil {
+ return nil
+ }
+ t := time.Unix(secs, 0).UTC()
+ d.data.Depth = DepthSince(t)
+
+ return d.decodeFlush
+}
+
+func (d *ulReqDecoder) decodeDeepenReference() stateFn {
+ d.line = bytes.TrimPrefix(d.line, deepenReference)
+
+ d.data.Depth = DepthReference(string(d.line))
+
+ return d.decodeFlush
+}
+
+func (d *ulReqDecoder) decodeFlush() stateFn {
+ if ok := d.nextLine(); !ok {
+ return nil
+ }
+
+ if len(d.line) != 0 {
+ d.err = fmt.Errorf("unexpected payload while expecting a flush-pkt: %q", d.line)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_encode.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_encode.go
new file mode 100644
index 00000000..c451e231
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/ulreq_encode.go
@@ -0,0 +1,145 @@
+package packp
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+// Encode writes the UlReq encoding of u to the stream.
+//
+// All the payloads will end with a newline character. Wants and
+// shallows are sorted alphabetically. A depth of 0 means no depth
+// request is sent.
+func (req *UploadRequest) Encode(w io.Writer) error {
+ e := newUlReqEncoder(w)
+ return e.Encode(req)
+}
+
+type ulReqEncoder struct {
+ pe *pktline.Encoder // where to write the encoded data
+ data *UploadRequest // the data to encode
+ err error // sticky error
+}
+
+func newUlReqEncoder(w io.Writer) *ulReqEncoder {
+ return &ulReqEncoder{
+ pe: pktline.NewEncoder(w),
+ }
+}
+
+func (e *ulReqEncoder) Encode(v *UploadRequest) error {
+ e.data = v
+
+ if len(v.Wants) == 0 {
+ return fmt.Errorf("empty wants provided")
+ }
+
+ plumbing.HashesSort(e.data.Wants)
+ for state := e.encodeFirstWant; state != nil; {
+ state = state()
+ }
+
+ return e.err
+}
+
+func (e *ulReqEncoder) encodeFirstWant() stateFn {
+ var err error
+ if e.data.Capabilities.IsEmpty() {
+ err = e.pe.Encodef("want %s\n", e.data.Wants[0])
+ } else {
+ err = e.pe.Encodef(
+ "want %s %s\n",
+ e.data.Wants[0],
+ e.data.Capabilities.String(),
+ )
+ }
+
+ if err != nil {
+ e.err = fmt.Errorf("encoding first want line: %s", err)
+ return nil
+ }
+
+ return e.encodeAdditionalWants
+}
+
+func (e *ulReqEncoder) encodeAdditionalWants() stateFn {
+ last := e.data.Wants[0]
+ for _, w := range e.data.Wants[1:] {
+ if bytes.Equal(last[:], w[:]) {
+ continue
+ }
+
+ if err := e.pe.Encodef("want %s\n", w); err != nil {
+ e.err = fmt.Errorf("encoding want %q: %s", w, err)
+ return nil
+ }
+
+ last = w
+ }
+
+ return e.encodeShallows
+}
+
+func (e *ulReqEncoder) encodeShallows() stateFn {
+ plumbing.HashesSort(e.data.Shallows)
+
+ var last plumbing.Hash
+ for _, s := range e.data.Shallows {
+ if bytes.Equal(last[:], s[:]) {
+ continue
+ }
+
+ if err := e.pe.Encodef("shallow %s\n", s); err != nil {
+ e.err = fmt.Errorf("encoding shallow %q: %s", s, err)
+ return nil
+ }
+
+ last = s
+ }
+
+ return e.encodeDepth
+}
+
+func (e *ulReqEncoder) encodeDepth() stateFn {
+ switch depth := e.data.Depth.(type) {
+ case DepthCommits:
+ if depth != 0 {
+ commits := int(depth)
+ if err := e.pe.Encodef("deepen %d\n", commits); err != nil {
+ e.err = fmt.Errorf("encoding depth %d: %s", depth, err)
+ return nil
+ }
+ }
+ case DepthSince:
+ when := time.Time(depth).UTC()
+ if err := e.pe.Encodef("deepen-since %d\n", when.Unix()); err != nil {
+ e.err = fmt.Errorf("encoding depth %s: %s", when, err)
+ return nil
+ }
+ case DepthReference:
+ reference := string(depth)
+ if err := e.pe.Encodef("deepen-not %s\n", reference); err != nil {
+ e.err = fmt.Errorf("encoding depth %s: %s", reference, err)
+ return nil
+ }
+ default:
+ e.err = fmt.Errorf("unsupported depth type")
+ return nil
+ }
+
+ return e.encodeFlush
+}
+
+func (e *ulReqEncoder) encodeFlush() stateFn {
+ if err := e.pe.Flush(); err != nil {
+ e.err = fmt.Errorf("encoding flush-pkt: %s", err)
+ return nil
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq.go
new file mode 100644
index 00000000..8f39b39c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq.go
@@ -0,0 +1,128 @@
+package packp
+
+import (
+ "errors"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband"
+)
+
+var (
+ ErrEmptyCommands = errors.New("commands cannot be empty")
+ ErrMalformedCommand = errors.New("malformed command")
+)
+
+// ReferenceUpdateRequest values represent reference upload requests.
+// Values from this type are not zero-value safe, use the New function instead.
+type ReferenceUpdateRequest struct {
+ Capabilities *capability.List
+ Commands []*Command
+ Options []*Option
+ Shallow *plumbing.Hash
+ // Packfile contains an optional packfile reader.
+ Packfile io.ReadCloser
+
+ // Progress receives sideband progress messages from the server
+ Progress sideband.Progress
+}
+
+// New returns a pointer to a new ReferenceUpdateRequest value.
+func NewReferenceUpdateRequest() *ReferenceUpdateRequest {
+ return &ReferenceUpdateRequest{
+ // TODO: Add support for push-cert
+ Capabilities: capability.NewList(),
+ Commands: nil,
+ }
+}
+
+// NewReferenceUpdateRequestFromCapabilities returns a pointer to a new
+// ReferenceUpdateRequest value, the request capabilities are filled with the
+// most optimal ones, based on the adv value (advertised capabilities), the
+// ReferenceUpdateRequest contains no commands
+//
+// It does set the following capabilities:
+// - agent
+// - report-status
+// - ofs-delta
+// - ref-delta
+// - delete-refs
+// It leaves up to the user to add the following capabilities later:
+// - atomic
+// - ofs-delta
+// - side-band
+// - side-band-64k
+// - quiet
+// - push-cert
+func NewReferenceUpdateRequestFromCapabilities(adv *capability.List) *ReferenceUpdateRequest {
+ r := NewReferenceUpdateRequest()
+
+ if adv.Supports(capability.Agent) {
+ r.Capabilities.Set(capability.Agent, capability.DefaultAgent())
+ }
+
+ if adv.Supports(capability.ReportStatus) {
+ r.Capabilities.Set(capability.ReportStatus)
+ }
+
+ return r
+}
+
+func (req *ReferenceUpdateRequest) validate() error {
+ if len(req.Commands) == 0 {
+ return ErrEmptyCommands
+ }
+
+ for _, c := range req.Commands {
+ if err := c.validate(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+type Action string
+
+const (
+ Create Action = "create"
+ Update Action = "update"
+ Delete Action = "delete"
+ Invalid Action = "invalid"
+)
+
+type Command struct {
+ Name plumbing.ReferenceName
+ Old plumbing.Hash
+ New plumbing.Hash
+}
+
+func (c *Command) Action() Action {
+ if c.Old == plumbing.ZeroHash && c.New == plumbing.ZeroHash {
+ return Invalid
+ }
+
+ if c.Old == plumbing.ZeroHash {
+ return Create
+ }
+
+ if c.New == plumbing.ZeroHash {
+ return Delete
+ }
+
+ return Update
+}
+
+func (c *Command) validate() error {
+ if c.Action() == Invalid {
+ return ErrMalformedCommand
+ }
+
+ return nil
+}
+
+type Option struct {
+ Key string
+ Value string
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_decode.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_decode.go
new file mode 100644
index 00000000..076de545
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_decode.go
@@ -0,0 +1,249 @@
+package packp
+
+import (
+ "bytes"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+)
+
+var (
+ shallowLineLength = len(shallow) + hashSize
+ minCommandLength = hashSize*2 + 2 + 1
+ minCommandAndCapsLength = minCommandLength + 1
+)
+
+var (
+ ErrEmpty = errors.New("empty update-request message")
+ errNoCommands = errors.New("unexpected EOF before any command")
+ errMissingCapabilitiesDelimiter = errors.New("capabilities delimiter not found")
+)
+
+func errMalformedRequest(reason string) error {
+ return fmt.Errorf("malformed request: %s", reason)
+}
+
+func errInvalidHashSize(got int) error {
+ return fmt.Errorf("invalid hash size: expected %d, got %d",
+ hashSize, got)
+}
+
+func errInvalidHash(err error) error {
+ return fmt.Errorf("invalid hash: %s", err.Error())
+}
+
+func errInvalidShallowLineLength(got int) error {
+ return errMalformedRequest(fmt.Sprintf(
+ "invalid shallow line length: expected %d, got %d",
+ shallowLineLength, got))
+}
+
+func errInvalidCommandCapabilitiesLineLength(got int) error {
+ return errMalformedRequest(fmt.Sprintf(
+ "invalid command and capabilities line length: expected at least %d, got %d",
+ minCommandAndCapsLength, got))
+}
+
+func errInvalidCommandLineLength(got int) error {
+ return errMalformedRequest(fmt.Sprintf(
+ "invalid command line length: expected at least %d, got %d",
+ minCommandLength, got))
+}
+
+func errInvalidShallowObjId(err error) error {
+ return errMalformedRequest(
+ fmt.Sprintf("invalid shallow object id: %s", err.Error()))
+}
+
+func errInvalidOldObjId(err error) error {
+ return errMalformedRequest(
+ fmt.Sprintf("invalid old object id: %s", err.Error()))
+}
+
+func errInvalidNewObjId(err error) error {
+ return errMalformedRequest(
+ fmt.Sprintf("invalid new object id: %s", err.Error()))
+}
+
+func errMalformedCommand(err error) error {
+ return errMalformedRequest(fmt.Sprintf(
+ "malformed command: %s", err.Error()))
+}
+
+// Decode reads the next update-request message form the reader and wr
+func (req *ReferenceUpdateRequest) Decode(r io.Reader) error {
+ var rc io.ReadCloser
+ var ok bool
+ rc, ok = r.(io.ReadCloser)
+ if !ok {
+ rc = io.NopCloser(r)
+ }
+
+ d := &updReqDecoder{r: rc, s: pktline.NewScanner(r)}
+ return d.Decode(req)
+}
+
+type updReqDecoder struct {
+ r io.ReadCloser
+ s *pktline.Scanner
+ req *ReferenceUpdateRequest
+}
+
+func (d *updReqDecoder) Decode(req *ReferenceUpdateRequest) error {
+ d.req = req
+ funcs := []func() error{
+ d.scanLine,
+ d.decodeShallow,
+ d.decodeCommandAndCapabilities,
+ d.decodeCommands,
+ d.setPackfile,
+ req.validate,
+ }
+
+ for _, f := range funcs {
+ if err := f(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (d *updReqDecoder) scanLine() error {
+ if ok := d.s.Scan(); !ok {
+ return d.scanErrorOr(ErrEmpty)
+ }
+
+ return nil
+}
+
+func (d *updReqDecoder) decodeShallow() error {
+ b := d.s.Bytes()
+
+ if !bytes.HasPrefix(b, shallowNoSp) {
+ return nil
+ }
+
+ if len(b) != shallowLineLength {
+ return errInvalidShallowLineLength(len(b))
+ }
+
+ h, err := parseHash(string(b[len(shallow):]))
+ if err != nil {
+ return errInvalidShallowObjId(err)
+ }
+
+ if ok := d.s.Scan(); !ok {
+ return d.scanErrorOr(errNoCommands)
+ }
+
+ d.req.Shallow = &h
+
+ return nil
+}
+
+func (d *updReqDecoder) decodeCommands() error {
+ for {
+ b := d.s.Bytes()
+ if bytes.Equal(b, pktline.Flush) {
+ return nil
+ }
+
+ c, err := parseCommand(b)
+ if err != nil {
+ return err
+ }
+
+ d.req.Commands = append(d.req.Commands, c)
+
+ if ok := d.s.Scan(); !ok {
+ return d.s.Err()
+ }
+ }
+}
+
+func (d *updReqDecoder) decodeCommandAndCapabilities() error {
+ b := d.s.Bytes()
+ i := bytes.IndexByte(b, 0)
+ if i == -1 {
+ return errMissingCapabilitiesDelimiter
+ }
+
+ if len(b) < minCommandAndCapsLength {
+ return errInvalidCommandCapabilitiesLineLength(len(b))
+ }
+
+ cmd, err := parseCommand(b[:i])
+ if err != nil {
+ return err
+ }
+
+ d.req.Commands = append(d.req.Commands, cmd)
+
+ if err := d.req.Capabilities.Decode(b[i+1:]); err != nil {
+ return err
+ }
+
+ if err := d.scanLine(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (d *updReqDecoder) setPackfile() error {
+ d.req.Packfile = d.r
+
+ return nil
+}
+
+func parseCommand(b []byte) (*Command, error) {
+ if len(b) < minCommandLength {
+ return nil, errInvalidCommandLineLength(len(b))
+ }
+
+ var (
+ os, ns string
+ n plumbing.ReferenceName
+ )
+ if _, err := fmt.Sscanf(string(b), "%s %s %s", &os, &ns, &n); err != nil {
+ return nil, errMalformedCommand(err)
+ }
+
+ oh, err := parseHash(os)
+ if err != nil {
+ return nil, errInvalidOldObjId(err)
+ }
+
+ nh, err := parseHash(ns)
+ if err != nil {
+ return nil, errInvalidNewObjId(err)
+ }
+
+ return &Command{Old: oh, New: nh, Name: n}, nil
+}
+
+func parseHash(s string) (plumbing.Hash, error) {
+ if len(s) != hashSize {
+ return plumbing.ZeroHash, errInvalidHashSize(len(s))
+ }
+
+ if _, err := hex.DecodeString(s); err != nil {
+ return plumbing.ZeroHash, errInvalidHash(err)
+ }
+
+ h := plumbing.NewHash(s)
+ return h, nil
+}
+
+func (d *updReqDecoder) scanErrorOr(origErr error) error {
+ if err := d.s.Err(); err != nil {
+ return err
+ }
+
+ return origErr
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_encode.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_encode.go
new file mode 100644
index 00000000..1205cfaf
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq_encode.go
@@ -0,0 +1,89 @@
+package packp
+
+import (
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+)
+
+// Encode writes the ReferenceUpdateRequest encoding to the stream.
+func (req *ReferenceUpdateRequest) Encode(w io.Writer) error {
+ if err := req.validate(); err != nil {
+ return err
+ }
+
+ e := pktline.NewEncoder(w)
+
+ if err := req.encodeShallow(e, req.Shallow); err != nil {
+ return err
+ }
+
+ if err := req.encodeCommands(e, req.Commands, req.Capabilities); err != nil {
+ return err
+ }
+
+ if req.Capabilities.Supports(capability.PushOptions) {
+ if err := req.encodeOptions(e, req.Options); err != nil {
+ return err
+ }
+ }
+
+ if req.Packfile != nil {
+ if _, err := io.Copy(w, req.Packfile); err != nil {
+ return err
+ }
+
+ return req.Packfile.Close()
+ }
+
+ return nil
+}
+
+func (req *ReferenceUpdateRequest) encodeShallow(e *pktline.Encoder,
+ h *plumbing.Hash) error {
+
+ if h == nil {
+ return nil
+ }
+
+ objId := []byte(h.String())
+ return e.Encodef("%s%s", shallow, objId)
+}
+
+func (req *ReferenceUpdateRequest) encodeCommands(e *pktline.Encoder,
+ cmds []*Command, cap *capability.List) error {
+
+ if err := e.Encodef("%s\x00%s",
+ formatCommand(cmds[0]), cap.String()); err != nil {
+ return err
+ }
+
+ for _, cmd := range cmds[1:] {
+ if err := e.Encodef(formatCommand(cmd)); err != nil {
+ return err
+ }
+ }
+
+ return e.Flush()
+}
+
+func formatCommand(cmd *Command) string {
+ o := cmd.Old.String()
+ n := cmd.New.String()
+ return fmt.Sprintf("%s %s %s", o, n, cmd.Name)
+}
+
+func (req *ReferenceUpdateRequest) encodeOptions(e *pktline.Encoder,
+ opts []*Option) error {
+
+ for _, opt := range opts {
+ if err := e.Encodef("%s=%s", opt.Key, opt.Value); err != nil {
+ return err
+ }
+ }
+
+ return e.Flush()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackreq.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackreq.go
new file mode 100644
index 00000000..48f44385
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackreq.go
@@ -0,0 +1,98 @@
+package packp
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+)
+
+// UploadPackRequest represents a upload-pack request.
+// Zero-value is not safe, use NewUploadPackRequest instead.
+type UploadPackRequest struct {
+ UploadRequest
+ UploadHaves
+}
+
+// NewUploadPackRequest creates a new UploadPackRequest and returns a pointer.
+func NewUploadPackRequest() *UploadPackRequest {
+ ur := NewUploadRequest()
+ return &UploadPackRequest{
+ UploadHaves: UploadHaves{},
+ UploadRequest: *ur,
+ }
+}
+
+// NewUploadPackRequestFromCapabilities creates a new UploadPackRequest and
+// returns a pointer. The request capabilities are filled with the most optimal
+// ones, based on the adv value (advertised capabilities), the UploadPackRequest
+// it has no wants, haves or shallows and an infinite depth
+func NewUploadPackRequestFromCapabilities(adv *capability.List) *UploadPackRequest {
+ ur := NewUploadRequestFromCapabilities(adv)
+ return &UploadPackRequest{
+ UploadHaves: UploadHaves{},
+ UploadRequest: *ur,
+ }
+}
+
+// IsEmpty returns whether a request is empty - it is empty if Haves are contained
+// in the Wants, or if Wants length is zero, and we don't have any shallows
+func (r *UploadPackRequest) IsEmpty() bool {
+ return isSubset(r.Wants, r.Haves) && len(r.Shallows) == 0
+}
+
+func isSubset(needle []plumbing.Hash, haystack []plumbing.Hash) bool {
+ for _, h := range needle {
+ found := false
+ for _, oh := range haystack {
+ if h == oh {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ return false
+ }
+ }
+
+ return true
+}
+
+// UploadHaves is a message to signal the references that a client has in a
+// upload-pack. Do not use this directly. Use UploadPackRequest request instead.
+type UploadHaves struct {
+ Haves []plumbing.Hash
+}
+
+// Encode encodes the UploadHaves into the Writer. If flush is true, a flush
+// command will be encoded at the end of the writer content.
+func (u *UploadHaves) Encode(w io.Writer, flush bool) error {
+ e := pktline.NewEncoder(w)
+
+ plumbing.HashesSort(u.Haves)
+
+ var last plumbing.Hash
+ for _, have := range u.Haves {
+ if bytes.Equal(last[:], have[:]) {
+ continue
+ }
+
+ if err := e.Encodef("have %s\n", have); err != nil {
+ return fmt.Errorf("sending haves for %q: %s", have, err)
+ }
+
+ last = have
+ }
+
+ if flush && len(u.Haves) != 0 {
+ if err := e.Flush(); err != nil {
+ return fmt.Errorf("sending flush-pkt after haves: %s", err)
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackresp.go b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackresp.go
new file mode 100644
index 00000000..a485cb7b
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/uppackresp.go
@@ -0,0 +1,108 @@
+package packp
+
+import (
+ "errors"
+ "io"
+
+ "bufio"
+
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// ErrUploadPackResponseNotDecoded is returned if Read is called without
+// decoding first
+var ErrUploadPackResponseNotDecoded = errors.New("upload-pack-response should be decoded")
+
+// UploadPackResponse contains all the information responded by the upload-pack
+// service, the response implements io.ReadCloser that allows to read the
+// packfile directly from it.
+type UploadPackResponse struct {
+ ShallowUpdate
+ ServerResponse
+
+ r io.ReadCloser
+ isShallow bool
+ isMultiACK bool
+}
+
+// NewUploadPackResponse create a new UploadPackResponse instance, the request
+// being responded by the response is required.
+func NewUploadPackResponse(req *UploadPackRequest) *UploadPackResponse {
+ isShallow := !req.Depth.IsZero()
+ isMultiACK := req.Capabilities.Supports(capability.MultiACK) ||
+ req.Capabilities.Supports(capability.MultiACKDetailed)
+
+ return &UploadPackResponse{
+ isShallow: isShallow,
+ isMultiACK: isMultiACK,
+ }
+}
+
+// NewUploadPackResponseWithPackfile creates a new UploadPackResponse instance,
+// and sets its packfile reader.
+func NewUploadPackResponseWithPackfile(req *UploadPackRequest,
+ pf io.ReadCloser) *UploadPackResponse {
+
+ r := NewUploadPackResponse(req)
+ r.r = pf
+ return r
+}
+
+// Decode decodes all the responses sent by upload-pack service into the struct
+// and prepares it to read the packfile using the Read method
+func (r *UploadPackResponse) Decode(reader io.ReadCloser) error {
+ buf := bufio.NewReader(reader)
+
+ if r.isShallow {
+ if err := r.ShallowUpdate.Decode(buf); err != nil {
+ return err
+ }
+ }
+
+ if err := r.ServerResponse.Decode(buf, r.isMultiACK); err != nil {
+ return err
+ }
+
+ // now the reader is ready to read the packfile content
+ r.r = ioutil.NewReadCloser(buf, reader)
+
+ return nil
+}
+
+// Encode encodes an UploadPackResponse.
+func (r *UploadPackResponse) Encode(w io.Writer) (err error) {
+ if r.isShallow {
+ if err := r.ShallowUpdate.Encode(w); err != nil {
+ return err
+ }
+ }
+
+ if err := r.ServerResponse.Encode(w, r.isMultiACK); err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(r.r, &err)
+ _, err = io.Copy(w, r.r)
+ return err
+}
+
+// Read reads the packfile data, if the request was done with any Sideband
+// capability the content read should be demultiplexed. If the methods wasn't
+// called before the ErrUploadPackResponseNotDecoded will be return
+func (r *UploadPackResponse) Read(p []byte) (int, error) {
+ if r.r == nil {
+ return 0, ErrUploadPackResponseNotDecoded
+ }
+
+ return r.r.Read(p)
+}
+
+// Close the underlying reader, if any
+func (r *UploadPackResponse) Close() error {
+ if r.r == nil {
+ return nil
+ }
+
+ return r.r.Close()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/reference.go b/vendor/github.com/go-git/go-git/v5/plumbing/reference.go
new file mode 100644
index 00000000..ddba9302
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/reference.go
@@ -0,0 +1,315 @@
+package plumbing
+
+import (
+ "errors"
+ "fmt"
+ "regexp"
+ "strings"
+)
+
+const (
+ refPrefix = "refs/"
+ refHeadPrefix = refPrefix + "heads/"
+ refTagPrefix = refPrefix + "tags/"
+ refRemotePrefix = refPrefix + "remotes/"
+ refNotePrefix = refPrefix + "notes/"
+ symrefPrefix = "ref: "
+)
+
+// RefRevParseRules are a set of rules to parse references into short names, or expand into a full reference.
+// These are the same rules as used by git in shorten_unambiguous_ref and expand_ref.
+// See: https://github.com/git/git/blob/e0aaa1b6532cfce93d87af9bc813fb2e7a7ce9d7/refs.c#L417
+var RefRevParseRules = []string{
+ "%s",
+ "refs/%s",
+ "refs/tags/%s",
+ "refs/heads/%s",
+ "refs/remotes/%s",
+ "refs/remotes/%s/HEAD",
+}
+
+var (
+ ErrReferenceNotFound = errors.New("reference not found")
+
+ // ErrInvalidReferenceName is returned when a reference name is invalid.
+ ErrInvalidReferenceName = errors.New("invalid reference name")
+)
+
+// ReferenceType reference type's
+type ReferenceType int8
+
+const (
+ InvalidReference ReferenceType = 0
+ HashReference ReferenceType = 1
+ SymbolicReference ReferenceType = 2
+)
+
+func (r ReferenceType) String() string {
+ switch r {
+ case InvalidReference:
+ return "invalid-reference"
+ case HashReference:
+ return "hash-reference"
+ case SymbolicReference:
+ return "symbolic-reference"
+ }
+
+ return ""
+}
+
+// ReferenceName reference name's
+type ReferenceName string
+
+// NewBranchReferenceName returns a reference name describing a branch based on
+// his short name.
+func NewBranchReferenceName(name string) ReferenceName {
+ return ReferenceName(refHeadPrefix + name)
+}
+
+// NewNoteReferenceName returns a reference name describing a note based on his
+// short name.
+func NewNoteReferenceName(name string) ReferenceName {
+ return ReferenceName(refNotePrefix + name)
+}
+
+// NewRemoteReferenceName returns a reference name describing a remote branch
+// based on his short name and the remote name.
+func NewRemoteReferenceName(remote, name string) ReferenceName {
+ return ReferenceName(refRemotePrefix + fmt.Sprintf("%s/%s", remote, name))
+}
+
+// NewRemoteHEADReferenceName returns a reference name describing a the HEAD
+// branch of a remote.
+func NewRemoteHEADReferenceName(remote string) ReferenceName {
+ return ReferenceName(refRemotePrefix + fmt.Sprintf("%s/%s", remote, HEAD))
+}
+
+// NewTagReferenceName returns a reference name describing a tag based on short
+// his name.
+func NewTagReferenceName(name string) ReferenceName {
+ return ReferenceName(refTagPrefix + name)
+}
+
+// IsBranch check if a reference is a branch
+func (r ReferenceName) IsBranch() bool {
+ return strings.HasPrefix(string(r), refHeadPrefix)
+}
+
+// IsNote check if a reference is a note
+func (r ReferenceName) IsNote() bool {
+ return strings.HasPrefix(string(r), refNotePrefix)
+}
+
+// IsRemote check if a reference is a remote
+func (r ReferenceName) IsRemote() bool {
+ return strings.HasPrefix(string(r), refRemotePrefix)
+}
+
+// IsTag check if a reference is a tag
+func (r ReferenceName) IsTag() bool {
+ return strings.HasPrefix(string(r), refTagPrefix)
+}
+
+func (r ReferenceName) String() string {
+ return string(r)
+}
+
+// Short returns the short name of a ReferenceName
+func (r ReferenceName) Short() string {
+ s := string(r)
+ res := s
+ for _, format := range RefRevParseRules[1:] {
+ _, err := fmt.Sscanf(s, format, &res)
+ if err == nil {
+ continue
+ }
+ }
+
+ return res
+}
+
+var (
+ ctrlSeqs = regexp.MustCompile(`[\000-\037\177]`)
+)
+
+// Validate validates a reference name.
+// This follows the git-check-ref-format rules.
+// See https://git-scm.com/docs/git-check-ref-format
+//
+// It is important to note that this function does not check if the reference
+// exists in the repository.
+// It only checks if the reference name is valid.
+// This functions does not support the --refspec-pattern, --normalize, and
+// --allow-onelevel options.
+//
+// Git imposes the following rules on how references are named:
+//
+// 1. They can include slash / for hierarchical (directory) grouping, but no
+// slash-separated component can begin with a dot . or end with the
+// sequence .lock.
+// 2. They must contain at least one /. This enforces the presence of a
+// category like heads/, tags/ etc. but the actual names are not
+// restricted. If the --allow-onelevel option is used, this rule is
+// waived.
+// 3. They cannot have two consecutive dots .. anywhere.
+// 4. They cannot have ASCII control characters (i.e. bytes whose values are
+// lower than \040, or \177 DEL), space, tilde ~, caret ^, or colon :
+// anywhere.
+// 5. They cannot have question-mark ?, asterisk *, or open bracket [
+// anywhere. See the --refspec-pattern option below for an exception to this
+// rule.
+// 6. They cannot begin or end with a slash / or contain multiple consecutive
+// slashes (see the --normalize option below for an exception to this rule).
+// 7. They cannot end with a dot ..
+// 8. They cannot contain a sequence @{.
+// 9. They cannot be the single character @.
+// 10. They cannot contain a \.
+func (r ReferenceName) Validate() error {
+ s := string(r)
+ if len(s) == 0 {
+ return ErrInvalidReferenceName
+ }
+
+ // HEAD is a special case
+ if r == HEAD {
+ return nil
+ }
+
+ // rule 7
+ if strings.HasSuffix(s, ".") {
+ return ErrInvalidReferenceName
+ }
+
+ // rule 2
+ parts := strings.Split(s, "/")
+ if len(parts) < 2 {
+ return ErrInvalidReferenceName
+ }
+
+ isBranch := r.IsBranch()
+ isTag := r.IsTag()
+ for _, part := range parts {
+ // rule 6
+ if len(part) == 0 {
+ return ErrInvalidReferenceName
+ }
+
+ if strings.HasPrefix(part, ".") || // rule 1
+ strings.Contains(part, "..") || // rule 3
+ ctrlSeqs.MatchString(part) || // rule 4
+ strings.ContainsAny(part, "~^:?*[ \t\n") || // rule 4 & 5
+ strings.Contains(part, "@{") || // rule 8
+ part == "@" || // rule 9
+ strings.Contains(part, "\\") || // rule 10
+ strings.HasSuffix(part, ".lock") { // rule 1
+ return ErrInvalidReferenceName
+ }
+
+ if (isBranch || isTag) && strings.HasPrefix(part, "-") { // branches & tags can't start with -
+ return ErrInvalidReferenceName
+ }
+ }
+
+ return nil
+}
+
+const (
+ HEAD ReferenceName = "HEAD"
+ Master ReferenceName = "refs/heads/master"
+ Main ReferenceName = "refs/heads/main"
+)
+
+// Reference is a representation of git reference
+type Reference struct {
+ t ReferenceType
+ n ReferenceName
+ h Hash
+ target ReferenceName
+}
+
+// NewReferenceFromStrings creates a reference from name and target as string,
+// the resulting reference can be a SymbolicReference or a HashReference base
+// on the target provided
+func NewReferenceFromStrings(name, target string) *Reference {
+ n := ReferenceName(name)
+
+ if strings.HasPrefix(target, symrefPrefix) {
+ target := ReferenceName(target[len(symrefPrefix):])
+ return NewSymbolicReference(n, target)
+ }
+
+ return NewHashReference(n, NewHash(target))
+}
+
+// NewSymbolicReference creates a new SymbolicReference reference
+func NewSymbolicReference(n, target ReferenceName) *Reference {
+ return &Reference{
+ t: SymbolicReference,
+ n: n,
+ target: target,
+ }
+}
+
+// NewHashReference creates a new HashReference reference
+func NewHashReference(n ReferenceName, h Hash) *Reference {
+ return &Reference{
+ t: HashReference,
+ n: n,
+ h: h,
+ }
+}
+
+// Type returns the type of a reference
+func (r *Reference) Type() ReferenceType {
+ return r.t
+}
+
+// Name returns the name of a reference
+func (r *Reference) Name() ReferenceName {
+ return r.n
+}
+
+// Hash returns the hash of a hash reference
+func (r *Reference) Hash() Hash {
+ return r.h
+}
+
+// Target returns the target of a symbolic reference
+func (r *Reference) Target() ReferenceName {
+ return r.target
+}
+
+// Strings dump a reference as a [2]string
+func (r *Reference) Strings() [2]string {
+ var o [2]string
+ o[0] = r.Name().String()
+
+ switch r.Type() {
+ case HashReference:
+ o[1] = r.Hash().String()
+ case SymbolicReference:
+ o[1] = symrefPrefix + r.Target().String()
+ }
+
+ return o
+}
+
+func (r *Reference) String() string {
+ ref := ""
+ switch r.Type() {
+ case HashReference:
+ ref = r.Hash().String()
+ case SymbolicReference:
+ ref = symrefPrefix + r.Target().String()
+ default:
+ return ""
+ }
+
+ name := r.Name().String()
+ var v strings.Builder
+ v.Grow(len(ref) + len(name) + 1)
+ v.WriteString(ref)
+ v.WriteString(" ")
+ v.WriteString(name)
+ return v.String()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/revision.go b/vendor/github.com/go-git/go-git/v5/plumbing/revision.go
new file mode 100644
index 00000000..5f053b20
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/revision.go
@@ -0,0 +1,11 @@
+package plumbing
+
+// Revision represents a git revision
+// to get more details about git revisions
+// please check git manual page :
+// https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
+type Revision string
+
+func (r Revision) String() string {
+ return string(r)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/revlist/revlist.go b/vendor/github.com/go-git/go-git/v5/plumbing/revlist/revlist.go
new file mode 100644
index 00000000..b9109870
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/revlist/revlist.go
@@ -0,0 +1,230 @@
+// Package revlist provides support to access the ancestors of commits, in a
+// similar way as the git-rev-list command.
+package revlist
+
+import (
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+// Objects applies a complementary set. It gets all the hashes from all
+// the reachable objects from the given objects. Ignore param are object hashes
+// that we want to ignore on the result. All that objects must be accessible
+// from the object storer.
+func Objects(
+ s storer.EncodedObjectStorer,
+ objs,
+ ignore []plumbing.Hash,
+) ([]plumbing.Hash, error) {
+ return ObjectsWithStorageForIgnores(s, s, objs, ignore)
+}
+
+// ObjectsWithStorageForIgnores is the same as Objects, but a
+// secondary storage layer can be provided, to be used to finding the
+// full set of objects to be ignored while finding the reachable
+// objects. This is useful when the main `s` storage layer is slow
+// and/or remote, while the ignore list is available somewhere local.
+func ObjectsWithStorageForIgnores(
+ s, ignoreStore storer.EncodedObjectStorer,
+ objs,
+ ignore []plumbing.Hash,
+) ([]plumbing.Hash, error) {
+ ignore, err := objects(ignoreStore, ignore, nil, true)
+ if err != nil {
+ return nil, err
+ }
+
+ return objects(s, objs, ignore, false)
+}
+
+func objects(
+ s storer.EncodedObjectStorer,
+ objects,
+ ignore []plumbing.Hash,
+ allowMissingObjects bool,
+) ([]plumbing.Hash, error) {
+ seen := hashListToSet(ignore)
+ result := make(map[plumbing.Hash]bool)
+ visited := make(map[plumbing.Hash]bool)
+
+ walkerFunc := func(h plumbing.Hash) {
+ if !seen[h] {
+ result[h] = true
+ seen[h] = true
+ }
+ }
+
+ for _, h := range objects {
+ if err := processObject(s, h, seen, visited, ignore, walkerFunc); err != nil {
+ if allowMissingObjects && err == plumbing.ErrObjectNotFound {
+ continue
+ }
+
+ return nil, err
+ }
+ }
+
+ return hashSetToList(result), nil
+}
+
+// processObject obtains the object using the hash an process it depending of its type
+func processObject(
+ s storer.EncodedObjectStorer,
+ h plumbing.Hash,
+ seen map[plumbing.Hash]bool,
+ visited map[plumbing.Hash]bool,
+ ignore []plumbing.Hash,
+ walkerFunc func(h plumbing.Hash),
+) error {
+ if seen[h] {
+ return nil
+ }
+
+ o, err := s.EncodedObject(plumbing.AnyObject, h)
+ if err != nil {
+ return err
+ }
+
+ do, err := object.DecodeObject(s, o)
+ if err != nil {
+ return err
+ }
+
+ switch do := do.(type) {
+ case *object.Commit:
+ return reachableObjects(do, seen, visited, ignore, walkerFunc)
+ case *object.Tree:
+ return iterateCommitTrees(seen, do, walkerFunc)
+ case *object.Tag:
+ walkerFunc(do.Hash)
+ return processObject(s, do.Target, seen, visited, ignore, walkerFunc)
+ case *object.Blob:
+ walkerFunc(do.Hash)
+ default:
+ return fmt.Errorf("object type not valid: %s. "+
+ "Object reference: %s", o.Type(), o.Hash())
+ }
+
+ return nil
+}
+
+// reachableObjects returns, using the callback function, all the reachable
+// objects from the specified commit. To avoid to iterate over seen commits,
+// if a commit hash is into the 'seen' set, we will not iterate all his trees
+// and blobs objects.
+func reachableObjects(
+ commit *object.Commit,
+ seen map[plumbing.Hash]bool,
+ visited map[plumbing.Hash]bool,
+ ignore []plumbing.Hash,
+ cb func(h plumbing.Hash),
+) error {
+ i := object.NewCommitPreorderIter(commit, seen, ignore)
+ pending := make(map[plumbing.Hash]bool)
+ addPendingParents(pending, visited, commit)
+ for {
+ commit, err := i.Next()
+ if err == io.EOF {
+ break
+ }
+
+ if err != nil {
+ return err
+ }
+
+ if pending[commit.Hash] {
+ delete(pending, commit.Hash)
+ }
+
+ addPendingParents(pending, visited, commit)
+
+ if visited[commit.Hash] && len(pending) == 0 {
+ break
+ }
+
+ if seen[commit.Hash] {
+ continue
+ }
+
+ cb(commit.Hash)
+
+ tree, err := commit.Tree()
+ if err != nil {
+ return err
+ }
+
+ if err := iterateCommitTrees(seen, tree, cb); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func addPendingParents(pending, visited map[plumbing.Hash]bool, commit *object.Commit) {
+ for _, p := range commit.ParentHashes {
+ if !visited[p] {
+ pending[p] = true
+ }
+ }
+}
+
+// iterateCommitTrees iterate all reachable trees from the given commit
+func iterateCommitTrees(
+ seen map[plumbing.Hash]bool,
+ tree *object.Tree,
+ cb func(h plumbing.Hash),
+) error {
+ if seen[tree.Hash] {
+ return nil
+ }
+
+ cb(tree.Hash)
+
+ treeWalker := object.NewTreeWalker(tree, true, seen)
+
+ for {
+ _, e, err := treeWalker.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ if e.Mode == filemode.Submodule {
+ continue
+ }
+
+ if seen[e.Hash] {
+ continue
+ }
+
+ cb(e.Hash)
+ }
+
+ return nil
+}
+
+func hashSetToList(hashes map[plumbing.Hash]bool) []plumbing.Hash {
+ var result []plumbing.Hash
+ for key := range hashes {
+ result = append(result, key)
+ }
+
+ return result
+}
+
+func hashListToSet(hashes []plumbing.Hash) map[plumbing.Hash]bool {
+ result := make(map[plumbing.Hash]bool)
+ for _, h := range hashes {
+ result[h] = true
+ }
+
+ return result
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/doc.go b/vendor/github.com/go-git/go-git/v5/plumbing/storer/doc.go
new file mode 100644
index 00000000..4d4f179c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/storer/doc.go
@@ -0,0 +1,2 @@
+// Package storer defines the interfaces to store objects, references, etc.
+package storer
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/index.go b/vendor/github.com/go-git/go-git/v5/plumbing/storer/index.go
new file mode 100644
index 00000000..33113949
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/storer/index.go
@@ -0,0 +1,9 @@
+package storer
+
+import "github.com/go-git/go-git/v5/plumbing/format/index"
+
+// IndexStorer generic storage of index.Index
+type IndexStorer interface {
+ SetIndex(*index.Index) error
+ Index() (*index.Index, error)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/object.go b/vendor/github.com/go-git/go-git/v5/plumbing/storer/object.go
new file mode 100644
index 00000000..126b3742
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/storer/object.go
@@ -0,0 +1,289 @@
+package storer
+
+import (
+ "errors"
+ "io"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+var (
+ //ErrStop is used to stop a ForEach function in an Iter
+ ErrStop = errors.New("stop iter")
+)
+
+// EncodedObjectStorer generic storage of objects
+type EncodedObjectStorer interface {
+ // NewEncodedObject returns a new plumbing.EncodedObject, the real type
+ // of the object can be a custom implementation or the default one,
+ // plumbing.MemoryObject.
+ NewEncodedObject() plumbing.EncodedObject
+ // SetEncodedObject saves an object into the storage, the object should
+ // be create with the NewEncodedObject, method, and file if the type is
+ // not supported.
+ SetEncodedObject(plumbing.EncodedObject) (plumbing.Hash, error)
+ // EncodedObject gets an object by hash with the given
+ // plumbing.ObjectType. Implementors should return
+ // (nil, plumbing.ErrObjectNotFound) if an object doesn't exist with
+ // both the given hash and object type.
+ //
+ // Valid plumbing.ObjectType values are CommitObject, BlobObject, TagObject,
+ // TreeObject and AnyObject. If plumbing.AnyObject is given, the object must
+ // be looked up regardless of its type.
+ EncodedObject(plumbing.ObjectType, plumbing.Hash) (plumbing.EncodedObject, error)
+ // IterObjects returns a custom EncodedObjectStorer over all the object
+ // on the storage.
+ //
+ // Valid plumbing.ObjectType values are CommitObject, BlobObject, TagObject,
+ IterEncodedObjects(plumbing.ObjectType) (EncodedObjectIter, error)
+ // HasEncodedObject returns ErrObjNotFound if the object doesn't
+ // exist. If the object does exist, it returns nil.
+ HasEncodedObject(plumbing.Hash) error
+ // EncodedObjectSize returns the plaintext size of the encoded object.
+ EncodedObjectSize(plumbing.Hash) (int64, error)
+ AddAlternate(remote string) error
+}
+
+// DeltaObjectStorer is an EncodedObjectStorer that can return delta
+// objects.
+type DeltaObjectStorer interface {
+ // DeltaObject is the same as EncodedObject but without resolving deltas.
+ // Deltas will be returned as plumbing.DeltaObject instances.
+ DeltaObject(plumbing.ObjectType, plumbing.Hash) (plumbing.EncodedObject, error)
+}
+
+// Transactioner is a optional method for ObjectStorer, it enables transactional read and write
+// operations.
+type Transactioner interface {
+ // Begin starts a transaction.
+ Begin() Transaction
+}
+
+// LooseObjectStorer is an optional interface for managing "loose"
+// objects, i.e. those not in packfiles.
+type LooseObjectStorer interface {
+ // ForEachObjectHash iterates over all the (loose) object hashes
+ // in the repository without necessarily having to read those objects.
+ // Objects only inside pack files may be omitted.
+ // If ErrStop is sent the iteration is stop but no error is returned.
+ ForEachObjectHash(func(plumbing.Hash) error) error
+ // LooseObjectTime looks up the (m)time associated with the
+ // loose object (that is not in a pack file). Some
+ // implementations (e.g. without loose objects)
+ // always return an error.
+ LooseObjectTime(plumbing.Hash) (time.Time, error)
+ // DeleteLooseObject deletes a loose object if it exists.
+ DeleteLooseObject(plumbing.Hash) error
+}
+
+// PackedObjectStorer is an optional interface for managing objects in
+// packfiles.
+type PackedObjectStorer interface {
+ // ObjectPacks returns hashes of object packs if the underlying
+ // implementation has pack files.
+ ObjectPacks() ([]plumbing.Hash, error)
+ // DeleteOldObjectPackAndIndex deletes an object pack and the corresponding index file if they exist.
+ // Deletion is only performed if the pack is older than the supplied time (or the time is zero).
+ DeleteOldObjectPackAndIndex(plumbing.Hash, time.Time) error
+}
+
+// PackfileWriter is an optional method for ObjectStorer, it enables directly writing
+// a packfile to storage.
+type PackfileWriter interface {
+ // PackfileWriter returns a writer for writing a packfile to the storage
+ //
+ // If the Storer not implements PackfileWriter the objects should be written
+ // using the Set method.
+ PackfileWriter() (io.WriteCloser, error)
+}
+
+// EncodedObjectIter is a generic closable interface for iterating over objects.
+type EncodedObjectIter interface {
+ Next() (plumbing.EncodedObject, error)
+ ForEach(func(plumbing.EncodedObject) error) error
+ Close()
+}
+
+// Transaction is an in-progress storage transaction. A transaction must end
+// with a call to Commit or Rollback.
+type Transaction interface {
+ SetEncodedObject(plumbing.EncodedObject) (plumbing.Hash, error)
+ EncodedObject(plumbing.ObjectType, plumbing.Hash) (plumbing.EncodedObject, error)
+ Commit() error
+ Rollback() error
+}
+
+// EncodedObjectLookupIter implements EncodedObjectIter. It iterates over a
+// series of object hashes and yields their associated objects by retrieving
+// each one from object storage. The retrievals are lazy and only occur when the
+// iterator moves forward with a call to Next().
+//
+// The EncodedObjectLookupIter must be closed with a call to Close() when it is
+// no longer needed.
+type EncodedObjectLookupIter struct {
+ storage EncodedObjectStorer
+ series []plumbing.Hash
+ t plumbing.ObjectType
+ pos int
+}
+
+// NewEncodedObjectLookupIter returns an object iterator given an object storage
+// and a slice of object hashes.
+func NewEncodedObjectLookupIter(
+ storage EncodedObjectStorer, t plumbing.ObjectType, series []plumbing.Hash) *EncodedObjectLookupIter {
+ return &EncodedObjectLookupIter{
+ storage: storage,
+ series: series,
+ t: t,
+ }
+}
+
+// Next returns the next object from the iterator. If the iterator has reached
+// the end it will return io.EOF as an error. If the object can't be found in
+// the object storage, it will return plumbing.ErrObjectNotFound as an error.
+// If the object is retrieved successfully error will be nil.
+func (iter *EncodedObjectLookupIter) Next() (plumbing.EncodedObject, error) {
+ if iter.pos >= len(iter.series) {
+ return nil, io.EOF
+ }
+
+ hash := iter.series[iter.pos]
+ obj, err := iter.storage.EncodedObject(iter.t, hash)
+ if err == nil {
+ iter.pos++
+ }
+
+ return obj, err
+}
+
+// ForEach call the cb function for each object contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *EncodedObjectLookupIter) ForEach(cb func(plumbing.EncodedObject) error) error {
+ return ForEachIterator(iter, cb)
+}
+
+// Close releases any resources used by the iterator.
+func (iter *EncodedObjectLookupIter) Close() {
+ iter.pos = len(iter.series)
+}
+
+// EncodedObjectSliceIter implements EncodedObjectIter. It iterates over a
+// series of objects stored in a slice and yields each one in turn when Next()
+// is called.
+//
+// The EncodedObjectSliceIter must be closed with a call to Close() when it is
+// no longer needed.
+type EncodedObjectSliceIter struct {
+ series []plumbing.EncodedObject
+}
+
+// NewEncodedObjectSliceIter returns an object iterator for the given slice of
+// objects.
+func NewEncodedObjectSliceIter(series []plumbing.EncodedObject) *EncodedObjectSliceIter {
+ return &EncodedObjectSliceIter{
+ series: series,
+ }
+}
+
+// Next returns the next object from the iterator. If the iterator has reached
+// the end it will return io.EOF as an error. If the object is retrieved
+// successfully error will be nil.
+func (iter *EncodedObjectSliceIter) Next() (plumbing.EncodedObject, error) {
+ if len(iter.series) == 0 {
+ return nil, io.EOF
+ }
+
+ obj := iter.series[0]
+ iter.series = iter.series[1:]
+
+ return obj, nil
+}
+
+// ForEach call the cb function for each object contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *EncodedObjectSliceIter) ForEach(cb func(plumbing.EncodedObject) error) error {
+ return ForEachIterator(iter, cb)
+}
+
+// Close releases any resources used by the iterator.
+func (iter *EncodedObjectSliceIter) Close() {
+ iter.series = []plumbing.EncodedObject{}
+}
+
+// MultiEncodedObjectIter implements EncodedObjectIter. It iterates over several
+// EncodedObjectIter,
+//
+// The MultiObjectIter must be closed with a call to Close() when it is no
+// longer needed.
+type MultiEncodedObjectIter struct {
+ iters []EncodedObjectIter
+}
+
+// NewMultiEncodedObjectIter returns an object iterator for the given slice of
+// EncodedObjectIters.
+func NewMultiEncodedObjectIter(iters []EncodedObjectIter) EncodedObjectIter {
+ return &MultiEncodedObjectIter{iters: iters}
+}
+
+// Next returns the next object from the iterator, if one iterator reach io.EOF
+// is removed and the next one is used.
+func (iter *MultiEncodedObjectIter) Next() (plumbing.EncodedObject, error) {
+ if len(iter.iters) == 0 {
+ return nil, io.EOF
+ }
+
+ obj, err := iter.iters[0].Next()
+ if err == io.EOF {
+ iter.iters[0].Close()
+ iter.iters = iter.iters[1:]
+ return iter.Next()
+ }
+
+ return obj, err
+}
+
+// ForEach call the cb function for each object contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *MultiEncodedObjectIter) ForEach(cb func(plumbing.EncodedObject) error) error {
+ return ForEachIterator(iter, cb)
+}
+
+// Close releases any resources used by the iterator.
+func (iter *MultiEncodedObjectIter) Close() {
+ for _, i := range iter.iters {
+ i.Close()
+ }
+}
+
+type bareIterator interface {
+ Next() (plumbing.EncodedObject, error)
+ Close()
+}
+
+// ForEachIterator is a helper function to build iterators without need to
+// rewrite the same ForEach function each time.
+func ForEachIterator(iter bareIterator, cb func(plumbing.EncodedObject) error) error {
+ defer iter.Close()
+ for {
+ obj, err := iter.Next()
+ if err != nil {
+ if err == io.EOF {
+ return nil
+ }
+
+ return err
+ }
+
+ if err := cb(obj); err != nil {
+ if err == ErrStop {
+ return nil
+ }
+
+ return err
+ }
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/reference.go b/vendor/github.com/go-git/go-git/v5/plumbing/storer/reference.go
new file mode 100644
index 00000000..1d74ef3c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/storer/reference.go
@@ -0,0 +1,240 @@
+package storer
+
+import (
+ "errors"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+const MaxResolveRecursion = 1024
+
+// ErrMaxResolveRecursion is returned by ResolveReference is MaxResolveRecursion
+// is exceeded
+var ErrMaxResolveRecursion = errors.New("max. recursion level reached")
+
+// ReferenceStorer is a generic storage of references.
+type ReferenceStorer interface {
+ SetReference(*plumbing.Reference) error
+ // CheckAndSetReference sets the reference `new`, but if `old` is
+ // not `nil`, it first checks that the current stored value for
+ // `old.Name()` matches the given reference value in `old`. If
+ // not, it returns an error and doesn't update `new`.
+ CheckAndSetReference(new, old *plumbing.Reference) error
+ Reference(plumbing.ReferenceName) (*plumbing.Reference, error)
+ IterReferences() (ReferenceIter, error)
+ RemoveReference(plumbing.ReferenceName) error
+ CountLooseRefs() (int, error)
+ PackRefs() error
+}
+
+// ReferenceIter is a generic closable interface for iterating over references.
+type ReferenceIter interface {
+ Next() (*plumbing.Reference, error)
+ ForEach(func(*plumbing.Reference) error) error
+ Close()
+}
+
+type referenceFilteredIter struct {
+ ff func(r *plumbing.Reference) bool
+ iter ReferenceIter
+}
+
+// NewReferenceFilteredIter returns a reference iterator for the given reference
+// Iterator. This iterator will iterate only references that accomplish the
+// provided function.
+func NewReferenceFilteredIter(
+ ff func(r *plumbing.Reference) bool, iter ReferenceIter) ReferenceIter {
+ return &referenceFilteredIter{ff, iter}
+}
+
+// Next returns the next reference from the iterator. If the iterator has reached
+// the end it will return io.EOF as an error.
+func (iter *referenceFilteredIter) Next() (*plumbing.Reference, error) {
+ for {
+ r, err := iter.iter.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ if iter.ff(r) {
+ return r, nil
+ }
+
+ continue
+ }
+}
+
+// ForEach call the cb function for each reference contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stopped but no error is returned. The iterator is closed.
+func (iter *referenceFilteredIter) ForEach(cb func(*plumbing.Reference) error) error {
+ defer iter.Close()
+ for {
+ r, err := iter.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ if err := cb(r); err != nil {
+ if err == ErrStop {
+ break
+ }
+
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Close releases any resources used by the iterator.
+func (iter *referenceFilteredIter) Close() {
+ iter.iter.Close()
+}
+
+// ReferenceSliceIter implements ReferenceIter. It iterates over a series of
+// references stored in a slice and yields each one in turn when Next() is
+// called.
+//
+// The ReferenceSliceIter must be closed with a call to Close() when it is no
+// longer needed.
+type ReferenceSliceIter struct {
+ series []*plumbing.Reference
+ pos int
+}
+
+// NewReferenceSliceIter returns a reference iterator for the given slice of
+// objects.
+func NewReferenceSliceIter(series []*plumbing.Reference) ReferenceIter {
+ return &ReferenceSliceIter{
+ series: series,
+ }
+}
+
+// Next returns the next reference from the iterator. If the iterator has
+// reached the end it will return io.EOF as an error.
+func (iter *ReferenceSliceIter) Next() (*plumbing.Reference, error) {
+ if iter.pos >= len(iter.series) {
+ return nil, io.EOF
+ }
+
+ obj := iter.series[iter.pos]
+ iter.pos++
+ return obj, nil
+}
+
+// ForEach call the cb function for each reference contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *ReferenceSliceIter) ForEach(cb func(*plumbing.Reference) error) error {
+ return forEachReferenceIter(iter, cb)
+}
+
+type bareReferenceIterator interface {
+ Next() (*plumbing.Reference, error)
+ Close()
+}
+
+func forEachReferenceIter(iter bareReferenceIterator, cb func(*plumbing.Reference) error) error {
+ defer iter.Close()
+ for {
+ obj, err := iter.Next()
+ if err != nil {
+ if err == io.EOF {
+ return nil
+ }
+
+ return err
+ }
+
+ if err := cb(obj); err != nil {
+ if err == ErrStop {
+ return nil
+ }
+
+ return err
+ }
+ }
+}
+
+// Close releases any resources used by the iterator.
+func (iter *ReferenceSliceIter) Close() {
+ iter.pos = len(iter.series)
+}
+
+// MultiReferenceIter implements ReferenceIter. It iterates over several
+// ReferenceIter,
+//
+// The MultiReferenceIter must be closed with a call to Close() when it is no
+// longer needed.
+type MultiReferenceIter struct {
+ iters []ReferenceIter
+}
+
+// NewMultiReferenceIter returns an reference iterator for the given slice of
+// EncodedObjectIters.
+func NewMultiReferenceIter(iters []ReferenceIter) ReferenceIter {
+ return &MultiReferenceIter{iters: iters}
+}
+
+// Next returns the next reference from the iterator, if one iterator reach
+// io.EOF is removed and the next one is used.
+func (iter *MultiReferenceIter) Next() (*plumbing.Reference, error) {
+ if len(iter.iters) == 0 {
+ return nil, io.EOF
+ }
+
+ obj, err := iter.iters[0].Next()
+ if err == io.EOF {
+ iter.iters[0].Close()
+ iter.iters = iter.iters[1:]
+ return iter.Next()
+ }
+
+ return obj, err
+}
+
+// ForEach call the cb function for each reference contained on this iter until
+// an error happens or the end of the iter is reached. If ErrStop is sent
+// the iteration is stop but no error is returned. The iterator is closed.
+func (iter *MultiReferenceIter) ForEach(cb func(*plumbing.Reference) error) error {
+ return forEachReferenceIter(iter, cb)
+}
+
+// Close releases any resources used by the iterator.
+func (iter *MultiReferenceIter) Close() {
+ for _, i := range iter.iters {
+ i.Close()
+ }
+}
+
+// ResolveReference resolves a SymbolicReference to a HashReference.
+func ResolveReference(s ReferenceStorer, n plumbing.ReferenceName) (*plumbing.Reference, error) {
+ r, err := s.Reference(n)
+ if err != nil || r == nil {
+ return r, err
+ }
+ return resolveReference(s, r, 0)
+}
+
+func resolveReference(s ReferenceStorer, r *plumbing.Reference, recursion int) (*plumbing.Reference, error) {
+ if r.Type() != plumbing.SymbolicReference {
+ return r, nil
+ }
+
+ if recursion > MaxResolveRecursion {
+ return nil, ErrMaxResolveRecursion
+ }
+
+ t, err := s.Reference(r.Target())
+ if err != nil {
+ return nil, err
+ }
+
+ recursion++
+ return resolveReference(s, t, recursion)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/shallow.go b/vendor/github.com/go-git/go-git/v5/plumbing/storer/shallow.go
new file mode 100644
index 00000000..39ef5ea5
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/storer/shallow.go
@@ -0,0 +1,10 @@
+package storer
+
+import "github.com/go-git/go-git/v5/plumbing"
+
+// ShallowStorer is a storage of references to shallow commits by hash,
+// meaning that these commits have missing parents because of a shallow fetch.
+type ShallowStorer interface {
+ SetShallow([]plumbing.Hash) error
+ Shallow() ([]plumbing.Hash, error)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/storer/storer.go b/vendor/github.com/go-git/go-git/v5/plumbing/storer/storer.go
new file mode 100644
index 00000000..c7bc65a0
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/storer/storer.go
@@ -0,0 +1,15 @@
+package storer
+
+// Storer is a basic storer for encoded objects and references.
+type Storer interface {
+ EncodedObjectStorer
+ ReferenceStorer
+}
+
+// Initializer should be implemented by storers that require to perform any
+// operation when creating a new repository (i.e. git init).
+type Initializer interface {
+ // Init performs initialization of the storer and returns the error, if
+ // any.
+ Init() error
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/client/client.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/client/client.go
new file mode 100644
index 00000000..1948c230
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/client/client.go
@@ -0,0 +1,51 @@
+// Package client contains helper function to deal with the different client
+// protocols.
+package client
+
+import (
+ "fmt"
+
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/plumbing/transport/file"
+ "github.com/go-git/go-git/v5/plumbing/transport/git"
+ "github.com/go-git/go-git/v5/plumbing/transport/http"
+ "github.com/go-git/go-git/v5/plumbing/transport/ssh"
+)
+
+// Protocols are the protocols supported by default.
+var Protocols = map[string]transport.Transport{
+ "http": http.DefaultClient,
+ "https": http.DefaultClient,
+ "ssh": ssh.DefaultClient,
+ "git": git.DefaultClient,
+ "file": file.DefaultClient,
+}
+
+// InstallProtocol adds or modifies an existing protocol.
+func InstallProtocol(scheme string, c transport.Transport) {
+ if c == nil {
+ delete(Protocols, scheme)
+ return
+ }
+
+ Protocols[scheme] = c
+}
+
+// NewClient returns the appropriate client among of the set of known protocols:
+// http://, https://, ssh:// and file://.
+// See `InstallProtocol` to add or modify protocols.
+func NewClient(endpoint *transport.Endpoint) (transport.Transport, error) {
+ return getTransport(endpoint)
+}
+
+func getTransport(endpoint *transport.Endpoint) (transport.Transport, error) {
+ f, ok := Protocols[endpoint.Protocol]
+ if !ok {
+ return nil, fmt.Errorf("unsupported scheme %q", endpoint.Protocol)
+ }
+
+ if f == nil {
+ return nil, fmt.Errorf("malformed client for scheme %q, client is defined as nil", endpoint.Protocol)
+ }
+ return f, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go
new file mode 100644
index 00000000..b05437fb
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go
@@ -0,0 +1,320 @@
+// Package transport includes the implementation for different transport
+// protocols.
+//
+// `Client` can be used to fetch and send packfiles to a git server.
+// The `client` package provides higher level functions to instantiate the
+// appropriate `Client` based on the repository URL.
+//
+// go-git supports HTTP and SSH (see `Protocols`), but you can also install
+// your own protocols (see the `client` package).
+//
+// Each protocol has its own implementation of `Client`, but you should
+// generally not use them directly, use `client.NewClient` instead.
+package transport
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net/url"
+ "strconv"
+ "strings"
+
+ giturl "github.com/go-git/go-git/v5/internal/url"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+)
+
+var (
+ ErrRepositoryNotFound = errors.New("repository not found")
+ ErrEmptyRemoteRepository = errors.New("remote repository is empty")
+ ErrAuthenticationRequired = errors.New("authentication required")
+ ErrAuthorizationFailed = errors.New("authorization failed")
+ ErrEmptyUploadPackRequest = errors.New("empty git-upload-pack given")
+ ErrInvalidAuthMethod = errors.New("invalid auth method")
+ ErrAlreadyConnected = errors.New("session already established")
+)
+
+const (
+ UploadPackServiceName = "git-upload-pack"
+ ReceivePackServiceName = "git-receive-pack"
+)
+
+// Transport can initiate git-upload-pack and git-receive-pack processes.
+// It is implemented both by the client and the server, making this a RPC.
+type Transport interface {
+ // NewUploadPackSession starts a git-upload-pack session for an endpoint.
+ NewUploadPackSession(*Endpoint, AuthMethod) (UploadPackSession, error)
+ // NewReceivePackSession starts a git-receive-pack session for an endpoint.
+ NewReceivePackSession(*Endpoint, AuthMethod) (ReceivePackSession, error)
+}
+
+type Session interface {
+ // AdvertisedReferences retrieves the advertised references for a
+ // repository.
+ // If the repository does not exist, returns ErrRepositoryNotFound.
+ // If the repository exists, but is empty, returns ErrEmptyRemoteRepository.
+ AdvertisedReferences() (*packp.AdvRefs, error)
+ // AdvertisedReferencesContext retrieves the advertised references for a
+ // repository.
+ // If the repository does not exist, returns ErrRepositoryNotFound.
+ // If the repository exists, but is empty, returns ErrEmptyRemoteRepository.
+ AdvertisedReferencesContext(context.Context) (*packp.AdvRefs, error)
+ io.Closer
+}
+
+type AuthMethod interface {
+ fmt.Stringer
+ Name() string
+}
+
+// UploadPackSession represents a git-upload-pack session.
+// A git-upload-pack session has two steps: reference discovery
+// (AdvertisedReferences) and uploading pack (UploadPack).
+type UploadPackSession interface {
+ Session
+ // UploadPack takes a git-upload-pack request and returns a response,
+ // including a packfile. Don't be confused by terminology, the client
+ // side of a git-upload-pack is called git-fetch-pack, although here
+ // the same interface is used to make it RPC-like.
+ UploadPack(context.Context, *packp.UploadPackRequest) (*packp.UploadPackResponse, error)
+}
+
+// ReceivePackSession represents a git-receive-pack session.
+// A git-receive-pack session has two steps: reference discovery
+// (AdvertisedReferences) and receiving pack (ReceivePack).
+// In that order.
+type ReceivePackSession interface {
+ Session
+ // ReceivePack sends an update references request and a packfile
+ // reader and returns a ReportStatus and error. Don't be confused by
+ // terminology, the client side of a git-receive-pack is called
+ // git-send-pack, although here the same interface is used to make it
+ // RPC-like.
+ ReceivePack(context.Context, *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error)
+}
+
+// Endpoint represents a Git URL in any supported protocol.
+type Endpoint struct {
+ // Protocol is the protocol of the endpoint (e.g. git, https, file).
+ Protocol string
+ // User is the user.
+ User string
+ // Password is the password.
+ Password string
+ // Host is the host.
+ Host string
+ // Port is the port to connect, if 0 the default port for the given protocol
+ // will be used.
+ Port int
+ // Path is the repository path.
+ Path string
+ // InsecureSkipTLS skips ssl verify if protocol is https
+ InsecureSkipTLS bool
+ // CaBundle specify additional ca bundle with system cert pool
+ CaBundle []byte
+ // Proxy provides info required for connecting to a proxy.
+ Proxy ProxyOptions
+}
+
+type ProxyOptions struct {
+ URL string
+ Username string
+ Password string
+}
+
+func (o *ProxyOptions) Validate() error {
+ if o.URL != "" {
+ _, err := url.Parse(o.URL)
+ return err
+ }
+ return nil
+}
+
+func (o *ProxyOptions) FullURL() (*url.URL, error) {
+ proxyURL, err := url.Parse(o.URL)
+ if err != nil {
+ return nil, err
+ }
+ if o.Username != "" {
+ if o.Password != "" {
+ proxyURL.User = url.UserPassword(o.Username, o.Password)
+ } else {
+ proxyURL.User = url.User(o.Username)
+ }
+ }
+ return proxyURL, nil
+}
+
+var defaultPorts = map[string]int{
+ "http": 80,
+ "https": 443,
+ "git": 9418,
+ "ssh": 22,
+}
+
+// String returns a string representation of the Git URL.
+func (u *Endpoint) String() string {
+ var buf bytes.Buffer
+ if u.Protocol != "" {
+ buf.WriteString(u.Protocol)
+ buf.WriteByte(':')
+ }
+
+ if u.Protocol != "" || u.Host != "" || u.User != "" || u.Password != "" {
+ buf.WriteString("//")
+
+ if u.User != "" || u.Password != "" {
+ buf.WriteString(url.PathEscape(u.User))
+ if u.Password != "" {
+ buf.WriteByte(':')
+ buf.WriteString(url.PathEscape(u.Password))
+ }
+
+ buf.WriteByte('@')
+ }
+
+ if u.Host != "" {
+ buf.WriteString(u.Host)
+
+ if u.Port != 0 {
+ port, ok := defaultPorts[strings.ToLower(u.Protocol)]
+ if !ok || ok && port != u.Port {
+ fmt.Fprintf(&buf, ":%d", u.Port)
+ }
+ }
+ }
+ }
+
+ if u.Path != "" && u.Path[0] != '/' && u.Host != "" {
+ buf.WriteByte('/')
+ }
+
+ buf.WriteString(u.Path)
+ return buf.String()
+}
+
+func NewEndpoint(endpoint string) (*Endpoint, error) {
+ if e, ok := parseSCPLike(endpoint); ok {
+ return e, nil
+ }
+
+ if e, ok := parseFile(endpoint); ok {
+ return e, nil
+ }
+
+ return parseURL(endpoint)
+}
+
+func parseURL(endpoint string) (*Endpoint, error) {
+ u, err := url.Parse(endpoint)
+ if err != nil {
+ return nil, err
+ }
+
+ if !u.IsAbs() {
+ return nil, plumbing.NewPermanentError(fmt.Errorf(
+ "invalid endpoint: %s", endpoint,
+ ))
+ }
+
+ var user, pass string
+ if u.User != nil {
+ user = u.User.Username()
+ pass, _ = u.User.Password()
+ }
+
+ host := u.Hostname()
+ if strings.Contains(host, ":") {
+ // IPv6 address
+ host = "[" + host + "]"
+ }
+
+ return &Endpoint{
+ Protocol: u.Scheme,
+ User: user,
+ Password: pass,
+ Host: host,
+ Port: getPort(u),
+ Path: getPath(u),
+ }, nil
+}
+
+func getPort(u *url.URL) int {
+ p := u.Port()
+ if p == "" {
+ return 0
+ }
+
+ i, err := strconv.Atoi(p)
+ if err != nil {
+ return 0
+ }
+
+ return i
+}
+
+func getPath(u *url.URL) string {
+ var res string = u.Path
+ if u.RawQuery != "" {
+ res += "?" + u.RawQuery
+ }
+
+ if u.Fragment != "" {
+ res += "#" + u.Fragment
+ }
+
+ return res
+}
+
+func parseSCPLike(endpoint string) (*Endpoint, bool) {
+ if giturl.MatchesScheme(endpoint) || !giturl.MatchesScpLike(endpoint) {
+ return nil, false
+ }
+
+ user, host, portStr, path := giturl.FindScpLikeComponents(endpoint)
+ port, err := strconv.Atoi(portStr)
+ if err != nil {
+ port = 22
+ }
+
+ return &Endpoint{
+ Protocol: "ssh",
+ User: user,
+ Host: host,
+ Port: port,
+ Path: path,
+ }, true
+}
+
+func parseFile(endpoint string) (*Endpoint, bool) {
+ if giturl.MatchesScheme(endpoint) {
+ return nil, false
+ }
+
+ path := endpoint
+ return &Endpoint{
+ Protocol: "file",
+ Path: path,
+ }, true
+}
+
+// UnsupportedCapabilities are the capabilities not supported by any client
+// implementation
+var UnsupportedCapabilities = []capability.Capability{
+ capability.MultiACK,
+ capability.MultiACKDetailed,
+ capability.ThinPack,
+}
+
+// FilterUnsupportedCapabilities it filter out all the UnsupportedCapabilities
+// from a capability.List, the intended usage is on the client implementation
+// to filter the capabilities from an AdvRefs message.
+func FilterUnsupportedCapabilities(list *capability.List) {
+ for _, c := range UnsupportedCapabilities {
+ list.Delete(c)
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/client.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/client.go
new file mode 100644
index 00000000..38714e2a
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/client.go
@@ -0,0 +1,156 @@
+// Package file implements the file transport protocol.
+package file
+
+import (
+ "bufio"
+ "errors"
+ "io"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/plumbing/transport/internal/common"
+ "golang.org/x/sys/execabs"
+)
+
+// DefaultClient is the default local client.
+var DefaultClient = NewClient(
+ transport.UploadPackServiceName,
+ transport.ReceivePackServiceName,
+)
+
+type runner struct {
+ UploadPackBin string
+ ReceivePackBin string
+}
+
+// NewClient returns a new local client using the given git-upload-pack and
+// git-receive-pack binaries.
+func NewClient(uploadPackBin, receivePackBin string) transport.Transport {
+ return common.NewClient(&runner{
+ UploadPackBin: uploadPackBin,
+ ReceivePackBin: receivePackBin,
+ })
+}
+
+func prefixExecPath(cmd string) (string, error) {
+ // Use `git --exec-path` to find the exec path.
+ execCmd := execabs.Command("git", "--exec-path")
+
+ stdout, err := execCmd.StdoutPipe()
+ if err != nil {
+ return "", err
+ }
+ stdoutBuf := bufio.NewReader(stdout)
+
+ err = execCmd.Start()
+ if err != nil {
+ return "", err
+ }
+
+ execPathBytes, isPrefix, err := stdoutBuf.ReadLine()
+ if err != nil {
+ return "", err
+ }
+ if isPrefix {
+ return "", errors.New("couldn't read exec-path line all at once")
+ }
+
+ err = execCmd.Wait()
+ if err != nil {
+ return "", err
+ }
+ execPath := string(execPathBytes)
+ execPath = strings.TrimSpace(execPath)
+ cmd = filepath.Join(execPath, cmd)
+
+ // Make sure it actually exists.
+ _, err = execabs.LookPath(cmd)
+ if err != nil {
+ return "", err
+ }
+ return cmd, nil
+}
+
+func (r *runner) Command(cmd string, ep *transport.Endpoint, auth transport.AuthMethod,
+) (common.Command, error) {
+
+ switch cmd {
+ case transport.UploadPackServiceName:
+ cmd = r.UploadPackBin
+ case transport.ReceivePackServiceName:
+ cmd = r.ReceivePackBin
+ }
+
+ _, err := execabs.LookPath(cmd)
+ if err != nil {
+ if e, ok := err.(*execabs.Error); ok && e.Err == execabs.ErrNotFound {
+ cmd, err = prefixExecPath(cmd)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ return nil, err
+ }
+ }
+
+ return &command{cmd: execabs.Command(cmd, ep.Path)}, nil
+}
+
+type command struct {
+ cmd *execabs.Cmd
+ stderrCloser io.Closer
+ closed bool
+}
+
+func (c *command) Start() error {
+ return c.cmd.Start()
+}
+
+func (c *command) StderrPipe() (io.Reader, error) {
+ // Pipe returned by Command.StderrPipe has a race with Read + Command.Wait.
+ // We use an io.Pipe and close it after the command finishes.
+ r, w := io.Pipe()
+ c.cmd.Stderr = w
+ c.stderrCloser = r
+ return r, nil
+}
+
+func (c *command) StdinPipe() (io.WriteCloser, error) {
+ return c.cmd.StdinPipe()
+}
+
+func (c *command) StdoutPipe() (io.Reader, error) {
+ return c.cmd.StdoutPipe()
+}
+
+func (c *command) Kill() error {
+ c.cmd.Process.Kill()
+ return c.Close()
+}
+
+// Close waits for the command to exit.
+func (c *command) Close() error {
+ if c.closed {
+ return nil
+ }
+
+ defer func() {
+ c.closed = true
+ _ = c.stderrCloser.Close()
+
+ }()
+
+ err := c.cmd.Wait()
+ if _, ok := err.(*os.PathError); ok {
+ return nil
+ }
+
+ // When a repository does not exist, the command exits with code 128.
+ if _, ok := err.(*execabs.ExitError); ok {
+ return nil
+ }
+
+ return err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/server.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/server.go
new file mode 100644
index 00000000..b45d7a71
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/file/server.go
@@ -0,0 +1,53 @@
+package file
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/plumbing/transport/internal/common"
+ "github.com/go-git/go-git/v5/plumbing/transport/server"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// ServeUploadPack serves a git-upload-pack request using standard output, input
+// and error. This is meant to be used when implementing a git-upload-pack
+// command.
+func ServeUploadPack(path string) error {
+ ep, err := transport.NewEndpoint(path)
+ if err != nil {
+ return err
+ }
+
+ // TODO: define and implement a server-side AuthMethod
+ s, err := server.DefaultServer.NewUploadPackSession(ep, nil)
+ if err != nil {
+ return fmt.Errorf("error creating session: %s", err)
+ }
+
+ return common.ServeUploadPack(srvCmd, s)
+}
+
+// ServeReceivePack serves a git-receive-pack request using standard output,
+// input and error. This is meant to be used when implementing a
+// git-receive-pack command.
+func ServeReceivePack(path string) error {
+ ep, err := transport.NewEndpoint(path)
+ if err != nil {
+ return err
+ }
+
+ // TODO: define and implement a server-side AuthMethod
+ s, err := server.DefaultServer.NewReceivePackSession(ep, nil)
+ if err != nil {
+ return fmt.Errorf("error creating session: %s", err)
+ }
+
+ return common.ServeReceivePack(srvCmd, s)
+}
+
+var srvCmd = common.ServerCommand{
+ Stdin: os.Stdin,
+ Stdout: ioutil.WriteNopCloser(os.Stdout),
+ Stderr: os.Stderr,
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/git/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/git/common.go
new file mode 100644
index 00000000..2b878b03
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/git/common.go
@@ -0,0 +1,108 @@
+// Package git implements the git transport protocol.
+package git
+
+import (
+ "io"
+ "net"
+ "strconv"
+
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/plumbing/transport/internal/common"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// DefaultClient is the default git client.
+var DefaultClient = common.NewClient(&runner{})
+
+const DefaultPort = 9418
+
+type runner struct{}
+
+// Command returns a new Command for the given cmd in the given Endpoint
+func (r *runner) Command(cmd string, ep *transport.Endpoint, auth transport.AuthMethod) (common.Command, error) {
+ // auth not allowed since git protocol doesn't support authentication
+ if auth != nil {
+ return nil, transport.ErrInvalidAuthMethod
+ }
+ c := &command{command: cmd, endpoint: ep}
+ if err := c.connect(); err != nil {
+ return nil, err
+ }
+ return c, nil
+}
+
+type command struct {
+ conn net.Conn
+ connected bool
+ command string
+ endpoint *transport.Endpoint
+}
+
+// Start executes the command sending the required message to the TCP connection
+func (c *command) Start() error {
+ req := packp.GitProtoRequest{
+ RequestCommand: c.command,
+ Pathname: c.endpoint.Path,
+ }
+ host := c.endpoint.Host
+ if c.endpoint.Port != DefaultPort {
+ host = net.JoinHostPort(c.endpoint.Host, strconv.Itoa(c.endpoint.Port))
+ }
+
+ req.Host = host
+
+ return req.Encode(c.conn)
+}
+
+func (c *command) connect() error {
+ if c.connected {
+ return transport.ErrAlreadyConnected
+ }
+
+ var err error
+ c.conn, err = net.Dial("tcp", c.getHostWithPort())
+ if err != nil {
+ return err
+ }
+
+ c.connected = true
+ return nil
+}
+
+func (c *command) getHostWithPort() string {
+ host := c.endpoint.Host
+ port := c.endpoint.Port
+ if port <= 0 {
+ port = DefaultPort
+ }
+
+ return net.JoinHostPort(host, strconv.Itoa(port))
+}
+
+// StderrPipe git protocol doesn't have any dedicated error channel
+func (c *command) StderrPipe() (io.Reader, error) {
+ return nil, nil
+}
+
+// StdinPipe returns the underlying connection as WriteCloser, wrapped to prevent
+// call to the Close function from the connection, a command execution in git
+// protocol can't be closed or killed
+func (c *command) StdinPipe() (io.WriteCloser, error) {
+ return ioutil.WriteNopCloser(c.conn), nil
+}
+
+// StdoutPipe returns the underlying connection as Reader
+func (c *command) StdoutPipe() (io.Reader, error) {
+ return c.conn, nil
+}
+
+// Close closes the TCP connection and connection.
+func (c *command) Close() error {
+ if !c.connected {
+ return nil
+ }
+
+ c.connected = false
+ return c.conn.Close()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go
new file mode 100644
index 00000000..1c4ceee6
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go
@@ -0,0 +1,452 @@
+// Package http implements the HTTP transport protocol.
+package http
+
+import (
+ "bytes"
+ "context"
+ "crypto/tls"
+ "crypto/x509"
+ "fmt"
+ "net"
+ "net/http"
+ "net/url"
+ "reflect"
+ "strconv"
+ "strings"
+ "sync"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/golang/groupcache/lru"
+)
+
+// it requires a bytes.Buffer, because we need to know the length
+func applyHeadersToRequest(req *http.Request, content *bytes.Buffer, host string, requestType string) {
+ req.Header.Add("User-Agent", "git/1.0")
+ req.Header.Add("Host", host) // host:port
+
+ if content == nil {
+ req.Header.Add("Accept", "*/*")
+ return
+ }
+
+ req.Header.Add("Accept", fmt.Sprintf("application/x-%s-result", requestType))
+ req.Header.Add("Content-Type", fmt.Sprintf("application/x-%s-request", requestType))
+ req.Header.Add("Content-Length", strconv.Itoa(content.Len()))
+}
+
+const infoRefsPath = "/info/refs"
+
+func advertisedReferences(ctx context.Context, s *session, serviceName string) (ref *packp.AdvRefs, err error) {
+ url := fmt.Sprintf(
+ "%s%s?service=%s",
+ s.endpoint.String(), infoRefsPath, serviceName,
+ )
+
+ req, err := http.NewRequest(http.MethodGet, url, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ s.ApplyAuthToRequest(req)
+ applyHeadersToRequest(req, nil, s.endpoint.Host, serviceName)
+ res, err := s.client.Do(req.WithContext(ctx))
+ if err != nil {
+ return nil, err
+ }
+
+ s.ModifyEndpointIfRedirect(res)
+ defer ioutil.CheckClose(res.Body, &err)
+
+ if err = NewErr(res); err != nil {
+ return nil, err
+ }
+
+ ar := packp.NewAdvRefs()
+ if err = ar.Decode(res.Body); err != nil {
+ if err == packp.ErrEmptyAdvRefs {
+ err = transport.ErrEmptyRemoteRepository
+ }
+
+ return nil, err
+ }
+
+ // Git 2.41+ returns a zero-id plus capabilities when an empty
+ // repository is being cloned. This skips the existing logic within
+ // advrefs_decode.decodeFirstHash, which expects a flush-pkt instead.
+ //
+ // This logic aligns with plumbing/transport/internal/common/common.go.
+ if ar.IsEmpty() &&
+ // Empty repositories are valid for git-receive-pack.
+ transport.ReceivePackServiceName != serviceName {
+ return nil, transport.ErrEmptyRemoteRepository
+ }
+
+ transport.FilterUnsupportedCapabilities(ar.Capabilities)
+ s.advRefs = ar
+
+ return ar, nil
+}
+
+type client struct {
+ client *http.Client
+ transports *lru.Cache
+ mutex sync.RWMutex
+}
+
+// ClientOptions holds user configurable options for the client.
+type ClientOptions struct {
+ // CacheMaxEntries is the max no. of entries that the transport objects
+ // cache will hold at any given point of time. It must be a positive integer.
+ // Calling `client.addTransport()` after the cache has reached the specified
+ // size, will result in the least recently used transport getting deleted
+ // before the provided transport is added to the cache.
+ CacheMaxEntries int
+}
+
+var (
+ // defaultTransportCacheSize is the default capacity of the transport objects cache.
+ // Its value is 0 because transport caching is turned off by default and is an
+ // opt-in feature.
+ defaultTransportCacheSize = 0
+
+ // DefaultClient is the default HTTP client, which uses a net/http client configured
+ // with http.DefaultTransport.
+ DefaultClient = NewClient(nil)
+)
+
+// NewClient creates a new client with a custom net/http client.
+// See `InstallProtocol` to install and override default http client.
+// If the net/http client is nil or empty, it will use a net/http client configured
+// with http.DefaultTransport.
+//
+// Note that for HTTP client cannot distinguish between private repositories and
+// unexistent repositories on GitHub. So it returns `ErrAuthorizationRequired`
+// for both.
+func NewClient(c *http.Client) transport.Transport {
+ if c == nil {
+ c = &http.Client{
+ Transport: http.DefaultTransport,
+ }
+ }
+ return NewClientWithOptions(c, &ClientOptions{
+ CacheMaxEntries: defaultTransportCacheSize,
+ })
+}
+
+// NewClientWithOptions returns a new client configured with the provided net/http client
+// and other custom options specific to the client.
+// If the net/http client is nil or empty, it will use a net/http client configured
+// with http.DefaultTransport.
+func NewClientWithOptions(c *http.Client, opts *ClientOptions) transport.Transport {
+ if c == nil {
+ c = &http.Client{
+ Transport: http.DefaultTransport,
+ }
+ }
+ cl := &client{
+ client: c,
+ }
+
+ if opts != nil {
+ if opts.CacheMaxEntries > 0 {
+ cl.transports = lru.New(opts.CacheMaxEntries)
+ }
+ }
+ return cl
+}
+
+func (c *client) NewUploadPackSession(ep *transport.Endpoint, auth transport.AuthMethod) (
+ transport.UploadPackSession, error) {
+
+ return newUploadPackSession(c, ep, auth)
+}
+
+func (c *client) NewReceivePackSession(ep *transport.Endpoint, auth transport.AuthMethod) (
+ transport.ReceivePackSession, error) {
+
+ return newReceivePackSession(c, ep, auth)
+}
+
+type session struct {
+ auth AuthMethod
+ client *http.Client
+ endpoint *transport.Endpoint
+ advRefs *packp.AdvRefs
+}
+
+func transportWithInsecureTLS(transport *http.Transport) {
+ if transport.TLSClientConfig == nil {
+ transport.TLSClientConfig = &tls.Config{}
+ }
+ transport.TLSClientConfig.InsecureSkipVerify = true
+}
+
+func transportWithCABundle(transport *http.Transport, caBundle []byte) error {
+ rootCAs, err := x509.SystemCertPool()
+ if err != nil {
+ return err
+ }
+ if rootCAs == nil {
+ rootCAs = x509.NewCertPool()
+ }
+ rootCAs.AppendCertsFromPEM(caBundle)
+ if transport.TLSClientConfig == nil {
+ transport.TLSClientConfig = &tls.Config{}
+ }
+ transport.TLSClientConfig.RootCAs = rootCAs
+ return nil
+}
+
+func transportWithProxy(transport *http.Transport, proxyURL *url.URL) {
+ transport.Proxy = http.ProxyURL(proxyURL)
+}
+
+func configureTransport(transport *http.Transport, ep *transport.Endpoint) error {
+ if len(ep.CaBundle) > 0 {
+ if err := transportWithCABundle(transport, ep.CaBundle); err != nil {
+ return err
+ }
+ }
+ if ep.InsecureSkipTLS {
+ transportWithInsecureTLS(transport)
+ }
+
+ if ep.Proxy.URL != "" {
+ proxyURL, err := ep.Proxy.FullURL()
+ if err != nil {
+ return err
+ }
+ transportWithProxy(transport, proxyURL)
+ }
+ return nil
+}
+
+func newSession(c *client, ep *transport.Endpoint, auth transport.AuthMethod) (*session, error) {
+ var httpClient *http.Client
+
+ // We need to configure the http transport if there are transport specific
+ // options present in the endpoint.
+ if len(ep.CaBundle) > 0 || ep.InsecureSkipTLS || ep.Proxy.URL != "" {
+ var transport *http.Transport
+ // if the client wasn't configured to have a cache for transports then just configure
+ // the transport and use it directly, otherwise try to use the cache.
+ if c.transports == nil {
+ tr, ok := c.client.Transport.(*http.Transport)
+ if !ok {
+ return nil, fmt.Errorf("expected underlying client transport to be of type: %s; got: %s",
+ reflect.TypeOf(transport), reflect.TypeOf(c.client.Transport))
+ }
+
+ transport = tr.Clone()
+ configureTransport(transport, ep)
+ } else {
+ transportOpts := transportOptions{
+ caBundle: string(ep.CaBundle),
+ insecureSkipTLS: ep.InsecureSkipTLS,
+ }
+ if ep.Proxy.URL != "" {
+ proxyURL, err := ep.Proxy.FullURL()
+ if err != nil {
+ return nil, err
+ }
+ transportOpts.proxyURL = *proxyURL
+ }
+ var found bool
+ transport, found = c.fetchTransport(transportOpts)
+
+ if !found {
+ transport = c.client.Transport.(*http.Transport).Clone()
+ configureTransport(transport, ep)
+ c.addTransport(transportOpts, transport)
+ }
+ }
+
+ httpClient = &http.Client{
+ Transport: transport,
+ CheckRedirect: c.client.CheckRedirect,
+ Jar: c.client.Jar,
+ Timeout: c.client.Timeout,
+ }
+ } else {
+ httpClient = c.client
+ }
+
+ s := &session{
+ auth: basicAuthFromEndpoint(ep),
+ client: httpClient,
+ endpoint: ep,
+ }
+ if auth != nil {
+ a, ok := auth.(AuthMethod)
+ if !ok {
+ return nil, transport.ErrInvalidAuthMethod
+ }
+
+ s.auth = a
+ }
+
+ return s, nil
+}
+
+func (s *session) ApplyAuthToRequest(req *http.Request) {
+ if s.auth == nil {
+ return
+ }
+
+ s.auth.SetAuth(req)
+}
+
+func (s *session) ModifyEndpointIfRedirect(res *http.Response) {
+ if res.Request == nil {
+ return
+ }
+
+ r := res.Request
+ if !strings.HasSuffix(r.URL.Path, infoRefsPath) {
+ return
+ }
+
+ h, p, err := net.SplitHostPort(r.URL.Host)
+ if err != nil {
+ h = r.URL.Host
+ }
+ if p != "" {
+ port, err := strconv.Atoi(p)
+ if err == nil {
+ s.endpoint.Port = port
+ }
+ }
+ s.endpoint.Host = h
+
+ s.endpoint.Protocol = r.URL.Scheme
+ s.endpoint.Path = r.URL.Path[:len(r.URL.Path)-len(infoRefsPath)]
+}
+
+func (*session) Close() error {
+ return nil
+}
+
+// AuthMethod is concrete implementation of common.AuthMethod for HTTP services
+type AuthMethod interface {
+ transport.AuthMethod
+ SetAuth(r *http.Request)
+}
+
+func basicAuthFromEndpoint(ep *transport.Endpoint) *BasicAuth {
+ u := ep.User
+ if u == "" {
+ return nil
+ }
+
+ return &BasicAuth{u, ep.Password}
+}
+
+// BasicAuth represent a HTTP basic auth
+type BasicAuth struct {
+ Username, Password string
+}
+
+func (a *BasicAuth) SetAuth(r *http.Request) {
+ if a == nil {
+ return
+ }
+
+ r.SetBasicAuth(a.Username, a.Password)
+}
+
+// Name is name of the auth
+func (a *BasicAuth) Name() string {
+ return "http-basic-auth"
+}
+
+func (a *BasicAuth) String() string {
+ masked := "*******"
+ if a.Password == "" {
+ masked = ""
+ }
+
+ return fmt.Sprintf("%s - %s:%s", a.Name(), a.Username, masked)
+}
+
+// TokenAuth implements an http.AuthMethod that can be used with http transport
+// to authenticate with HTTP token authentication (also known as bearer
+// authentication).
+//
+// IMPORTANT: If you are looking to use OAuth tokens with popular servers (e.g.
+// GitHub, Bitbucket, GitLab) you should use BasicAuth instead. These servers
+// use basic HTTP authentication, with the OAuth token as user or password.
+// Check the documentation of your git server for details.
+type TokenAuth struct {
+ Token string
+}
+
+func (a *TokenAuth) SetAuth(r *http.Request) {
+ if a == nil {
+ return
+ }
+ r.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Token))
+}
+
+// Name is name of the auth
+func (a *TokenAuth) Name() string {
+ return "http-token-auth"
+}
+
+func (a *TokenAuth) String() string {
+ masked := "*******"
+ if a.Token == "" {
+ masked = ""
+ }
+ return fmt.Sprintf("%s - %s", a.Name(), masked)
+}
+
+// Err is a dedicated error to return errors based on status code
+type Err struct {
+ Response *http.Response
+ Reason string
+}
+
+// NewErr returns a new Err based on a http response and closes response body
+// if needed
+func NewErr(r *http.Response) error {
+ if r.StatusCode >= http.StatusOK && r.StatusCode < http.StatusMultipleChoices {
+ return nil
+ }
+
+ var reason string
+
+ // If a response message is present, add it to error
+ var messageBuffer bytes.Buffer
+ if r.Body != nil {
+ messageLength, _ := messageBuffer.ReadFrom(r.Body)
+ if messageLength > 0 {
+ reason = messageBuffer.String()
+ }
+ _ = r.Body.Close()
+ }
+
+ switch r.StatusCode {
+ case http.StatusUnauthorized:
+ return transport.ErrAuthenticationRequired
+ case http.StatusForbidden:
+ return transport.ErrAuthorizationFailed
+ case http.StatusNotFound:
+ return transport.ErrRepositoryNotFound
+ }
+
+ return plumbing.NewUnexpectedError(&Err{r, reason})
+}
+
+// StatusCode returns the status code of the response
+func (e *Err) StatusCode() int {
+ return e.Response.StatusCode
+}
+
+func (e *Err) Error() string {
+ return fmt.Sprintf("unexpected requesting %q status code: %d",
+ e.Response.Request.URL, e.Response.StatusCode,
+ )
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/receive_pack.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/receive_pack.go
new file mode 100644
index 00000000..3e736cd9
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/receive_pack.go
@@ -0,0 +1,109 @@
+package http
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io"
+ "net/http"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+type rpSession struct {
+ *session
+}
+
+func newReceivePackSession(c *client, ep *transport.Endpoint, auth transport.AuthMethod) (transport.ReceivePackSession, error) {
+ s, err := newSession(c, ep, auth)
+ return &rpSession{s}, err
+}
+
+func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
+ return advertisedReferences(context.TODO(), s.session, transport.ReceivePackServiceName)
+}
+
+func (s *rpSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
+ return advertisedReferences(ctx, s.session, transport.ReceivePackServiceName)
+}
+
+func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) (
+ *packp.ReportStatus, error) {
+ url := fmt.Sprintf(
+ "%s/%s",
+ s.endpoint.String(), transport.ReceivePackServiceName,
+ )
+
+ buf := bytes.NewBuffer(nil)
+ if err := req.Encode(buf); err != nil {
+ return nil, err
+ }
+
+ res, err := s.doRequest(ctx, http.MethodPost, url, buf)
+ if err != nil {
+ return nil, err
+ }
+
+ r, err := ioutil.NonEmptyReader(res.Body)
+ if err == ioutil.ErrEmptyReader {
+ return nil, nil
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ var d *sideband.Demuxer
+ if req.Capabilities.Supports(capability.Sideband64k) {
+ d = sideband.NewDemuxer(sideband.Sideband64k, r)
+ } else if req.Capabilities.Supports(capability.Sideband) {
+ d = sideband.NewDemuxer(sideband.Sideband, r)
+ }
+ if d != nil {
+ d.Progress = req.Progress
+ r = d
+ }
+
+ rc := ioutil.NewReadCloser(r, res.Body)
+
+ report := packp.NewReportStatus()
+ if err := report.Decode(rc); err != nil {
+ return nil, err
+ }
+
+ return report, report.Error()
+}
+
+func (s *rpSession) doRequest(
+ ctx context.Context, method, url string, content *bytes.Buffer,
+) (*http.Response, error) {
+
+ var body io.Reader
+ if content != nil {
+ body = content
+ }
+
+ req, err := http.NewRequest(method, url, body)
+ if err != nil {
+ return nil, plumbing.NewPermanentError(err)
+ }
+
+ applyHeadersToRequest(req, content, s.endpoint.Host, transport.ReceivePackServiceName)
+ s.ApplyAuthToRequest(req)
+
+ res, err := s.client.Do(req.WithContext(ctx))
+ if err != nil {
+ return nil, plumbing.NewUnexpectedError(err)
+ }
+
+ if err := NewErr(res); err != nil {
+ return nil, err
+ }
+
+ return res, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go
new file mode 100644
index 00000000..c8db3892
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go
@@ -0,0 +1,40 @@
+package http
+
+import (
+ "net/http"
+ "net/url"
+)
+
+// transportOptions contains transport specific configuration.
+type transportOptions struct {
+ insecureSkipTLS bool
+ // []byte is not comparable.
+ caBundle string
+ proxyURL url.URL
+}
+
+func (c *client) addTransport(opts transportOptions, transport *http.Transport) {
+ c.mutex.Lock()
+ c.transports.Add(opts, transport)
+ c.mutex.Unlock()
+}
+
+func (c *client) removeTransport(opts transportOptions) {
+ c.mutex.Lock()
+ c.transports.Remove(opts)
+ c.mutex.Unlock()
+}
+
+func (c *client) fetchTransport(opts transportOptions) (*http.Transport, bool) {
+ c.mutex.RLock()
+ t, ok := c.transports.Get(opts)
+ c.mutex.RUnlock()
+ if !ok {
+ return nil, false
+ }
+ transport, ok := t.(*http.Transport)
+ if !ok {
+ return nil, false
+ }
+ return transport, true
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/upload_pack.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/upload_pack.go
new file mode 100644
index 00000000..3432618a
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/upload_pack.go
@@ -0,0 +1,126 @@
+package http
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io"
+ "net/http"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/plumbing/transport/internal/common"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+type upSession struct {
+ *session
+}
+
+func newUploadPackSession(c *client, ep *transport.Endpoint, auth transport.AuthMethod) (transport.UploadPackSession, error) {
+ s, err := newSession(c, ep, auth)
+ return &upSession{s}, err
+}
+
+func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
+ return advertisedReferences(context.TODO(), s.session, transport.UploadPackServiceName)
+}
+
+func (s *upSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
+ return advertisedReferences(ctx, s.session, transport.UploadPackServiceName)
+}
+
+func (s *upSession) UploadPack(
+ ctx context.Context, req *packp.UploadPackRequest,
+) (*packp.UploadPackResponse, error) {
+
+ if req.IsEmpty() {
+ return nil, transport.ErrEmptyUploadPackRequest
+ }
+
+ if err := req.Validate(); err != nil {
+ return nil, err
+ }
+
+ url := fmt.Sprintf(
+ "%s/%s",
+ s.endpoint.String(), transport.UploadPackServiceName,
+ )
+
+ content, err := uploadPackRequestToReader(req)
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := s.doRequest(ctx, http.MethodPost, url, content)
+ if err != nil {
+ return nil, err
+ }
+
+ r, err := ioutil.NonEmptyReader(res.Body)
+ if err != nil {
+ if err == ioutil.ErrEmptyReader || err == io.ErrUnexpectedEOF {
+ return nil, transport.ErrEmptyUploadPackRequest
+ }
+
+ return nil, err
+ }
+
+ rc := ioutil.NewReadCloser(r, res.Body)
+ return common.DecodeUploadPackResponse(rc, req)
+}
+
+// Close does nothing.
+func (s *upSession) Close() error {
+ return nil
+}
+
+func (s *upSession) doRequest(
+ ctx context.Context, method, url string, content *bytes.Buffer,
+) (*http.Response, error) {
+
+ var body io.Reader
+ if content != nil {
+ body = content
+ }
+
+ req, err := http.NewRequest(method, url, body)
+ if err != nil {
+ return nil, plumbing.NewPermanentError(err)
+ }
+
+ applyHeadersToRequest(req, content, s.endpoint.Host, transport.UploadPackServiceName)
+ s.ApplyAuthToRequest(req)
+
+ res, err := s.client.Do(req.WithContext(ctx))
+ if err != nil {
+ return nil, plumbing.NewUnexpectedError(err)
+ }
+
+ if err := NewErr(res); err != nil {
+ return nil, err
+ }
+
+ return res, nil
+}
+
+func uploadPackRequestToReader(req *packp.UploadPackRequest) (*bytes.Buffer, error) {
+ buf := bytes.NewBuffer(nil)
+ e := pktline.NewEncoder(buf)
+
+ if err := req.UploadRequest.Encode(buf); err != nil {
+ return nil, fmt.Errorf("sending upload-req message: %s", err)
+ }
+
+ if err := req.UploadHaves.Encode(buf, false); err != nil {
+ return nil, fmt.Errorf("sending haves message: %s", err)
+ }
+
+ if err := e.EncodeString("done\n"); err != nil {
+ return nil, err
+ }
+
+ return buf, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go
new file mode 100644
index 00000000..9e1d0235
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go
@@ -0,0 +1,492 @@
+// Package common implements the git pack protocol with a pluggable transport.
+// This is a low-level package to implement new transports. Use a concrete
+// implementation instead (e.g. http, file, ssh).
+//
+// A simple example of usage can be found in the file package.
+package common
+
+import (
+ "bufio"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "regexp"
+ "strings"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing/format/pktline"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+const (
+ readErrorSecondsTimeout = 10
+)
+
+var (
+ ErrTimeoutExceeded = errors.New("timeout exceeded")
+ // stdErrSkipPattern is used for skipping lines from a command's stderr output.
+ // Any line matching this pattern will be skipped from further
+ // processing and not be returned to calling code.
+ stdErrSkipPattern = regexp.MustCompile("^remote:( =*){0,1}$")
+)
+
+// Commander creates Command instances. This is the main entry point for
+// transport implementations.
+type Commander interface {
+ // Command creates a new Command for the given git command and
+ // endpoint. cmd can be git-upload-pack or git-receive-pack. An
+ // error should be returned if the endpoint is not supported or the
+ // command cannot be created (e.g. binary does not exist, connection
+ // cannot be established).
+ Command(cmd string, ep *transport.Endpoint, auth transport.AuthMethod) (Command, error)
+}
+
+// Command is used for a single command execution.
+// This interface is modeled after exec.Cmd and ssh.Session in the standard
+// library.
+type Command interface {
+ // StderrPipe returns a pipe that will be connected to the command's
+ // standard error when the command starts. It should not be called after
+ // Start.
+ StderrPipe() (io.Reader, error)
+ // StdinPipe returns a pipe that will be connected to the command's
+ // standard input when the command starts. It should not be called after
+ // Start. The pipe should be closed when no more input is expected.
+ StdinPipe() (io.WriteCloser, error)
+ // StdoutPipe returns a pipe that will be connected to the command's
+ // standard output when the command starts. It should not be called after
+ // Start.
+ StdoutPipe() (io.Reader, error)
+ // Start starts the specified command. It does not wait for it to
+ // complete.
+ Start() error
+ // Close closes the command and releases any resources used by it. It
+ // will block until the command exits.
+ Close() error
+}
+
+// CommandKiller expands the Command interface, enabling it for being killed.
+type CommandKiller interface {
+ // Kill and close the session whatever the state it is. It will block until
+ // the command is terminated.
+ Kill() error
+}
+
+type client struct {
+ cmdr Commander
+}
+
+// NewClient creates a new client using the given Commander.
+func NewClient(runner Commander) transport.Transport {
+ return &client{runner}
+}
+
+// NewUploadPackSession creates a new UploadPackSession.
+func (c *client) NewUploadPackSession(ep *transport.Endpoint, auth transport.AuthMethod) (
+ transport.UploadPackSession, error) {
+
+ return c.newSession(transport.UploadPackServiceName, ep, auth)
+}
+
+// NewReceivePackSession creates a new ReceivePackSession.
+func (c *client) NewReceivePackSession(ep *transport.Endpoint, auth transport.AuthMethod) (
+ transport.ReceivePackSession, error) {
+
+ return c.newSession(transport.ReceivePackServiceName, ep, auth)
+}
+
+type session struct {
+ Stdin io.WriteCloser
+ Stdout io.Reader
+ Command Command
+
+ isReceivePack bool
+ advRefs *packp.AdvRefs
+ packRun bool
+ finished bool
+ firstErrLine chan string
+}
+
+func (c *client) newSession(s string, ep *transport.Endpoint, auth transport.AuthMethod) (*session, error) {
+ cmd, err := c.cmdr.Command(s, ep, auth)
+ if err != nil {
+ return nil, err
+ }
+
+ stdin, err := cmd.StdinPipe()
+ if err != nil {
+ return nil, err
+ }
+
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, err
+ }
+
+ stderr, err := cmd.StderrPipe()
+ if err != nil {
+ return nil, err
+ }
+
+ if err := cmd.Start(); err != nil {
+ return nil, err
+ }
+
+ return &session{
+ Stdin: stdin,
+ Stdout: stdout,
+ Command: cmd,
+ firstErrLine: c.listenFirstError(stderr),
+ isReceivePack: s == transport.ReceivePackServiceName,
+ }, nil
+}
+
+func (c *client) listenFirstError(r io.Reader) chan string {
+ if r == nil {
+ return nil
+ }
+
+ errLine := make(chan string, 1)
+ go func() {
+ s := bufio.NewScanner(r)
+ for {
+ if s.Scan() {
+ line := s.Text()
+ if !stdErrSkipPattern.MatchString(line) {
+ errLine <- line
+ break
+ }
+ } else {
+ close(errLine)
+ break
+ }
+ }
+
+ _, _ = io.Copy(io.Discard, r)
+ }()
+
+ return errLine
+}
+
+func (s *session) AdvertisedReferences() (*packp.AdvRefs, error) {
+ return s.AdvertisedReferencesContext(context.TODO())
+}
+
+// AdvertisedReferences retrieves the advertised references from the server.
+func (s *session) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
+ if s.advRefs != nil {
+ return s.advRefs, nil
+ }
+
+ ar := packp.NewAdvRefs()
+ if err := ar.Decode(s.StdoutContext(ctx)); err != nil {
+ if err := s.handleAdvRefDecodeError(err); err != nil {
+ return nil, err
+ }
+ }
+
+ // Some servers like jGit, announce capabilities instead of returning an
+ // packp message with a flush. This verifies that we received a empty
+ // adv-refs, even it contains capabilities.
+ if !s.isReceivePack && ar.IsEmpty() {
+ return nil, transport.ErrEmptyRemoteRepository
+ }
+
+ transport.FilterUnsupportedCapabilities(ar.Capabilities)
+ s.advRefs = ar
+ return ar, nil
+}
+
+func (s *session) handleAdvRefDecodeError(err error) error {
+ var errLine *pktline.ErrorLine
+ if errors.As(err, &errLine) {
+ if isRepoNotFoundError(errLine.Text) {
+ return transport.ErrRepositoryNotFound
+ }
+
+ return errLine
+ }
+
+ // If repository is not found, we get empty stdout and server writes an
+ // error to stderr.
+ if errors.Is(err, packp.ErrEmptyInput) {
+ // TODO:(v6): handle this error in a better way.
+ // Instead of checking the stderr output for a specific error message,
+ // define an ExitError and embed the stderr output and exit (if one
+ // exists) in the error struct. Just like exec.ExitError.
+ s.finished = true
+ if err := s.checkNotFoundError(); err != nil {
+ return err
+ }
+
+ return io.ErrUnexpectedEOF
+ }
+
+ // For empty (but existing) repositories, we get empty advertised-references
+ // message. But valid. That is, it includes at least a flush.
+ if err == packp.ErrEmptyAdvRefs {
+ // Empty repositories are valid for git-receive-pack.
+ if s.isReceivePack {
+ return nil
+ }
+
+ if err := s.finish(); err != nil {
+ return err
+ }
+
+ return transport.ErrEmptyRemoteRepository
+ }
+
+ // Some server sends the errors as normal content (git protocol), so when
+ // we try to decode it fails, we need to check the content of it, to detect
+ // not found errors
+ if uerr, ok := err.(*packp.ErrUnexpectedData); ok {
+ if isRepoNotFoundError(string(uerr.Data)) {
+ return transport.ErrRepositoryNotFound
+ }
+ }
+
+ return err
+}
+
+// UploadPack performs a request to the server to fetch a packfile. A reader is
+// returned with the packfile content. The reader must be closed after reading.
+func (s *session) UploadPack(ctx context.Context, req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) {
+ if req.IsEmpty() {
+ // XXX: IsEmpty means haves are a subset of wants, in that case we have
+ // everything we asked for. Close the connection and return nil.
+ if err := s.finish(); err != nil {
+ return nil, err
+ }
+ // TODO:(v6) return nil here
+ return nil, transport.ErrEmptyUploadPackRequest
+ }
+
+ if err := req.Validate(); err != nil {
+ return nil, err
+ }
+
+ if _, err := s.AdvertisedReferencesContext(ctx); err != nil {
+ return nil, err
+ }
+
+ s.packRun = true
+
+ in := s.StdinContext(ctx)
+ out := s.StdoutContext(ctx)
+
+ if err := uploadPack(in, out, req); err != nil {
+ return nil, err
+ }
+
+ r, err := ioutil.NonEmptyReader(out)
+ if err == ioutil.ErrEmptyReader {
+ if c, ok := s.Stdout.(io.Closer); ok {
+ _ = c.Close()
+ }
+
+ return nil, transport.ErrEmptyUploadPackRequest
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ rc := ioutil.NewReadCloser(r, s)
+ return DecodeUploadPackResponse(rc, req)
+}
+
+func (s *session) StdinContext(ctx context.Context) io.WriteCloser {
+ return ioutil.NewWriteCloserOnError(
+ ioutil.NewContextWriteCloser(ctx, s.Stdin),
+ s.onError,
+ )
+}
+
+func (s *session) StdoutContext(ctx context.Context) io.Reader {
+ return ioutil.NewReaderOnError(
+ ioutil.NewContextReader(ctx, s.Stdout),
+ s.onError,
+ )
+}
+
+func (s *session) onError(err error) {
+ if k, ok := s.Command.(CommandKiller); ok {
+ _ = k.Kill()
+ }
+
+ _ = s.Close()
+}
+
+func (s *session) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) {
+ if _, err := s.AdvertisedReferences(); err != nil {
+ return nil, err
+ }
+
+ s.packRun = true
+
+ w := s.StdinContext(ctx)
+ if err := req.Encode(w); err != nil {
+ return nil, err
+ }
+
+ if err := w.Close(); err != nil {
+ return nil, err
+ }
+
+ if !req.Capabilities.Supports(capability.ReportStatus) {
+ // If we don't have report-status, we can only
+ // check return value error.
+ return nil, s.Command.Close()
+ }
+
+ r := s.StdoutContext(ctx)
+
+ var d *sideband.Demuxer
+ if req.Capabilities.Supports(capability.Sideband64k) {
+ d = sideband.NewDemuxer(sideband.Sideband64k, r)
+ } else if req.Capabilities.Supports(capability.Sideband) {
+ d = sideband.NewDemuxer(sideband.Sideband, r)
+ }
+ if d != nil {
+ d.Progress = req.Progress
+ r = d
+ }
+
+ report := packp.NewReportStatus()
+ if err := report.Decode(r); err != nil {
+ return nil, err
+ }
+
+ if err := report.Error(); err != nil {
+ defer s.Close()
+ return report, err
+ }
+
+ return report, s.Command.Close()
+}
+
+func (s *session) finish() error {
+ if s.finished {
+ return nil
+ }
+
+ s.finished = true
+
+ // If we did not run a upload/receive-pack, we close the connection
+ // gracefully by sending a flush packet to the server. If the server
+ // operates correctly, it will exit with status 0.
+ if !s.packRun {
+ _, err := s.Stdin.Write(pktline.FlushPkt)
+ return err
+ }
+
+ return nil
+}
+
+func (s *session) Close() (err error) {
+ err = s.finish()
+
+ defer ioutil.CheckClose(s.Command, &err)
+ return
+}
+
+func (s *session) checkNotFoundError() error {
+ t := time.NewTicker(time.Second * readErrorSecondsTimeout)
+ defer t.Stop()
+
+ select {
+ case <-t.C:
+ return ErrTimeoutExceeded
+ case line, ok := <-s.firstErrLine:
+ if !ok || len(line) == 0 {
+ return nil
+ }
+
+ if isRepoNotFoundError(line) {
+ return transport.ErrRepositoryNotFound
+ }
+
+ // TODO:(v6): return server error just as it is without a prefix
+ return fmt.Errorf("unknown error: %s", line)
+ }
+}
+
+const (
+ githubRepoNotFoundErr = "Repository not found."
+ bitbucketRepoNotFoundErr = "repository does not exist."
+ localRepoNotFoundErr = "does not appear to be a git repository"
+ gitProtocolNotFoundErr = "Repository not found."
+ gitProtocolNoSuchErr = "no such repository"
+ gitProtocolAccessDeniedErr = "access denied"
+ gogsAccessDeniedErr = "Repository does not exist or you do not have access"
+ gitlabRepoNotFoundErr = "The project you were looking for could not be found"
+)
+
+func isRepoNotFoundError(s string) bool {
+ for _, err := range []string{
+ githubRepoNotFoundErr,
+ bitbucketRepoNotFoundErr,
+ localRepoNotFoundErr,
+ gitProtocolNotFoundErr,
+ gitProtocolNoSuchErr,
+ gitProtocolAccessDeniedErr,
+ gogsAccessDeniedErr,
+ gitlabRepoNotFoundErr,
+ } {
+ if strings.Contains(s, err) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// uploadPack implements the git-upload-pack protocol.
+func uploadPack(w io.WriteCloser, _ io.Reader, req *packp.UploadPackRequest) error {
+ // TODO support multi_ack mode
+ // TODO support multi_ack_detailed mode
+ // TODO support acks for common objects
+ // TODO build a proper state machine for all these processing options
+
+ if err := req.UploadRequest.Encode(w); err != nil {
+ return fmt.Errorf("sending upload-req message: %s", err)
+ }
+
+ if err := req.UploadHaves.Encode(w, true); err != nil {
+ return fmt.Errorf("sending haves message: %s", err)
+ }
+
+ if err := sendDone(w); err != nil {
+ return fmt.Errorf("sending done message: %s", err)
+ }
+
+ if err := w.Close(); err != nil {
+ return fmt.Errorf("closing input: %s", err)
+ }
+
+ return nil
+}
+
+func sendDone(w io.Writer) error {
+ e := pktline.NewEncoder(w)
+
+ return e.Encodef("done\n")
+}
+
+// DecodeUploadPackResponse decodes r into a new packp.UploadPackResponse
+func DecodeUploadPackResponse(r io.ReadCloser, req *packp.UploadPackRequest) (
+ *packp.UploadPackResponse, error,
+) {
+ res := packp.NewUploadPackResponse(req)
+ if err := res.Decode(r); err != nil {
+ return nil, fmt.Errorf("error decoding upload-pack response: %s", err)
+ }
+
+ return res, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/mocks.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/mocks.go
new file mode 100644
index 00000000..bc18b27e
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/mocks.go
@@ -0,0 +1,46 @@
+package common
+
+import (
+ "bytes"
+ "io"
+
+ gogitioutil "github.com/go-git/go-git/v5/utils/ioutil"
+
+ "github.com/go-git/go-git/v5/plumbing/transport"
+)
+
+type MockCommand struct {
+ stdin bytes.Buffer
+ stdout bytes.Buffer
+ stderr bytes.Buffer
+}
+
+func (c MockCommand) StderrPipe() (io.Reader, error) {
+ return &c.stderr, nil
+}
+
+func (c MockCommand) StdinPipe() (io.WriteCloser, error) {
+ return gogitioutil.WriteNopCloser(&c.stdin), nil
+}
+
+func (c MockCommand) StdoutPipe() (io.Reader, error) {
+ return &c.stdout, nil
+}
+
+func (c MockCommand) Start() error {
+ return nil
+}
+
+func (c MockCommand) Close() error {
+ panic("not implemented")
+}
+
+type MockCommander struct {
+ stderr string
+}
+
+func (c MockCommander) Command(cmd string, ep *transport.Endpoint, auth transport.AuthMethod) (Command, error) {
+ return &MockCommand{
+ stderr: *bytes.NewBufferString(c.stderr),
+ }, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/server.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/server.go
new file mode 100644
index 00000000..e2480848
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/server.go
@@ -0,0 +1,73 @@
+package common
+
+import (
+ "context"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// ServerCommand is used for a single server command execution.
+type ServerCommand struct {
+ Stderr io.Writer
+ Stdout io.WriteCloser
+ Stdin io.Reader
+}
+
+func ServeUploadPack(cmd ServerCommand, s transport.UploadPackSession) (err error) {
+ ioutil.CheckClose(cmd.Stdout, &err)
+
+ ar, err := s.AdvertisedReferences()
+ if err != nil {
+ return err
+ }
+
+ if err := ar.Encode(cmd.Stdout); err != nil {
+ return err
+ }
+
+ req := packp.NewUploadPackRequest()
+ if err := req.Decode(cmd.Stdin); err != nil {
+ return err
+ }
+
+ var resp *packp.UploadPackResponse
+ resp, err = s.UploadPack(context.TODO(), req)
+ if err != nil {
+ return err
+ }
+
+ return resp.Encode(cmd.Stdout)
+}
+
+func ServeReceivePack(cmd ServerCommand, s transport.ReceivePackSession) error {
+ ar, err := s.AdvertisedReferences()
+ if err != nil {
+ return fmt.Errorf("internal error in advertised references: %s", err)
+ }
+
+ if err := ar.Encode(cmd.Stdout); err != nil {
+ return fmt.Errorf("error in advertised references encoding: %s", err)
+ }
+
+ req := packp.NewReferenceUpdateRequest()
+ if err := req.Decode(cmd.Stdin); err != nil {
+ return fmt.Errorf("error decoding: %s", err)
+ }
+
+ rs, err := s.ReceivePack(context.TODO(), req)
+ if rs != nil {
+ if err := rs.Encode(cmd.Stdout); err != nil {
+ return fmt.Errorf("error in encoding report status %s", err)
+ }
+ }
+
+ if err != nil {
+ return fmt.Errorf("error in receive pack: %s", err)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/loader.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/loader.go
new file mode 100644
index 00000000..e7e2b075
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/loader.go
@@ -0,0 +1,64 @@
+package server
+
+import (
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/storage/filesystem"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/osfs"
+)
+
+// DefaultLoader is a filesystem loader ignoring host and resolving paths to /.
+var DefaultLoader = NewFilesystemLoader(osfs.New(""))
+
+// Loader loads repository's storer.Storer based on an optional host and a path.
+type Loader interface {
+ // Load loads a storer.Storer given a transport.Endpoint.
+ // Returns transport.ErrRepositoryNotFound if the repository does not
+ // exist.
+ Load(ep *transport.Endpoint) (storer.Storer, error)
+}
+
+type fsLoader struct {
+ base billy.Filesystem
+}
+
+// NewFilesystemLoader creates a Loader that ignores host and resolves paths
+// with a given base filesystem.
+func NewFilesystemLoader(base billy.Filesystem) Loader {
+ return &fsLoader{base}
+}
+
+// Load looks up the endpoint's path in the base file system and returns a
+// storer for it. Returns transport.ErrRepositoryNotFound if a repository does
+// not exist in the given path.
+func (l *fsLoader) Load(ep *transport.Endpoint) (storer.Storer, error) {
+ fs, err := l.base.Chroot(ep.Path)
+ if err != nil {
+ return nil, err
+ }
+
+ if _, err := fs.Stat("config"); err != nil {
+ return nil, transport.ErrRepositoryNotFound
+ }
+
+ return filesystem.NewStorage(fs, cache.NewObjectLRUDefault()), nil
+}
+
+// MapLoader is a Loader that uses a lookup map of storer.Storer by
+// transport.Endpoint.
+type MapLoader map[string]storer.Storer
+
+// Load returns a storer.Storer for given a transport.Endpoint by looking it up
+// in the map. Returns transport.ErrRepositoryNotFound if the endpoint does not
+// exist.
+func (l MapLoader) Load(ep *transport.Endpoint) (storer.Storer, error) {
+ s, ok := l[ep.String()]
+ if !ok {
+ return nil, transport.ErrRepositoryNotFound
+ }
+
+ return s, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/server.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/server.go
new file mode 100644
index 00000000..cf5d6f43
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/server/server.go
@@ -0,0 +1,432 @@
+// Package server implements the git server protocol. For most use cases, the
+// transport-specific implementations should be used.
+package server
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/packfile"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+ "github.com/go-git/go-git/v5/plumbing/revlist"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+var DefaultServer = NewServer(DefaultLoader)
+
+type server struct {
+ loader Loader
+ handler *handler
+}
+
+// NewServer returns a transport.Transport implementing a git server,
+// independent of transport. Each transport must wrap this.
+func NewServer(loader Loader) transport.Transport {
+ return &server{
+ loader,
+ &handler{asClient: false},
+ }
+}
+
+// NewClient returns a transport.Transport implementing a client with an
+// embedded server.
+func NewClient(loader Loader) transport.Transport {
+ return &server{
+ loader,
+ &handler{asClient: true},
+ }
+}
+
+func (s *server) NewUploadPackSession(ep *transport.Endpoint, auth transport.AuthMethod) (transport.UploadPackSession, error) {
+ sto, err := s.loader.Load(ep)
+ if err != nil {
+ return nil, err
+ }
+
+ return s.handler.NewUploadPackSession(sto)
+}
+
+func (s *server) NewReceivePackSession(ep *transport.Endpoint, auth transport.AuthMethod) (transport.ReceivePackSession, error) {
+ sto, err := s.loader.Load(ep)
+ if err != nil {
+ return nil, err
+ }
+
+ return s.handler.NewReceivePackSession(sto)
+}
+
+type handler struct {
+ asClient bool
+}
+
+func (h *handler) NewUploadPackSession(s storer.Storer) (transport.UploadPackSession, error) {
+ return &upSession{
+ session: session{storer: s, asClient: h.asClient},
+ }, nil
+}
+
+func (h *handler) NewReceivePackSession(s storer.Storer) (transport.ReceivePackSession, error) {
+ return &rpSession{
+ session: session{storer: s, asClient: h.asClient},
+ cmdStatus: map[plumbing.ReferenceName]error{},
+ }, nil
+}
+
+type session struct {
+ storer storer.Storer
+ caps *capability.List
+ asClient bool
+}
+
+func (s *session) Close() error {
+ return nil
+}
+
+func (s *session) SetAuth(transport.AuthMethod) error {
+ //TODO: deprecate
+ return nil
+}
+
+func (s *session) checkSupportedCapabilities(cl *capability.List) error {
+ for _, c := range cl.All() {
+ if !s.caps.Supports(c) {
+ return fmt.Errorf("unsupported capability: %s", c)
+ }
+ }
+
+ return nil
+}
+
+type upSession struct {
+ session
+}
+
+func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
+ return s.AdvertisedReferencesContext(context.TODO())
+}
+
+func (s *upSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
+ ar := packp.NewAdvRefs()
+
+ if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {
+ return nil, err
+ }
+
+ s.caps = ar.Capabilities
+
+ if err := setReferences(s.storer, ar); err != nil {
+ return nil, err
+ }
+
+ if err := setHEAD(s.storer, ar); err != nil {
+ return nil, err
+ }
+
+ if s.asClient && len(ar.References) == 0 {
+ return nil, transport.ErrEmptyRemoteRepository
+ }
+
+ return ar, nil
+}
+
+func (s *upSession) UploadPack(ctx context.Context, req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) {
+ if req.IsEmpty() {
+ return nil, transport.ErrEmptyUploadPackRequest
+ }
+
+ if err := req.Validate(); err != nil {
+ return nil, err
+ }
+
+ if s.caps == nil {
+ s.caps = capability.NewList()
+ if err := s.setSupportedCapabilities(s.caps); err != nil {
+ return nil, err
+ }
+ }
+
+ if err := s.checkSupportedCapabilities(req.Capabilities); err != nil {
+ return nil, err
+ }
+
+ s.caps = req.Capabilities
+
+ if len(req.Shallows) > 0 {
+ return nil, fmt.Errorf("shallow not supported")
+ }
+
+ objs, err := s.objectsToUpload(req)
+ if err != nil {
+ return nil, err
+ }
+
+ pr, pw := io.Pipe()
+ e := packfile.NewEncoder(pw, s.storer, false)
+ go func() {
+ // TODO: plumb through a pack window.
+ _, err := e.Encode(objs, 10)
+ pw.CloseWithError(err)
+ }()
+
+ return packp.NewUploadPackResponseWithPackfile(req,
+ ioutil.NewContextReadCloser(ctx, pr),
+ ), nil
+}
+
+func (s *upSession) objectsToUpload(req *packp.UploadPackRequest) ([]plumbing.Hash, error) {
+ haves, err := revlist.Objects(s.storer, req.Haves, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ return revlist.Objects(s.storer, req.Wants, haves)
+}
+
+func (*upSession) setSupportedCapabilities(c *capability.List) error {
+ if err := c.Set(capability.Agent, capability.DefaultAgent()); err != nil {
+ return err
+ }
+
+ if err := c.Set(capability.OFSDelta); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+type rpSession struct {
+ session
+ cmdStatus map[plumbing.ReferenceName]error
+ firstErr error
+ unpackErr error
+}
+
+func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
+ return s.AdvertisedReferencesContext(context.TODO())
+}
+
+func (s *rpSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
+ ar := packp.NewAdvRefs()
+
+ if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {
+ return nil, err
+ }
+
+ s.caps = ar.Capabilities
+
+ if err := setReferences(s.storer, ar); err != nil {
+ return nil, err
+ }
+
+ if err := setHEAD(s.storer, ar); err != nil {
+ return nil, err
+ }
+
+ return ar, nil
+}
+
+var (
+ ErrUpdateReference = errors.New("failed to update ref")
+)
+
+func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) {
+ if s.caps == nil {
+ s.caps = capability.NewList()
+ if err := s.setSupportedCapabilities(s.caps); err != nil {
+ return nil, err
+ }
+ }
+
+ if err := s.checkSupportedCapabilities(req.Capabilities); err != nil {
+ return nil, err
+ }
+
+ s.caps = req.Capabilities
+
+ //TODO: Implement 'atomic' update of references.
+
+ if req.Packfile != nil {
+ r := ioutil.NewContextReadCloser(ctx, req.Packfile)
+ if err := s.writePackfile(r); err != nil {
+ s.unpackErr = err
+ s.firstErr = err
+ return s.reportStatus(), err
+ }
+ }
+
+ s.updateReferences(req)
+ return s.reportStatus(), s.firstErr
+}
+
+func (s *rpSession) updateReferences(req *packp.ReferenceUpdateRequest) {
+ for _, cmd := range req.Commands {
+ exists, err := referenceExists(s.storer, cmd.Name)
+ if err != nil {
+ s.setStatus(cmd.Name, err)
+ continue
+ }
+
+ switch cmd.Action() {
+ case packp.Create:
+ if exists {
+ s.setStatus(cmd.Name, ErrUpdateReference)
+ continue
+ }
+
+ ref := plumbing.NewHashReference(cmd.Name, cmd.New)
+ err := s.storer.SetReference(ref)
+ s.setStatus(cmd.Name, err)
+ case packp.Delete:
+ if !exists {
+ s.setStatus(cmd.Name, ErrUpdateReference)
+ continue
+ }
+
+ err := s.storer.RemoveReference(cmd.Name)
+ s.setStatus(cmd.Name, err)
+ case packp.Update:
+ if !exists {
+ s.setStatus(cmd.Name, ErrUpdateReference)
+ continue
+ }
+
+ ref := plumbing.NewHashReference(cmd.Name, cmd.New)
+ err := s.storer.SetReference(ref)
+ s.setStatus(cmd.Name, err)
+ }
+ }
+}
+
+func (s *rpSession) writePackfile(r io.ReadCloser) error {
+ if r == nil {
+ return nil
+ }
+
+ if err := packfile.UpdateObjectStorage(s.storer, r); err != nil {
+ _ = r.Close()
+ return err
+ }
+
+ return r.Close()
+}
+
+func (s *rpSession) setStatus(ref plumbing.ReferenceName, err error) {
+ s.cmdStatus[ref] = err
+ if s.firstErr == nil && err != nil {
+ s.firstErr = err
+ }
+}
+
+func (s *rpSession) reportStatus() *packp.ReportStatus {
+ if !s.caps.Supports(capability.ReportStatus) {
+ return nil
+ }
+
+ rs := packp.NewReportStatus()
+ rs.UnpackStatus = "ok"
+
+ if s.unpackErr != nil {
+ rs.UnpackStatus = s.unpackErr.Error()
+ }
+
+ if s.cmdStatus == nil {
+ return rs
+ }
+
+ for ref, err := range s.cmdStatus {
+ msg := "ok"
+ if err != nil {
+ msg = err.Error()
+ }
+ status := &packp.CommandStatus{
+ ReferenceName: ref,
+ Status: msg,
+ }
+ rs.CommandStatuses = append(rs.CommandStatuses, status)
+ }
+
+ return rs
+}
+
+func (*rpSession) setSupportedCapabilities(c *capability.List) error {
+ if err := c.Set(capability.Agent, capability.DefaultAgent()); err != nil {
+ return err
+ }
+
+ if err := c.Set(capability.OFSDelta); err != nil {
+ return err
+ }
+
+ if err := c.Set(capability.DeleteRefs); err != nil {
+ return err
+ }
+
+ return c.Set(capability.ReportStatus)
+}
+
+func setHEAD(s storer.Storer, ar *packp.AdvRefs) error {
+ ref, err := s.Reference(plumbing.HEAD)
+ if err == plumbing.ErrReferenceNotFound {
+ return nil
+ }
+
+ if err != nil {
+ return err
+ }
+
+ if ref.Type() == plumbing.SymbolicReference {
+ if err := ar.AddReference(ref); err != nil {
+ return nil
+ }
+
+ ref, err = storer.ResolveReference(s, ref.Target())
+ if err == plumbing.ErrReferenceNotFound {
+ return nil
+ }
+
+ if err != nil {
+ return err
+ }
+ }
+
+ if ref.Type() != plumbing.HashReference {
+ return plumbing.ErrInvalidType
+ }
+
+ h := ref.Hash()
+ ar.Head = &h
+
+ return nil
+}
+
+func setReferences(s storer.Storer, ar *packp.AdvRefs) error {
+ //TODO: add peeled references.
+ iter, err := s.IterReferences()
+ if err != nil {
+ return err
+ }
+
+ return iter.ForEach(func(ref *plumbing.Reference) error {
+ if ref.Type() != plumbing.HashReference {
+ return nil
+ }
+
+ ar.References[ref.Name().String()] = ref.Hash()
+ return nil
+ })
+}
+
+func referenceExists(s storer.ReferenceStorer, n plumbing.ReferenceName) (bool, error) {
+ _, err := s.Reference(n)
+ if err == plumbing.ErrReferenceNotFound {
+ return false, nil
+ }
+
+ return err == nil, err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go
new file mode 100644
index 00000000..ac4e3583
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go
@@ -0,0 +1,313 @@
+package ssh
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "os/user"
+ "path/filepath"
+
+ "github.com/go-git/go-git/v5/plumbing/transport"
+
+ "github.com/skeema/knownhosts"
+ sshagent "github.com/xanzy/ssh-agent"
+ "golang.org/x/crypto/ssh"
+)
+
+const DefaultUsername = "git"
+
+// AuthMethod is the interface all auth methods for the ssh client
+// must implement. The clientConfig method returns the ssh client
+// configuration needed to establish an ssh connection.
+type AuthMethod interface {
+ transport.AuthMethod
+ // ClientConfig should return a valid ssh.ClientConfig to be used to create
+ // a connection to the SSH server.
+ ClientConfig() (*ssh.ClientConfig, error)
+}
+
+// The names of the AuthMethod implementations. To be returned by the
+// Name() method. Most git servers only allow PublicKeysName and
+// PublicKeysCallbackName.
+const (
+ KeyboardInteractiveName = "ssh-keyboard-interactive"
+ PasswordName = "ssh-password"
+ PasswordCallbackName = "ssh-password-callback"
+ PublicKeysName = "ssh-public-keys"
+ PublicKeysCallbackName = "ssh-public-key-callback"
+)
+
+// KeyboardInteractive implements AuthMethod by using a
+// prompt/response sequence controlled by the server.
+type KeyboardInteractive struct {
+ User string
+ Challenge ssh.KeyboardInteractiveChallenge
+ HostKeyCallbackHelper
+}
+
+func (a *KeyboardInteractive) Name() string {
+ return KeyboardInteractiveName
+}
+
+func (a *KeyboardInteractive) String() string {
+ return fmt.Sprintf("user: %s, name: %s", a.User, a.Name())
+}
+
+func (a *KeyboardInteractive) ClientConfig() (*ssh.ClientConfig, error) {
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
+ User: a.User,
+ Auth: []ssh.AuthMethod{
+ a.Challenge,
+ },
+ })
+}
+
+// Password implements AuthMethod by using the given password.
+type Password struct {
+ User string
+ Password string
+ HostKeyCallbackHelper
+}
+
+func (a *Password) Name() string {
+ return PasswordName
+}
+
+func (a *Password) String() string {
+ return fmt.Sprintf("user: %s, name: %s", a.User, a.Name())
+}
+
+func (a *Password) ClientConfig() (*ssh.ClientConfig, error) {
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
+ User: a.User,
+ Auth: []ssh.AuthMethod{ssh.Password(a.Password)},
+ })
+}
+
+// PasswordCallback implements AuthMethod by using a callback
+// to fetch the password.
+type PasswordCallback struct {
+ User string
+ Callback func() (pass string, err error)
+ HostKeyCallbackHelper
+}
+
+func (a *PasswordCallback) Name() string {
+ return PasswordCallbackName
+}
+
+func (a *PasswordCallback) String() string {
+ return fmt.Sprintf("user: %s, name: %s", a.User, a.Name())
+}
+
+func (a *PasswordCallback) ClientConfig() (*ssh.ClientConfig, error) {
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
+ User: a.User,
+ Auth: []ssh.AuthMethod{ssh.PasswordCallback(a.Callback)},
+ })
+}
+
+// PublicKeys implements AuthMethod by using the given key pairs.
+type PublicKeys struct {
+ User string
+ Signer ssh.Signer
+ HostKeyCallbackHelper
+}
+
+// NewPublicKeys returns a PublicKeys from a PEM encoded private key. An
+// encryption password should be given if the pemBytes contains a password
+// encrypted PEM block otherwise password should be empty. It supports RSA
+// (PKCS#1), PKCS#8, DSA (OpenSSL), and ECDSA private keys.
+func NewPublicKeys(user string, pemBytes []byte, password string) (*PublicKeys, error) {
+ signer, err := ssh.ParsePrivateKey(pemBytes)
+ if _, ok := err.(*ssh.PassphraseMissingError); ok {
+ signer, err = ssh.ParsePrivateKeyWithPassphrase(pemBytes, []byte(password))
+ }
+ if err != nil {
+ return nil, err
+ }
+ return &PublicKeys{User: user, Signer: signer}, nil
+}
+
+// NewPublicKeysFromFile returns a PublicKeys from a file containing a PEM
+// encoded private key. An encryption password should be given if the pemBytes
+// contains a password encrypted PEM block otherwise password should be empty.
+func NewPublicKeysFromFile(user, pemFile, password string) (*PublicKeys, error) {
+ bytes, err := os.ReadFile(pemFile)
+ if err != nil {
+ return nil, err
+ }
+
+ return NewPublicKeys(user, bytes, password)
+}
+
+func (a *PublicKeys) Name() string {
+ return PublicKeysName
+}
+
+func (a *PublicKeys) String() string {
+ return fmt.Sprintf("user: %s, name: %s", a.User, a.Name())
+}
+
+func (a *PublicKeys) ClientConfig() (*ssh.ClientConfig, error) {
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
+ User: a.User,
+ Auth: []ssh.AuthMethod{ssh.PublicKeys(a.Signer)},
+ })
+}
+
+func username() (string, error) {
+ var username string
+ if user, err := user.Current(); err == nil {
+ username = user.Username
+ } else {
+ username = os.Getenv("USER")
+ }
+
+ if username == "" {
+ return "", errors.New("failed to get username")
+ }
+
+ return username, nil
+}
+
+// PublicKeysCallback implements AuthMethod by asking a
+// ssh.agent.Agent to act as a signer.
+type PublicKeysCallback struct {
+ User string
+ Callback func() (signers []ssh.Signer, err error)
+ HostKeyCallbackHelper
+}
+
+// NewSSHAgentAuth returns a PublicKeysCallback based on a SSH agent, it opens
+// a pipe with the SSH agent and uses the pipe as the implementer of the public
+// key callback function.
+func NewSSHAgentAuth(u string) (*PublicKeysCallback, error) {
+ var err error
+ if u == "" {
+ u, err = username()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ a, _, err := sshagent.New()
+ if err != nil {
+ return nil, fmt.Errorf("error creating SSH agent: %q", err)
+ }
+
+ return &PublicKeysCallback{
+ User: u,
+ Callback: a.Signers,
+ }, nil
+}
+
+func (a *PublicKeysCallback) Name() string {
+ return PublicKeysCallbackName
+}
+
+func (a *PublicKeysCallback) String() string {
+ return fmt.Sprintf("user: %s, name: %s", a.User, a.Name())
+}
+
+func (a *PublicKeysCallback) ClientConfig() (*ssh.ClientConfig, error) {
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
+ User: a.User,
+ Auth: []ssh.AuthMethod{ssh.PublicKeysCallback(a.Callback)},
+ })
+}
+
+// NewKnownHostsCallback returns ssh.HostKeyCallback based on a file based on a
+// known_hosts file. http://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT
+//
+// If list of files is empty, then it will be read from the SSH_KNOWN_HOSTS
+// environment variable, example:
+//
+// /home/foo/custom_known_hosts_file:/etc/custom_known/hosts_file
+//
+// If SSH_KNOWN_HOSTS is not set the following file locations will be used:
+//
+// ~/.ssh/known_hosts
+// /etc/ssh/ssh_known_hosts
+func NewKnownHostsCallback(files ...string) (ssh.HostKeyCallback, error) {
+ kh, err := newKnownHosts(files...)
+ return ssh.HostKeyCallback(kh), err
+}
+
+func newKnownHosts(files ...string) (knownhosts.HostKeyCallback, error) {
+ var err error
+
+ if len(files) == 0 {
+ if files, err = getDefaultKnownHostsFiles(); err != nil {
+ return nil, err
+ }
+ }
+
+ if files, err = filterKnownHostsFiles(files...); err != nil {
+ return nil, err
+ }
+
+ return knownhosts.New(files...)
+}
+
+func getDefaultKnownHostsFiles() ([]string, error) {
+ files := filepath.SplitList(os.Getenv("SSH_KNOWN_HOSTS"))
+ if len(files) != 0 {
+ return files, nil
+ }
+
+ homeDirPath, err := os.UserHomeDir()
+ if err != nil {
+ return nil, err
+ }
+
+ return []string{
+ filepath.Join(homeDirPath, "/.ssh/known_hosts"),
+ "/etc/ssh/ssh_known_hosts",
+ }, nil
+}
+
+func filterKnownHostsFiles(files ...string) ([]string, error) {
+ var out []string
+ for _, file := range files {
+ _, err := os.Stat(file)
+ if err == nil {
+ out = append(out, file)
+ continue
+ }
+
+ if !os.IsNotExist(err) {
+ return nil, err
+ }
+ }
+
+ if len(out) == 0 {
+ return nil, fmt.Errorf("unable to find any valid known_hosts file, set SSH_KNOWN_HOSTS env variable")
+ }
+
+ return out, nil
+}
+
+// HostKeyCallbackHelper is a helper that provides common functionality to
+// configure HostKeyCallback into a ssh.ClientConfig.
+type HostKeyCallbackHelper struct {
+ // HostKeyCallback is the function type used for verifying server keys.
+ // If nil default callback will be create using NewKnownHostsCallback
+ // without argument.
+ HostKeyCallback ssh.HostKeyCallback
+}
+
+// SetHostKeyCallback sets the field HostKeyCallback in the given cfg. If
+// HostKeyCallback is empty a default callback is created using
+// NewKnownHostsCallback.
+func (m *HostKeyCallbackHelper) SetHostKeyCallback(cfg *ssh.ClientConfig) (*ssh.ClientConfig, error) {
+ var err error
+ if m.HostKeyCallback == nil {
+ if m.HostKeyCallback, err = NewKnownHostsCallback(); err != nil {
+ return cfg, err
+ }
+ }
+
+ cfg.HostKeyCallback = m.HostKeyCallback
+ return cfg, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go b/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go
new file mode 100644
index 00000000..05dea448
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go
@@ -0,0 +1,276 @@
+// Package ssh implements the SSH transport protocol.
+package ssh
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "reflect"
+ "strconv"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/plumbing/transport/internal/common"
+ "github.com/skeema/knownhosts"
+
+ "github.com/kevinburke/ssh_config"
+ "golang.org/x/crypto/ssh"
+ "golang.org/x/net/proxy"
+)
+
+// DefaultClient is the default SSH client.
+var DefaultClient = NewClient(nil)
+
+// DefaultSSHConfig is the reader used to access parameters stored in the
+// system's ssh_config files. If nil all the ssh_config are ignored.
+var DefaultSSHConfig sshConfig = ssh_config.DefaultUserSettings
+
+type sshConfig interface {
+ Get(alias, key string) string
+}
+
+// NewClient creates a new SSH client with an optional *ssh.ClientConfig.
+func NewClient(config *ssh.ClientConfig) transport.Transport {
+ return common.NewClient(&runner{config: config})
+}
+
+// DefaultAuthBuilder is the function used to create a default AuthMethod, when
+// the user doesn't provide any.
+var DefaultAuthBuilder = func(user string) (AuthMethod, error) {
+ return NewSSHAgentAuth(user)
+}
+
+const DefaultPort = 22
+
+type runner struct {
+ config *ssh.ClientConfig
+}
+
+func (r *runner) Command(cmd string, ep *transport.Endpoint, auth transport.AuthMethod) (common.Command, error) {
+ c := &command{command: cmd, endpoint: ep, config: r.config}
+ if auth != nil {
+ if err := c.setAuth(auth); err != nil {
+ return nil, err
+ }
+ }
+
+ if err := c.connect(); err != nil {
+ return nil, err
+ }
+ return c, nil
+}
+
+type command struct {
+ *ssh.Session
+ connected bool
+ command string
+ endpoint *transport.Endpoint
+ client *ssh.Client
+ auth AuthMethod
+ config *ssh.ClientConfig
+}
+
+func (c *command) setAuth(auth transport.AuthMethod) error {
+ a, ok := auth.(AuthMethod)
+ if !ok {
+ return transport.ErrInvalidAuthMethod
+ }
+
+ c.auth = a
+ return nil
+}
+
+func (c *command) Start() error {
+ return c.Session.Start(endpointToCommand(c.command, c.endpoint))
+}
+
+// Close closes the SSH session and connection.
+func (c *command) Close() error {
+ if !c.connected {
+ return nil
+ }
+
+ c.connected = false
+
+ //XXX: If did read the full packfile, then the session might be already
+ // closed.
+ _ = c.Session.Close()
+ err := c.client.Close()
+
+ //XXX: in go1.16+ we can use errors.Is(err, net.ErrClosed)
+ if err != nil && strings.HasSuffix(err.Error(), "use of closed network connection") {
+ return nil
+ }
+
+ return err
+}
+
+// connect connects to the SSH server, unless a AuthMethod was set with
+// SetAuth method, by default uses an auth method based on PublicKeysCallback,
+// it connects to a SSH agent, using the address stored in the SSH_AUTH_SOCK
+// environment var.
+func (c *command) connect() error {
+ if c.connected {
+ return transport.ErrAlreadyConnected
+ }
+
+ if c.auth == nil {
+ if err := c.setAuthFromEndpoint(); err != nil {
+ return err
+ }
+ }
+
+ var err error
+ config, err := c.auth.ClientConfig()
+ if err != nil {
+ return err
+ }
+ hostWithPort := c.getHostWithPort()
+ if config.HostKeyCallback == nil {
+ kh, err := newKnownHosts()
+ if err != nil {
+ return err
+ }
+ config.HostKeyCallback = kh.HostKeyCallback()
+ config.HostKeyAlgorithms = kh.HostKeyAlgorithms(hostWithPort)
+ } else if len(config.HostKeyAlgorithms) == 0 {
+ // Set the HostKeyAlgorithms based on HostKeyCallback.
+ // For background see https://github.com/go-git/go-git/issues/411 as well as
+ // https://github.com/golang/go/issues/29286 for root cause.
+ config.HostKeyAlgorithms = knownhosts.HostKeyAlgorithms(config.HostKeyCallback, hostWithPort)
+ }
+
+ overrideConfig(c.config, config)
+
+ c.client, err = dial("tcp", hostWithPort, c.endpoint.Proxy, config)
+ if err != nil {
+ return err
+ }
+
+ c.Session, err = c.client.NewSession()
+ if err != nil {
+ _ = c.client.Close()
+ return err
+ }
+
+ c.connected = true
+ return nil
+}
+
+func dial(network, addr string, proxyOpts transport.ProxyOptions, config *ssh.ClientConfig) (*ssh.Client, error) {
+ var (
+ ctx = context.Background()
+ cancel context.CancelFunc
+ )
+ if config.Timeout > 0 {
+ ctx, cancel = context.WithTimeout(ctx, config.Timeout)
+ } else {
+ ctx, cancel = context.WithCancel(ctx)
+ }
+ defer cancel()
+
+ var conn net.Conn
+ var dialErr error
+
+ if proxyOpts.URL != "" {
+ proxyUrl, err := proxyOpts.FullURL()
+ if err != nil {
+ return nil, err
+ }
+ dialer, err := proxy.FromURL(proxyUrl, proxy.Direct)
+ if err != nil {
+ return nil, err
+ }
+
+ // Try to use a ContextDialer, but fall back to a Dialer if that goes south.
+ ctxDialer, ok := dialer.(proxy.ContextDialer)
+ if !ok {
+ return nil, fmt.Errorf("expected ssh proxy dialer to be of type %s; got %s",
+ reflect.TypeOf(ctxDialer), reflect.TypeOf(dialer))
+ }
+ conn, dialErr = ctxDialer.DialContext(ctx, "tcp", addr)
+ } else {
+ conn, dialErr = proxy.Dial(ctx, network, addr)
+ }
+ if dialErr != nil {
+ return nil, dialErr
+ }
+
+ c, chans, reqs, err := ssh.NewClientConn(conn, addr, config)
+ if err != nil {
+ return nil, err
+ }
+ return ssh.NewClient(c, chans, reqs), nil
+}
+
+func (c *command) getHostWithPort() string {
+ if addr, found := c.doGetHostWithPortFromSSHConfig(); found {
+ return addr
+ }
+
+ host := c.endpoint.Host
+ port := c.endpoint.Port
+ if port <= 0 {
+ port = DefaultPort
+ }
+
+ return net.JoinHostPort(host, strconv.Itoa(port))
+}
+
+func (c *command) doGetHostWithPortFromSSHConfig() (addr string, found bool) {
+ if DefaultSSHConfig == nil {
+ return
+ }
+
+ host := c.endpoint.Host
+ port := c.endpoint.Port
+
+ configHost := DefaultSSHConfig.Get(c.endpoint.Host, "Hostname")
+ if configHost != "" {
+ host = configHost
+ found = true
+ }
+
+ if !found {
+ return
+ }
+
+ configPort := DefaultSSHConfig.Get(c.endpoint.Host, "Port")
+ if configPort != "" {
+ if i, err := strconv.Atoi(configPort); err == nil {
+ port = i
+ }
+ }
+
+ addr = net.JoinHostPort(host, strconv.Itoa(port))
+ return
+}
+
+func (c *command) setAuthFromEndpoint() error {
+ var err error
+ c.auth, err = DefaultAuthBuilder(c.endpoint.User)
+ return err
+}
+
+func endpointToCommand(cmd string, ep *transport.Endpoint) string {
+ return fmt.Sprintf("%s '%s'", cmd, ep.Path)
+}
+
+func overrideConfig(overrides *ssh.ClientConfig, c *ssh.ClientConfig) {
+ if overrides == nil {
+ return
+ }
+
+ t := reflect.TypeOf(*c)
+ vc := reflect.ValueOf(c).Elem()
+ vo := reflect.ValueOf(overrides).Elem()
+
+ for i := 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+ vcf := vc.FieldByName(f.Name)
+ vof := vo.FieldByName(f.Name)
+ vcf.Set(vof)
+ }
+
+ *c = vc.Interface().(ssh.ClientConfig)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/prune.go b/vendor/github.com/go-git/go-git/v5/prune.go
new file mode 100644
index 00000000..8e35b994
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/prune.go
@@ -0,0 +1,66 @@
+package git
+
+import (
+ "errors"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+type PruneHandler func(unreferencedObjectHash plumbing.Hash) error
+type PruneOptions struct {
+ // OnlyObjectsOlderThan if set to non-zero value
+ // selects only objects older than the time provided.
+ OnlyObjectsOlderThan time.Time
+ // Handler is called on matching objects
+ Handler PruneHandler
+}
+
+var ErrLooseObjectsNotSupported = errors.New("loose objects not supported")
+
+// DeleteObject deletes an object from a repository.
+// The type conveniently matches PruneHandler.
+func (r *Repository) DeleteObject(hash plumbing.Hash) error {
+ los, ok := r.Storer.(storer.LooseObjectStorer)
+ if !ok {
+ return ErrLooseObjectsNotSupported
+ }
+
+ return los.DeleteLooseObject(hash)
+}
+
+func (r *Repository) Prune(opt PruneOptions) error {
+ los, ok := r.Storer.(storer.LooseObjectStorer)
+ if !ok {
+ return ErrLooseObjectsNotSupported
+ }
+
+ pw := newObjectWalker(r.Storer)
+ err := pw.walkAllRefs()
+ if err != nil {
+ return err
+ }
+ // Now walk all (loose) objects in storage.
+ return los.ForEachObjectHash(func(hash plumbing.Hash) error {
+ // Get out if we have seen this object.
+ if pw.isSeen(hash) {
+ return nil
+ }
+ // Otherwise it is a candidate for pruning.
+ // Check out for too new objects next.
+ if !opt.OnlyObjectsOlderThan.IsZero() {
+ // Errors here are non-fatal. The object may be e.g. packed.
+ // Or concurrently deleted. Skip such objects.
+ t, err := los.LooseObjectTime(hash)
+ if err != nil {
+ return nil
+ }
+ // Skip too new objects.
+ if !t.Before(opt.OnlyObjectsOlderThan) {
+ return nil
+ }
+ }
+ return opt.Handler(hash)
+ })
+}
diff --git a/vendor/github.com/go-git/go-git/v5/remote.go b/vendor/github.com/go-git/go-git/v5/remote.go
new file mode 100644
index 00000000..7cc0db9b
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/remote.go
@@ -0,0 +1,1528 @@
+package git
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "strings"
+ "time"
+
+ "github.com/go-git/go-billy/v5/osfs"
+ "github.com/go-git/go-git/v5/config"
+ "github.com/go-git/go-git/v5/internal/url"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ "github.com/go-git/go-git/v5/plumbing/format/packfile"
+ "github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
+ "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband"
+ "github.com/go-git/go-git/v5/plumbing/revlist"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+ "github.com/go-git/go-git/v5/plumbing/transport/client"
+ "github.com/go-git/go-git/v5/storage"
+ "github.com/go-git/go-git/v5/storage/filesystem"
+ "github.com/go-git/go-git/v5/storage/memory"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+var (
+ NoErrAlreadyUpToDate = errors.New("already up-to-date")
+ ErrDeleteRefNotSupported = errors.New("server does not support delete-refs")
+ ErrForceNeeded = errors.New("some refs were not updated")
+ ErrExactSHA1NotSupported = errors.New("server does not support exact SHA1 refspec")
+ ErrEmptyUrls = errors.New("URLs cannot be empty")
+)
+
+type NoMatchingRefSpecError struct {
+ refSpec config.RefSpec
+}
+
+func (e NoMatchingRefSpecError) Error() string {
+ return fmt.Sprintf("couldn't find remote ref %q", e.refSpec.Src())
+}
+
+func (e NoMatchingRefSpecError) Is(target error) bool {
+ _, ok := target.(NoMatchingRefSpecError)
+ return ok
+}
+
+const (
+ // This describes the maximum number of commits to walk when
+ // computing the haves to send to a server, for each ref in the
+ // repo containing this remote, when not using the multi-ack
+ // protocol. Setting this to 0 means there is no limit.
+ maxHavesToVisitPerRef = 100
+
+ // peeledSuffix is the suffix used to build peeled reference names.
+ peeledSuffix = "^{}"
+)
+
+// Remote represents a connection to a remote repository.
+type Remote struct {
+ c *config.RemoteConfig
+ s storage.Storer
+}
+
+// NewRemote creates a new Remote.
+// The intended purpose is to use the Remote for tasks such as listing remote references (like using git ls-remote).
+// Otherwise Remotes should be created via the use of a Repository.
+func NewRemote(s storage.Storer, c *config.RemoteConfig) *Remote {
+ return &Remote{s: s, c: c}
+}
+
+// Config returns the RemoteConfig object used to instantiate this Remote.
+func (r *Remote) Config() *config.RemoteConfig {
+ return r.c
+}
+
+func (r *Remote) String() string {
+ var fetch, push string
+ if len(r.c.URLs) > 0 {
+ fetch = r.c.URLs[0]
+ push = r.c.URLs[0]
+ }
+
+ return fmt.Sprintf("%s\t%s (fetch)\n%[1]s\t%[3]s (push)", r.c.Name, fetch, push)
+}
+
+// Push performs a push to the remote. Returns NoErrAlreadyUpToDate if the
+// remote was already up-to-date.
+func (r *Remote) Push(o *PushOptions) error {
+ return r.PushContext(context.Background(), o)
+}
+
+// PushContext performs a push to the remote. Returns NoErrAlreadyUpToDate if
+// the remote was already up-to-date.
+//
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects the
+// transport operations.
+func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
+ if err := o.Validate(); err != nil {
+ return err
+ }
+
+ if o.RemoteName != r.c.Name {
+ return fmt.Errorf("remote names don't match: %s != %s", o.RemoteName, r.c.Name)
+ }
+
+ if o.RemoteURL == "" {
+ o.RemoteURL = r.c.URLs[0]
+ }
+
+ s, err := newSendPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.CABundle, o.ProxyOptions)
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(s, &err)
+
+ ar, err := s.AdvertisedReferencesContext(ctx)
+ if err != nil {
+ return err
+ }
+
+ remoteRefs, err := ar.AllReferences()
+ if err != nil {
+ return err
+ }
+
+ if err := r.checkRequireRemoteRefs(o.RequireRemoteRefs, remoteRefs); err != nil {
+ return err
+ }
+
+ isDelete := false
+ allDelete := true
+ for _, rs := range o.RefSpecs {
+ if rs.IsDelete() {
+ isDelete = true
+ } else {
+ allDelete = false
+ }
+ if isDelete && !allDelete {
+ break
+ }
+ }
+
+ if isDelete && !ar.Capabilities.Supports(capability.DeleteRefs) {
+ return ErrDeleteRefNotSupported
+ }
+
+ if o.Force {
+ for i := 0; i < len(o.RefSpecs); i++ {
+ rs := &o.RefSpecs[i]
+ if !rs.IsForceUpdate() && !rs.IsDelete() {
+ o.RefSpecs[i] = config.RefSpec("+" + rs.String())
+ }
+ }
+ }
+
+ localRefs, err := r.references()
+ if err != nil {
+ return err
+ }
+
+ req, err := r.newReferenceUpdateRequest(o, localRefs, remoteRefs, ar)
+ if err != nil {
+ return err
+ }
+
+ if len(req.Commands) == 0 {
+ return NoErrAlreadyUpToDate
+ }
+
+ objects := objectsToPush(req.Commands)
+
+ haves, err := referencesToHashes(remoteRefs)
+ if err != nil {
+ return err
+ }
+
+ stop, err := r.s.Shallow()
+ if err != nil {
+ return err
+ }
+
+ // if we have shallow we should include this as part of the objects that
+ // we are aware.
+ haves = append(haves, stop...)
+
+ var hashesToPush []plumbing.Hash
+ // Avoid the expensive revlist operation if we're only doing deletes.
+ if !allDelete {
+ if url.IsLocalEndpoint(o.RemoteURL) {
+ // If we're are pushing to a local repo, it might be much
+ // faster to use a local storage layer to get the commits
+ // to ignore, when calculating the object revlist.
+ localStorer := filesystem.NewStorage(
+ osfs.New(o.RemoteURL), cache.NewObjectLRUDefault())
+ hashesToPush, err = revlist.ObjectsWithStorageForIgnores(
+ r.s, localStorer, objects, haves)
+ } else {
+ hashesToPush, err = revlist.Objects(r.s, objects, haves)
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ if len(hashesToPush) == 0 {
+ allDelete = true
+ for _, command := range req.Commands {
+ if command.Action() != packp.Delete {
+ allDelete = false
+ break
+ }
+ }
+ }
+
+ rs, err := pushHashes(ctx, s, r.s, req, hashesToPush, r.useRefDeltas(ar), allDelete)
+ if err != nil {
+ return err
+ }
+
+ if rs != nil {
+ if err = rs.Error(); err != nil {
+ return err
+ }
+ }
+
+ return r.updateRemoteReferenceStorage(req)
+}
+
+func (r *Remote) useRefDeltas(ar *packp.AdvRefs) bool {
+ return !ar.Capabilities.Supports(capability.OFSDelta)
+}
+
+func (r *Remote) addReachableTags(localRefs []*plumbing.Reference, remoteRefs storer.ReferenceStorer, req *packp.ReferenceUpdateRequest) error {
+ tags := make(map[plumbing.Reference]struct{})
+ // get a list of all tags locally
+ for _, ref := range localRefs {
+ if strings.HasPrefix(string(ref.Name()), "refs/tags") {
+ tags[*ref] = struct{}{}
+ }
+ }
+
+ remoteRefIter, err := remoteRefs.IterReferences()
+ if err != nil {
+ return err
+ }
+
+ // remove any that are already on the remote
+ if err := remoteRefIter.ForEach(func(reference *plumbing.Reference) error {
+ delete(tags, *reference)
+ return nil
+ }); err != nil {
+ return err
+ }
+
+ for tag := range tags {
+ tagObject, err := object.GetObject(r.s, tag.Hash())
+ var tagCommit *object.Commit
+ if err != nil {
+ return fmt.Errorf("get tag object: %w", err)
+ }
+
+ if tagObject.Type() != plumbing.TagObject {
+ continue
+ }
+
+ annotatedTag, ok := tagObject.(*object.Tag)
+ if !ok {
+ return errors.New("could not get annotated tag object")
+ }
+
+ tagCommit, err = object.GetCommit(r.s, annotatedTag.Target)
+ if err != nil {
+ return fmt.Errorf("get annotated tag commit: %w", err)
+ }
+
+ // only include tags that are reachable from one of the refs
+ // already being pushed
+ for _, cmd := range req.Commands {
+ if tag.Name() == cmd.Name {
+ continue
+ }
+
+ if strings.HasPrefix(cmd.Name.String(), "refs/tags") {
+ continue
+ }
+
+ c, err := object.GetCommit(r.s, cmd.New)
+ if err != nil {
+ return fmt.Errorf("get commit %v: %w", cmd.Name, err)
+ }
+
+ if isAncestor, err := tagCommit.IsAncestor(c); err == nil && isAncestor {
+ req.Commands = append(req.Commands, &packp.Command{Name: tag.Name(), New: tag.Hash()})
+ }
+ }
+ }
+
+ return nil
+}
+
+func (r *Remote) newReferenceUpdateRequest(
+ o *PushOptions,
+ localRefs []*plumbing.Reference,
+ remoteRefs storer.ReferenceStorer,
+ ar *packp.AdvRefs,
+) (*packp.ReferenceUpdateRequest, error) {
+ req := packp.NewReferenceUpdateRequestFromCapabilities(ar.Capabilities)
+
+ if o.Progress != nil {
+ req.Progress = o.Progress
+ if ar.Capabilities.Supports(capability.Sideband64k) {
+ _ = req.Capabilities.Set(capability.Sideband64k)
+ } else if ar.Capabilities.Supports(capability.Sideband) {
+ _ = req.Capabilities.Set(capability.Sideband)
+ }
+ }
+
+ if ar.Capabilities.Supports(capability.PushOptions) {
+ _ = req.Capabilities.Set(capability.PushOptions)
+ for k, v := range o.Options {
+ req.Options = append(req.Options, &packp.Option{Key: k, Value: v})
+ }
+ }
+
+ if o.Atomic && ar.Capabilities.Supports(capability.Atomic) {
+ _ = req.Capabilities.Set(capability.Atomic)
+ }
+
+ if err := r.addReferencesToUpdate(o.RefSpecs, localRefs, remoteRefs, req, o.Prune, o.ForceWithLease); err != nil {
+
+ return nil, err
+ }
+
+ if o.FollowTags {
+ if err := r.addReachableTags(localRefs, remoteRefs, req); err != nil {
+ return nil, err
+ }
+ }
+
+ return req, nil
+}
+
+func (r *Remote) updateRemoteReferenceStorage(
+ req *packp.ReferenceUpdateRequest,
+) error {
+
+ for _, spec := range r.c.Fetch {
+ for _, c := range req.Commands {
+ if !spec.Match(c.Name) {
+ continue
+ }
+
+ local := spec.Dst(c.Name)
+ ref := plumbing.NewHashReference(local, c.New)
+ switch c.Action() {
+ case packp.Create, packp.Update:
+ if err := r.s.SetReference(ref); err != nil {
+ return err
+ }
+ case packp.Delete:
+ if err := r.s.RemoveReference(local); err != nil {
+ return err
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+// FetchContext fetches references along with the objects necessary to complete
+// their histories.
+//
+// Returns nil if the operation is successful, NoErrAlreadyUpToDate if there are
+// no changes to be fetched, or an error.
+//
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects the
+// transport operations.
+func (r *Remote) FetchContext(ctx context.Context, o *FetchOptions) error {
+ _, err := r.fetch(ctx, o)
+ return err
+}
+
+// Fetch fetches references along with the objects necessary to complete their
+// histories.
+//
+// Returns nil if the operation is successful, NoErrAlreadyUpToDate if there are
+// no changes to be fetched, or an error.
+func (r *Remote) Fetch(o *FetchOptions) error {
+ return r.FetchContext(context.Background(), o)
+}
+
+func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.ReferenceStorer, err error) {
+ if o.RemoteName == "" {
+ o.RemoteName = r.c.Name
+ }
+
+ if err = o.Validate(); err != nil {
+ return nil, err
+ }
+
+ if len(o.RefSpecs) == 0 {
+ o.RefSpecs = r.c.Fetch
+ }
+
+ if o.RemoteURL == "" {
+ o.RemoteURL = r.c.URLs[0]
+ }
+
+ s, err := newUploadPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.CABundle, o.ProxyOptions)
+ if err != nil {
+ return nil, err
+ }
+
+ defer ioutil.CheckClose(s, &err)
+
+ ar, err := s.AdvertisedReferencesContext(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ req, err := r.newUploadPackRequest(o, ar)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := r.isSupportedRefSpec(o.RefSpecs, ar); err != nil {
+ return nil, err
+ }
+
+ remoteRefs, err := ar.AllReferences()
+ if err != nil {
+ return nil, err
+ }
+
+ localRefs, err := r.references()
+ if err != nil {
+ return nil, err
+ }
+
+ refs, specToRefs, err := calculateRefs(o.RefSpecs, remoteRefs, o.Tags)
+ if err != nil {
+ return nil, err
+ }
+
+ if !req.Depth.IsZero() {
+ req.Shallows, err = r.s.Shallow()
+ if err != nil {
+ return nil, fmt.Errorf("existing checkout is not shallow")
+ }
+ }
+
+ req.Wants, err = getWants(r.s, refs, o.Depth)
+ if len(req.Wants) > 0 {
+ req.Haves, err = getHaves(localRefs, remoteRefs, r.s, o.Depth)
+ if err != nil {
+ return nil, err
+ }
+
+ if err = r.fetchPack(ctx, o, s, req); err != nil {
+ return nil, err
+ }
+ }
+
+ var updatedPrune bool
+ if o.Prune {
+ updatedPrune, err = r.pruneRemotes(o.RefSpecs, localRefs, remoteRefs)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ updated, err := r.updateLocalReferenceStorage(o.RefSpecs, refs, remoteRefs, specToRefs, o.Tags, o.Force)
+ if err != nil {
+ return nil, err
+ }
+
+ if !updated {
+ updated, err = depthChanged(req.Shallows, r.s)
+ if err != nil {
+ return nil, fmt.Errorf("error checking depth change: %v", err)
+ }
+ }
+
+ if !updated && !updatedPrune {
+ return remoteRefs, NoErrAlreadyUpToDate
+ }
+
+ return remoteRefs, nil
+}
+
+func depthChanged(before []plumbing.Hash, s storage.Storer) (bool, error) {
+ after, err := s.Shallow()
+ if err != nil {
+ return false, err
+ }
+
+ if len(before) != len(after) {
+ return true, nil
+ }
+
+ bm := make(map[plumbing.Hash]bool, len(before))
+ for _, b := range before {
+ bm[b] = true
+ }
+ for _, a := range after {
+ if _, ok := bm[a]; !ok {
+ return true, nil
+ }
+ }
+
+ return false, nil
+}
+
+func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte, proxyOpts transport.ProxyOptions) (transport.UploadPackSession, error) {
+ c, ep, err := newClient(url, insecure, cabundle, proxyOpts)
+ if err != nil {
+ return nil, err
+ }
+
+ return c.NewUploadPackSession(ep, auth)
+}
+
+func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte, proxyOpts transport.ProxyOptions) (transport.ReceivePackSession, error) {
+ c, ep, err := newClient(url, insecure, cabundle, proxyOpts)
+ if err != nil {
+ return nil, err
+ }
+
+ return c.NewReceivePackSession(ep, auth)
+}
+
+func newClient(url string, insecure bool, cabundle []byte, proxyOpts transport.ProxyOptions) (transport.Transport, *transport.Endpoint, error) {
+ ep, err := transport.NewEndpoint(url)
+ if err != nil {
+ return nil, nil, err
+ }
+ ep.InsecureSkipTLS = insecure
+ ep.CaBundle = cabundle
+ ep.Proxy = proxyOpts
+
+ c, err := client.NewClient(ep)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return c, ep, err
+}
+
+func (r *Remote) fetchPack(ctx context.Context, o *FetchOptions, s transport.UploadPackSession,
+ req *packp.UploadPackRequest) (err error) {
+
+ reader, err := s.UploadPack(ctx, req)
+ if err != nil {
+ if errors.Is(err, transport.ErrEmptyUploadPackRequest) {
+ // XXX: no packfile provided, everything is up-to-date.
+ return nil
+ }
+ return err
+ }
+
+ defer ioutil.CheckClose(reader, &err)
+
+ if err = r.updateShallow(o, reader); err != nil {
+ return err
+ }
+
+ if err = packfile.UpdateObjectStorage(r.s,
+ buildSidebandIfSupported(req.Capabilities, reader, o.Progress),
+ ); err != nil {
+ return err
+ }
+
+ return err
+}
+
+func (r *Remote) pruneRemotes(specs []config.RefSpec, localRefs []*plumbing.Reference, remoteRefs memory.ReferenceStorage) (bool, error) {
+ var updatedPrune bool
+ for _, spec := range specs {
+ rev := spec.Reverse()
+ for _, ref := range localRefs {
+ if !rev.Match(ref.Name()) {
+ continue
+ }
+ _, err := remoteRefs.Reference(rev.Dst(ref.Name()))
+ if errors.Is(err, plumbing.ErrReferenceNotFound) {
+ updatedPrune = true
+ err := r.s.RemoveReference(ref.Name())
+ if err != nil {
+ return false, err
+ }
+ }
+ }
+ }
+ return updatedPrune, nil
+}
+
+func (r *Remote) addReferencesToUpdate(
+ refspecs []config.RefSpec,
+ localRefs []*plumbing.Reference,
+ remoteRefs storer.ReferenceStorer,
+ req *packp.ReferenceUpdateRequest,
+ prune bool,
+ forceWithLease *ForceWithLease,
+) error {
+ // This references dictionary will be used to search references by name.
+ refsDict := make(map[string]*plumbing.Reference)
+ for _, ref := range localRefs {
+ refsDict[ref.Name().String()] = ref
+ }
+
+ for _, rs := range refspecs {
+ if rs.IsDelete() {
+ if err := r.deleteReferences(rs, remoteRefs, refsDict, req, false); err != nil {
+ return err
+ }
+ } else {
+ err := r.addOrUpdateReferences(rs, localRefs, refsDict, remoteRefs, req, forceWithLease)
+ if err != nil {
+ return err
+ }
+
+ if prune {
+ if err := r.deleteReferences(rs, remoteRefs, refsDict, req, true); err != nil {
+ return err
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+func (r *Remote) addOrUpdateReferences(
+ rs config.RefSpec,
+ localRefs []*plumbing.Reference,
+ refsDict map[string]*plumbing.Reference,
+ remoteRefs storer.ReferenceStorer,
+ req *packp.ReferenceUpdateRequest,
+ forceWithLease *ForceWithLease,
+) error {
+ // If it is not a wildcard refspec we can directly search for the reference
+ // in the references dictionary.
+ if !rs.IsWildcard() {
+ ref, ok := refsDict[rs.Src()]
+ if !ok {
+ commit, err := object.GetCommit(r.s, plumbing.NewHash(rs.Src()))
+ if err == nil {
+ return r.addCommit(rs, remoteRefs, commit.Hash, req)
+ }
+ return nil
+ }
+
+ return r.addReferenceIfRefSpecMatches(rs, remoteRefs, ref, req, forceWithLease)
+ }
+
+ for _, ref := range localRefs {
+ err := r.addReferenceIfRefSpecMatches(rs, remoteRefs, ref, req, forceWithLease)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (r *Remote) deleteReferences(rs config.RefSpec,
+ remoteRefs storer.ReferenceStorer,
+ refsDict map[string]*plumbing.Reference,
+ req *packp.ReferenceUpdateRequest,
+ prune bool) error {
+ iter, err := remoteRefs.IterReferences()
+ if err != nil {
+ return err
+ }
+
+ return iter.ForEach(func(ref *plumbing.Reference) error {
+ if ref.Type() != plumbing.HashReference {
+ return nil
+ }
+
+ if prune {
+ rs := rs.Reverse()
+ if !rs.Match(ref.Name()) {
+ return nil
+ }
+
+ if _, ok := refsDict[rs.Dst(ref.Name()).String()]; ok {
+ return nil
+ }
+ } else if rs.Dst("") != ref.Name() {
+ return nil
+ }
+
+ cmd := &packp.Command{
+ Name: ref.Name(),
+ Old: ref.Hash(),
+ New: plumbing.ZeroHash,
+ }
+ req.Commands = append(req.Commands, cmd)
+ return nil
+ })
+}
+
+func (r *Remote) addCommit(rs config.RefSpec,
+ remoteRefs storer.ReferenceStorer, localCommit plumbing.Hash,
+ req *packp.ReferenceUpdateRequest) error {
+
+ if rs.IsWildcard() {
+ return errors.New("can't use wildcard together with hash refspecs")
+ }
+
+ cmd := &packp.Command{
+ Name: rs.Dst(""),
+ Old: plumbing.ZeroHash,
+ New: localCommit,
+ }
+ remoteRef, err := remoteRefs.Reference(cmd.Name)
+ if err == nil {
+ if remoteRef.Type() != plumbing.HashReference {
+ // TODO: check actual git behavior here
+ return nil
+ }
+
+ cmd.Old = remoteRef.Hash()
+ } else if err != plumbing.ErrReferenceNotFound {
+ return err
+ }
+ if cmd.Old == cmd.New {
+ return nil
+ }
+ if !rs.IsForceUpdate() {
+ if err := checkFastForwardUpdate(r.s, remoteRefs, cmd); err != nil {
+ return err
+ }
+ }
+
+ req.Commands = append(req.Commands, cmd)
+ return nil
+}
+
+func (r *Remote) addReferenceIfRefSpecMatches(rs config.RefSpec,
+ remoteRefs storer.ReferenceStorer, localRef *plumbing.Reference,
+ req *packp.ReferenceUpdateRequest, forceWithLease *ForceWithLease) error {
+
+ if localRef.Type() != plumbing.HashReference {
+ return nil
+ }
+
+ if !rs.Match(localRef.Name()) {
+ return nil
+ }
+
+ cmd := &packp.Command{
+ Name: rs.Dst(localRef.Name()),
+ Old: plumbing.ZeroHash,
+ New: localRef.Hash(),
+ }
+
+ remoteRef, err := remoteRefs.Reference(cmd.Name)
+ if err == nil {
+ if remoteRef.Type() != plumbing.HashReference {
+ // TODO: check actual git behavior here
+ return nil
+ }
+
+ cmd.Old = remoteRef.Hash()
+ } else if err != plumbing.ErrReferenceNotFound {
+ return err
+ }
+
+ if cmd.Old == cmd.New {
+ return nil
+ }
+
+ if forceWithLease != nil {
+ if err = r.checkForceWithLease(localRef, cmd, forceWithLease); err != nil {
+ return err
+ }
+ } else if !rs.IsForceUpdate() {
+ if err := checkFastForwardUpdate(r.s, remoteRefs, cmd); err != nil {
+ return err
+ }
+ }
+
+ req.Commands = append(req.Commands, cmd)
+ return nil
+}
+
+func (r *Remote) checkForceWithLease(localRef *plumbing.Reference, cmd *packp.Command, forceWithLease *ForceWithLease) error {
+ remotePrefix := fmt.Sprintf("refs/remotes/%s/", r.Config().Name)
+
+ ref, err := storer.ResolveReference(
+ r.s,
+ plumbing.ReferenceName(remotePrefix+strings.Replace(localRef.Name().String(), "refs/heads/", "", -1)))
+ if err != nil {
+ return err
+ }
+
+ if forceWithLease.RefName.String() == "" || (forceWithLease.RefName == cmd.Name) {
+ expectedOID := ref.Hash()
+
+ if !forceWithLease.Hash.IsZero() {
+ expectedOID = forceWithLease.Hash
+ }
+
+ if cmd.Old != expectedOID {
+ return fmt.Errorf("non-fast-forward update: %s", cmd.Name.String())
+ }
+ }
+
+ return nil
+}
+
+func (r *Remote) references() ([]*plumbing.Reference, error) {
+ var localRefs []*plumbing.Reference
+
+ iter, err := r.s.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+
+ for {
+ ref, err := iter.Next()
+ if err == io.EOF {
+ break
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ localRefs = append(localRefs, ref)
+ }
+
+ return localRefs, nil
+}
+
+func getRemoteRefsFromStorer(remoteRefStorer storer.ReferenceStorer) (
+ map[plumbing.Hash]bool, error) {
+ remoteRefs := map[plumbing.Hash]bool{}
+ iter, err := remoteRefStorer.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+ err = iter.ForEach(func(ref *plumbing.Reference) error {
+ if ref.Type() != plumbing.HashReference {
+ return nil
+ }
+ remoteRefs[ref.Hash()] = true
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ return remoteRefs, nil
+}
+
+// getHavesFromRef populates the given `haves` map with the given
+// reference, and up to `maxHavesToVisitPerRef` ancestor commits.
+func getHavesFromRef(
+ ref *plumbing.Reference,
+ remoteRefs map[plumbing.Hash]bool,
+ s storage.Storer,
+ haves map[plumbing.Hash]bool,
+ depth int,
+) error {
+ h := ref.Hash()
+ if haves[h] {
+ return nil
+ }
+
+ // No need to load the commit if we know the remote already
+ // has this hash.
+ if remoteRefs[h] {
+ haves[h] = true
+ return nil
+ }
+
+ commit, err := object.GetCommit(s, h)
+ if err != nil {
+ // Ignore the error if this isn't a commit.
+ haves[ref.Hash()] = true
+ return nil
+ }
+
+ // Until go-git supports proper commit negotiation during an
+ // upload pack request, include up to `maxHavesToVisitPerRef`
+ // commits from the history of each ref.
+ walker := object.NewCommitPreorderIter(commit, haves, nil)
+ toVisit := maxHavesToVisitPerRef
+ // But only need up to the requested depth
+ if depth > 0 && depth < maxHavesToVisitPerRef {
+ toVisit = depth
+ }
+ // It is safe to ignore any error here as we are just trying to find the references that we already have
+ // An example of a legitimate failure is we have a shallow clone and don't have the previous commit(s)
+ _ = walker.ForEach(func(c *object.Commit) error {
+ haves[c.Hash] = true
+ toVisit--
+ // If toVisit starts out at 0 (indicating there is no
+ // max), then it will be negative here and we won't stop
+ // early.
+ if toVisit == 0 || remoteRefs[c.Hash] {
+ return storer.ErrStop
+ }
+ return nil
+ })
+
+ return nil
+}
+
+func getHaves(
+ localRefs []*plumbing.Reference,
+ remoteRefStorer storer.ReferenceStorer,
+ s storage.Storer,
+ depth int,
+) ([]plumbing.Hash, error) {
+ haves := map[plumbing.Hash]bool{}
+
+ // Build a map of all the remote references, to avoid loading too
+ // many parent commits for references we know don't need to be
+ // transferred.
+ remoteRefs, err := getRemoteRefsFromStorer(remoteRefStorer)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, ref := range localRefs {
+ if haves[ref.Hash()] {
+ continue
+ }
+
+ if ref.Type() != plumbing.HashReference {
+ continue
+ }
+
+ err = getHavesFromRef(ref, remoteRefs, s, haves, depth)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ var result []plumbing.Hash
+ for h := range haves {
+ result = append(result, h)
+ }
+
+ return result, nil
+}
+
+const refspecAllTags = "+refs/tags/*:refs/tags/*"
+
+func calculateRefs(
+ spec []config.RefSpec,
+ remoteRefs storer.ReferenceStorer,
+ tagMode TagMode,
+) (memory.ReferenceStorage, [][]*plumbing.Reference, error) {
+ if tagMode == AllTags {
+ spec = append(spec, refspecAllTags)
+ }
+
+ refs := make(memory.ReferenceStorage)
+ // list of references matched for each spec
+ specToRefs := make([][]*plumbing.Reference, len(spec))
+ for i := range spec {
+ var err error
+ specToRefs[i], err = doCalculateRefs(spec[i], remoteRefs, refs)
+ if err != nil {
+ return nil, nil, err
+ }
+ }
+
+ return refs, specToRefs, nil
+}
+
+func doCalculateRefs(
+ s config.RefSpec,
+ remoteRefs storer.ReferenceStorer,
+ refs memory.ReferenceStorage,
+) ([]*plumbing.Reference, error) {
+ var refList []*plumbing.Reference
+
+ if s.IsExactSHA1() {
+ ref := plumbing.NewHashReference(s.Dst(""), plumbing.NewHash(s.Src()))
+
+ refList = append(refList, ref)
+ return refList, refs.SetReference(ref)
+ }
+
+ var matched bool
+ onMatched := func(ref *plumbing.Reference) error {
+ if ref.Type() == plumbing.SymbolicReference {
+ target, err := storer.ResolveReference(remoteRefs, ref.Name())
+ if err != nil {
+ return err
+ }
+
+ ref = plumbing.NewHashReference(ref.Name(), target.Hash())
+ }
+
+ if ref.Type() != plumbing.HashReference {
+ return nil
+ }
+
+ matched = true
+ refList = append(refList, ref)
+ return refs.SetReference(ref)
+ }
+
+ var ret error
+ if s.IsWildcard() {
+ iter, err := remoteRefs.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+ ret = iter.ForEach(func(ref *plumbing.Reference) error {
+ if !s.Match(ref.Name()) {
+ return nil
+ }
+
+ return onMatched(ref)
+ })
+ } else {
+ var resolvedRef *plumbing.Reference
+ src := s.Src()
+ resolvedRef, ret = expand_ref(remoteRefs, plumbing.ReferenceName(src))
+ if ret == nil {
+ ret = onMatched(resolvedRef)
+ }
+ }
+
+ if !matched && !s.IsWildcard() {
+ return nil, NoMatchingRefSpecError{refSpec: s}
+ }
+
+ return refList, ret
+}
+
+func getWants(localStorer storage.Storer, refs memory.ReferenceStorage, depth int) ([]plumbing.Hash, error) {
+ // If depth is anything other than 1 and the repo has shallow commits then just because we have the commit
+ // at the reference doesn't mean that we don't still need to fetch the parents
+ shallow := false
+ if depth != 1 {
+ if s, _ := localStorer.Shallow(); len(s) > 0 {
+ shallow = true
+ }
+ }
+
+ wants := map[plumbing.Hash]bool{}
+ for _, ref := range refs {
+ hash := ref.Hash()
+ exists, err := objectExists(localStorer, ref.Hash())
+ if err != nil {
+ return nil, err
+ }
+
+ if !exists || shallow {
+ wants[hash] = true
+ }
+ }
+
+ var result []plumbing.Hash
+ for h := range wants {
+ result = append(result, h)
+ }
+
+ return result, nil
+}
+
+func objectExists(s storer.EncodedObjectStorer, h plumbing.Hash) (bool, error) {
+ _, err := s.EncodedObject(plumbing.AnyObject, h)
+ if err == plumbing.ErrObjectNotFound {
+ return false, nil
+ }
+
+ return true, err
+}
+
+func checkFastForwardUpdate(s storer.EncodedObjectStorer, remoteRefs storer.ReferenceStorer, cmd *packp.Command) error {
+ if cmd.Old == plumbing.ZeroHash {
+ _, err := remoteRefs.Reference(cmd.Name)
+ if err == plumbing.ErrReferenceNotFound {
+ return nil
+ }
+
+ if err != nil {
+ return err
+ }
+
+ return fmt.Errorf("non-fast-forward update: %s", cmd.Name.String())
+ }
+
+ ff, err := isFastForward(s, cmd.Old, cmd.New, nil)
+ if err != nil {
+ return err
+ }
+
+ if !ff {
+ return fmt.Errorf("non-fast-forward update: %s", cmd.Name.String())
+ }
+
+ return nil
+}
+
+func isFastForward(s storer.EncodedObjectStorer, old, new plumbing.Hash, earliestShallow *plumbing.Hash) (bool, error) {
+ c, err := object.GetCommit(s, new)
+ if err != nil {
+ return false, err
+ }
+
+ parentsToIgnore := []plumbing.Hash{}
+ if earliestShallow != nil {
+ earliestCommit, err := object.GetCommit(s, *earliestShallow)
+ if err != nil {
+ return false, err
+ }
+
+ parentsToIgnore = earliestCommit.ParentHashes
+ }
+
+ found := false
+ // stop iterating at the earliest shallow commit, ignoring its parents
+ // note: when pull depth is smaller than the number of new changes on the remote, this fails due to missing parents.
+ // as far as i can tell, without the commits in-between the shallow pull and the earliest shallow, there's no
+ // real way of telling whether it will be a fast-forward merge.
+ iter := object.NewCommitPreorderIter(c, nil, parentsToIgnore)
+ err = iter.ForEach(func(c *object.Commit) error {
+ if c.Hash != old {
+ return nil
+ }
+
+ found = true
+ return storer.ErrStop
+ })
+ return found, err
+}
+
+func (r *Remote) newUploadPackRequest(o *FetchOptions,
+ ar *packp.AdvRefs) (*packp.UploadPackRequest, error) {
+
+ req := packp.NewUploadPackRequestFromCapabilities(ar.Capabilities)
+
+ if o.Depth != 0 {
+ req.Depth = packp.DepthCommits(o.Depth)
+ if err := req.Capabilities.Set(capability.Shallow); err != nil {
+ return nil, err
+ }
+ }
+
+ if o.Progress == nil && ar.Capabilities.Supports(capability.NoProgress) {
+ if err := req.Capabilities.Set(capability.NoProgress); err != nil {
+ return nil, err
+ }
+ }
+
+ isWildcard := true
+ for _, s := range o.RefSpecs {
+ if !s.IsWildcard() {
+ isWildcard = false
+ break
+ }
+ }
+
+ if isWildcard && o.Tags == TagFollowing && ar.Capabilities.Supports(capability.IncludeTag) {
+ if err := req.Capabilities.Set(capability.IncludeTag); err != nil {
+ return nil, err
+ }
+ }
+
+ return req, nil
+}
+
+func (r *Remote) isSupportedRefSpec(refs []config.RefSpec, ar *packp.AdvRefs) error {
+ var containsIsExact bool
+ for _, ref := range refs {
+ if ref.IsExactSHA1() {
+ containsIsExact = true
+ }
+ }
+
+ if !containsIsExact {
+ return nil
+ }
+
+ if ar.Capabilities.Supports(capability.AllowReachableSHA1InWant) ||
+ ar.Capabilities.Supports(capability.AllowTipSHA1InWant) {
+ return nil
+ }
+
+ return ErrExactSHA1NotSupported
+}
+
+func buildSidebandIfSupported(l *capability.List, reader io.Reader, p sideband.Progress) io.Reader {
+ var t sideband.Type
+
+ switch {
+ case l.Supports(capability.Sideband):
+ t = sideband.Sideband
+ case l.Supports(capability.Sideband64k):
+ t = sideband.Sideband64k
+ default:
+ return reader
+ }
+
+ d := sideband.NewDemuxer(t, reader)
+ d.Progress = p
+
+ return d
+}
+
+func (r *Remote) updateLocalReferenceStorage(
+ specs []config.RefSpec,
+ fetchedRefs, remoteRefs memory.ReferenceStorage,
+ specToRefs [][]*plumbing.Reference,
+ tagMode TagMode,
+ force bool,
+) (updated bool, err error) {
+ isWildcard := true
+ forceNeeded := false
+
+ for i, spec := range specs {
+ if !spec.IsWildcard() {
+ isWildcard = false
+ }
+
+ for _, ref := range specToRefs[i] {
+ if ref.Type() != plumbing.HashReference {
+ continue
+ }
+
+ localName := spec.Dst(ref.Name())
+ // If localName doesn't start with "refs/" then treat as a branch.
+ if !strings.HasPrefix(localName.String(), "refs/") {
+ localName = plumbing.NewBranchReferenceName(localName.String())
+ }
+ old, _ := storer.ResolveReference(r.s, localName)
+ new := plumbing.NewHashReference(localName, ref.Hash())
+
+ // If the ref exists locally as a non-tag and force is not
+ // specified, only update if the new ref is an ancestor of the old
+ if old != nil && !old.Name().IsTag() && !force && !spec.IsForceUpdate() {
+ ff, err := isFastForward(r.s, old.Hash(), new.Hash(), nil)
+ if err != nil {
+ return updated, err
+ }
+
+ if !ff {
+ forceNeeded = true
+ continue
+ }
+ }
+
+ refUpdated, err := checkAndUpdateReferenceStorerIfNeeded(r.s, new, old)
+ if err != nil {
+ return updated, err
+ }
+
+ if refUpdated {
+ updated = true
+ }
+ }
+ }
+
+ if tagMode == NoTags {
+ return updated, nil
+ }
+
+ tags := fetchedRefs
+ if isWildcard {
+ tags = remoteRefs
+ }
+ tagUpdated, err := r.buildFetchedTags(tags)
+ if err != nil {
+ return updated, err
+ }
+
+ if tagUpdated {
+ updated = true
+ }
+
+ if forceNeeded {
+ err = ErrForceNeeded
+ }
+
+ return
+}
+
+func (r *Remote) buildFetchedTags(refs memory.ReferenceStorage) (updated bool, err error) {
+ for _, ref := range refs {
+ if !ref.Name().IsTag() {
+ continue
+ }
+
+ _, err := r.s.EncodedObject(plumbing.AnyObject, ref.Hash())
+ if err == plumbing.ErrObjectNotFound {
+ continue
+ }
+
+ if err != nil {
+ return false, err
+ }
+
+ refUpdated, err := updateReferenceStorerIfNeeded(r.s, ref)
+ if err != nil {
+ return updated, err
+ }
+
+ if refUpdated {
+ updated = true
+ }
+ }
+
+ return
+}
+
+// List the references on the remote repository.
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects to the
+// transport operations.
+func (r *Remote) ListContext(ctx context.Context, o *ListOptions) (rfs []*plumbing.Reference, err error) {
+ return r.list(ctx, o)
+}
+
+func (r *Remote) List(o *ListOptions) (rfs []*plumbing.Reference, err error) {
+ timeout := o.Timeout
+ // Default to the old hardcoded 10s value if a timeout is not explicitly set.
+ if timeout == 0 {
+ timeout = 10
+ }
+ if timeout < 0 {
+ return nil, fmt.Errorf("invalid timeout: %d", timeout)
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
+ defer cancel()
+ return r.ListContext(ctx, o)
+}
+
+func (r *Remote) list(ctx context.Context, o *ListOptions) (rfs []*plumbing.Reference, err error) {
+ if r.c == nil || len(r.c.URLs) == 0 {
+ return nil, ErrEmptyUrls
+ }
+
+ s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle, o.ProxyOptions)
+ if err != nil {
+ return nil, err
+ }
+
+ defer ioutil.CheckClose(s, &err)
+
+ ar, err := s.AdvertisedReferencesContext(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ allRefs, err := ar.AllReferences()
+ if err != nil {
+ return nil, err
+ }
+
+ refs, err := allRefs.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+
+ var resultRefs []*plumbing.Reference
+ if o.PeelingOption == AppendPeeled || o.PeelingOption == IgnorePeeled {
+ err = refs.ForEach(func(ref *plumbing.Reference) error {
+ resultRefs = append(resultRefs, ref)
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if o.PeelingOption == AppendPeeled || o.PeelingOption == OnlyPeeled {
+ for k, v := range ar.Peeled {
+ resultRefs = append(resultRefs, plumbing.NewReferenceFromStrings(k+"^{}", v.String()))
+ }
+ }
+
+ return resultRefs, nil
+}
+
+func objectsToPush(commands []*packp.Command) []plumbing.Hash {
+ objects := make([]plumbing.Hash, 0, len(commands))
+ for _, cmd := range commands {
+ if cmd.New == plumbing.ZeroHash {
+ continue
+ }
+ objects = append(objects, cmd.New)
+ }
+ return objects
+}
+
+func referencesToHashes(refs storer.ReferenceStorer) ([]plumbing.Hash, error) {
+ iter, err := refs.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+
+ var hs []plumbing.Hash
+ err = iter.ForEach(func(ref *plumbing.Reference) error {
+ if ref.Type() != plumbing.HashReference {
+ return nil
+ }
+
+ hs = append(hs, ref.Hash())
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return hs, nil
+}
+
+func pushHashes(
+ ctx context.Context,
+ sess transport.ReceivePackSession,
+ s storage.Storer,
+ req *packp.ReferenceUpdateRequest,
+ hs []plumbing.Hash,
+ useRefDeltas bool,
+ allDelete bool,
+) (*packp.ReportStatus, error) {
+ rd, wr := io.Pipe()
+
+ config, err := s.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ // Set buffer size to 1 so the error message can be written when
+ // ReceivePack fails. Otherwise the goroutine will be blocked writing
+ // to the channel.
+ done := make(chan error, 1)
+
+ if !allDelete {
+ req.Packfile = rd
+ go func() {
+ e := packfile.NewEncoder(wr, s, useRefDeltas)
+ if _, err := e.Encode(hs, config.Pack.Window); err != nil {
+ done <- wr.CloseWithError(err)
+ return
+ }
+
+ done <- wr.Close()
+ }()
+ } else {
+ close(done)
+ }
+
+ rs, err := sess.ReceivePack(ctx, req)
+ if err != nil {
+ // close the pipe to unlock encode write
+ _ = rd.Close()
+ return nil, err
+ }
+
+ if err := <-done; err != nil {
+ return nil, err
+ }
+
+ return rs, nil
+}
+
+func (r *Remote) updateShallow(o *FetchOptions, resp *packp.UploadPackResponse) error {
+ if o.Depth == 0 || len(resp.Shallows) == 0 {
+ return nil
+ }
+
+ shallows, err := r.s.Shallow()
+ if err != nil {
+ return err
+ }
+
+outer:
+ for _, s := range resp.Shallows {
+ for _, oldS := range shallows {
+ if s == oldS {
+ continue outer
+ }
+ }
+ shallows = append(shallows, s)
+ }
+
+ return r.s.SetShallow(shallows)
+}
+
+func (r *Remote) checkRequireRemoteRefs(requires []config.RefSpec, remoteRefs storer.ReferenceStorer) error {
+ for _, require := range requires {
+ if require.IsWildcard() {
+ return fmt.Errorf("wildcards not supported in RequireRemoteRefs, got %s", require.String())
+ }
+
+ name := require.Dst("")
+ remote, err := remoteRefs.Reference(name)
+ if err != nil {
+ return fmt.Errorf("remote ref %s required to be %s but is absent", name.String(), require.Src())
+ }
+
+ var requireHash string
+ if require.IsExactSHA1() {
+ requireHash = require.Src()
+ } else {
+ target, err := storer.ResolveReference(remoteRefs, plumbing.ReferenceName(require.Src()))
+ if err != nil {
+ return fmt.Errorf("could not resolve ref %s in RequireRemoteRefs", require.Src())
+ }
+ requireHash = target.Hash().String()
+ }
+
+ if remote.Hash().String() != requireHash {
+ return fmt.Errorf("remote ref %s required to be %s but is %s", name.String(), requireHash, remote.Hash().String())
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/repository.go b/vendor/github.com/go-git/go-git/v5/repository.go
new file mode 100644
index 00000000..a57c7141
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/repository.go
@@ -0,0 +1,1886 @@
+package git
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "dario.cat/mergo"
+ "github.com/ProtonMail/go-crypto/openpgp"
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/osfs"
+ "github.com/go-git/go-billy/v5/util"
+ "github.com/go-git/go-git/v5/config"
+ "github.com/go-git/go-git/v5/internal/path_util"
+ "github.com/go-git/go-git/v5/internal/revision"
+ "github.com/go-git/go-git/v5/internal/url"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ formatcfg "github.com/go-git/go-git/v5/plumbing/format/config"
+ "github.com/go-git/go-git/v5/plumbing/format/packfile"
+ "github.com/go-git/go-git/v5/plumbing/hash"
+ "github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/storage"
+ "github.com/go-git/go-git/v5/storage/filesystem"
+ "github.com/go-git/go-git/v5/storage/filesystem/dotgit"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// GitDirName this is a special folder where all the git stuff is.
+const GitDirName = ".git"
+
+var (
+ // ErrBranchExists an error stating the specified branch already exists
+ ErrBranchExists = errors.New("branch already exists")
+ // ErrBranchNotFound an error stating the specified branch does not exist
+ ErrBranchNotFound = errors.New("branch not found")
+ // ErrTagExists an error stating the specified tag already exists
+ ErrTagExists = errors.New("tag already exists")
+ // ErrTagNotFound an error stating the specified tag does not exist
+ ErrTagNotFound = errors.New("tag not found")
+ // ErrFetching is returned when the packfile could not be downloaded
+ ErrFetching = errors.New("unable to fetch packfile")
+
+ ErrInvalidReference = errors.New("invalid reference, should be a tag or a branch")
+ ErrRepositoryNotExists = errors.New("repository does not exist")
+ ErrRepositoryIncomplete = errors.New("repository's commondir path does not exist")
+ ErrRepositoryAlreadyExists = errors.New("repository already exists")
+ ErrRemoteNotFound = errors.New("remote not found")
+ ErrRemoteExists = errors.New("remote already exists")
+ ErrAnonymousRemoteName = errors.New("anonymous remote name must be 'anonymous'")
+ ErrWorktreeNotProvided = errors.New("worktree should be provided")
+ ErrIsBareRepository = errors.New("worktree not available in a bare repository")
+ ErrUnableToResolveCommit = errors.New("unable to resolve commit")
+ ErrPackedObjectsNotSupported = errors.New("packed objects not supported")
+ ErrSHA256NotSupported = errors.New("go-git was not compiled with SHA256 support")
+ ErrAlternatePathNotSupported = errors.New("alternate path must use the file scheme")
+ ErrUnsupportedMergeStrategy = errors.New("unsupported merge strategy")
+ ErrFastForwardMergeNotPossible = errors.New("not possible to fast-forward merge changes")
+)
+
+// Repository represents a git repository
+type Repository struct {
+ Storer storage.Storer
+
+ r map[string]*Remote
+ wt billy.Filesystem
+}
+
+type InitOptions struct {
+ // The default branch (e.g. "refs/heads/master")
+ DefaultBranch plumbing.ReferenceName
+}
+
+// Init creates an empty git repository, based on the given Storer and worktree.
+// The worktree Filesystem is optional, if nil a bare repository is created. If
+// the given storer is not empty ErrRepositoryAlreadyExists is returned
+func Init(s storage.Storer, worktree billy.Filesystem) (*Repository, error) {
+ options := InitOptions{
+ DefaultBranch: plumbing.Master,
+ }
+ return InitWithOptions(s, worktree, options)
+}
+
+func InitWithOptions(s storage.Storer, worktree billy.Filesystem, options InitOptions) (*Repository, error) {
+ if err := initStorer(s); err != nil {
+ return nil, err
+ }
+
+ if options.DefaultBranch == "" {
+ options.DefaultBranch = plumbing.Master
+ }
+
+ if err := options.DefaultBranch.Validate(); err != nil {
+ return nil, err
+ }
+
+ r := newRepository(s, worktree)
+ _, err := r.Reference(plumbing.HEAD, false)
+ switch err {
+ case plumbing.ErrReferenceNotFound:
+ case nil:
+ return nil, ErrRepositoryAlreadyExists
+ default:
+ return nil, err
+ }
+
+ h := plumbing.NewSymbolicReference(plumbing.HEAD, options.DefaultBranch)
+ if err := s.SetReference(h); err != nil {
+ return nil, err
+ }
+
+ if worktree == nil {
+ _ = r.setIsBare(true)
+ return r, nil
+ }
+
+ return r, setWorktreeAndStoragePaths(r, worktree)
+}
+
+func initStorer(s storer.Storer) error {
+ i, ok := s.(storer.Initializer)
+ if !ok {
+ return nil
+ }
+
+ return i.Init()
+}
+
+func setWorktreeAndStoragePaths(r *Repository, worktree billy.Filesystem) error {
+ type fsBased interface {
+ Filesystem() billy.Filesystem
+ }
+
+ // .git file is only created if the storage is file based and the file
+ // system is osfs.OS
+ fs, isFSBased := r.Storer.(fsBased)
+ if !isFSBased {
+ return nil
+ }
+
+ if err := createDotGitFile(worktree, fs.Filesystem()); err != nil {
+ return err
+ }
+
+ return setConfigWorktree(r, worktree, fs.Filesystem())
+}
+
+func createDotGitFile(worktree, storage billy.Filesystem) error {
+ path, err := filepath.Rel(worktree.Root(), storage.Root())
+ if err != nil {
+ path = storage.Root()
+ }
+
+ if path == GitDirName {
+ // not needed, since the folder is the default place
+ return nil
+ }
+
+ f, err := worktree.Create(GitDirName)
+ if err != nil {
+ return err
+ }
+
+ defer f.Close()
+ _, err = fmt.Fprintf(f, "gitdir: %s\n", path)
+ return err
+}
+
+func setConfigWorktree(r *Repository, worktree, storage billy.Filesystem) error {
+ path, err := filepath.Rel(storage.Root(), worktree.Root())
+ if err != nil {
+ path = worktree.Root()
+ }
+
+ if path == ".." {
+ // not needed, since the folder is the default place
+ return nil
+ }
+
+ cfg, err := r.Config()
+ if err != nil {
+ return err
+ }
+
+ cfg.Core.Worktree = path
+ return r.Storer.SetConfig(cfg)
+}
+
+// Open opens a git repository using the given Storer and worktree filesystem,
+// if the given storer is complete empty ErrRepositoryNotExists is returned.
+// The worktree can be nil when the repository being opened is bare, if the
+// repository is a normal one (not bare) and worktree is nil the err
+// ErrWorktreeNotProvided is returned
+func Open(s storage.Storer, worktree billy.Filesystem) (*Repository, error) {
+ _, err := s.Reference(plumbing.HEAD)
+ if err == plumbing.ErrReferenceNotFound {
+ return nil, ErrRepositoryNotExists
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ return newRepository(s, worktree), nil
+}
+
+// Clone a repository into the given Storer and worktree Filesystem with the
+// given options, if worktree is nil a bare repository is created. If the given
+// storer is not empty ErrRepositoryAlreadyExists is returned.
+func Clone(s storage.Storer, worktree billy.Filesystem, o *CloneOptions) (*Repository, error) {
+ return CloneContext(context.Background(), s, worktree, o)
+}
+
+// CloneContext a repository into the given Storer and worktree Filesystem with
+// the given options, if worktree is nil a bare repository is created. If the
+// given storer is not empty ErrRepositoryAlreadyExists is returned.
+//
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects the
+// transport operations.
+func CloneContext(
+ ctx context.Context, s storage.Storer, worktree billy.Filesystem, o *CloneOptions,
+) (*Repository, error) {
+ r, err := Init(s, worktree)
+ if err != nil {
+ return nil, err
+ }
+
+ return r, r.clone(ctx, o)
+}
+
+// PlainInit create an empty git repository at the given path. isBare defines
+// if the repository will have worktree (non-bare) or not (bare), if the path
+// is not empty ErrRepositoryAlreadyExists is returned.
+func PlainInit(path string, isBare bool) (*Repository, error) {
+ return PlainInitWithOptions(path, &PlainInitOptions{
+ Bare: isBare,
+ })
+}
+
+func PlainInitWithOptions(path string, opts *PlainInitOptions) (*Repository, error) {
+ if opts == nil {
+ opts = &PlainInitOptions{}
+ }
+
+ var wt, dot billy.Filesystem
+
+ if opts.Bare {
+ dot = osfs.New(path)
+ } else {
+ wt = osfs.New(path)
+ dot, _ = wt.Chroot(GitDirName)
+ }
+
+ s := filesystem.NewStorage(dot, cache.NewObjectLRUDefault())
+
+ r, err := InitWithOptions(s, wt, opts.InitOptions)
+ if err != nil {
+ return nil, err
+ }
+
+ cfg, err := r.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ if opts.ObjectFormat != "" {
+ if opts.ObjectFormat == formatcfg.SHA256 && hash.CryptoType != crypto.SHA256 {
+ return nil, ErrSHA256NotSupported
+ }
+
+ cfg.Core.RepositoryFormatVersion = formatcfg.Version_1
+ cfg.Extensions.ObjectFormat = opts.ObjectFormat
+ }
+
+ err = r.Storer.SetConfig(cfg)
+ if err != nil {
+ return nil, err
+ }
+
+ return r, err
+}
+
+// PlainOpen opens a git repository from the given path. It detects if the
+// repository is bare or a normal one. If the path doesn't contain a valid
+// repository ErrRepositoryNotExists is returned
+func PlainOpen(path string) (*Repository, error) {
+ return PlainOpenWithOptions(path, &PlainOpenOptions{})
+}
+
+// PlainOpenWithOptions opens a git repository from the given path with specific
+// options. See PlainOpen for more info.
+func PlainOpenWithOptions(path string, o *PlainOpenOptions) (*Repository, error) {
+ dot, wt, err := dotGitToOSFilesystems(path, o.DetectDotGit)
+ if err != nil {
+ return nil, err
+ }
+
+ if _, err := dot.Stat(""); err != nil {
+ if os.IsNotExist(err) {
+ return nil, ErrRepositoryNotExists
+ }
+
+ return nil, err
+ }
+
+ var repositoryFs billy.Filesystem
+
+ if o.EnableDotGitCommonDir {
+ dotGitCommon, err := dotGitCommonDirectory(dot)
+ if err != nil {
+ return nil, err
+ }
+ repositoryFs = dotgit.NewRepositoryFilesystem(dot, dotGitCommon)
+ } else {
+ repositoryFs = dot
+ }
+
+ s := filesystem.NewStorage(repositoryFs, cache.NewObjectLRUDefault())
+
+ return Open(s, wt)
+}
+
+func dotGitToOSFilesystems(path string, detect bool) (dot, wt billy.Filesystem, err error) {
+ path, err = path_util.ReplaceTildeWithHome(path)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if path, err = filepath.Abs(path); err != nil {
+ return nil, nil, err
+ }
+
+ var fs billy.Filesystem
+ var fi os.FileInfo
+ for {
+ fs = osfs.New(path)
+
+ pathinfo, err := fs.Stat("/")
+ if !os.IsNotExist(err) {
+ if pathinfo == nil {
+ return nil, nil, err
+ }
+ if !pathinfo.IsDir() && detect {
+ fs = osfs.New(filepath.Dir(path))
+ }
+ }
+
+ fi, err = fs.Stat(GitDirName)
+ if err == nil {
+ // no error; stop
+ break
+ }
+ if !os.IsNotExist(err) {
+ // unknown error; stop
+ return nil, nil, err
+ }
+ if detect {
+ // try its parent as long as we haven't reached
+ // the root dir
+ if dir := filepath.Dir(path); dir != path {
+ path = dir
+ continue
+ }
+ }
+ // not detecting via parent dirs and the dir does not exist;
+ // stop
+ return fs, nil, nil
+ }
+
+ if fi.IsDir() {
+ dot, err = fs.Chroot(GitDirName)
+ return dot, fs, err
+ }
+
+ dot, err = dotGitFileToOSFilesystem(path, fs)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return dot, fs, nil
+}
+
+func dotGitFileToOSFilesystem(path string, fs billy.Filesystem) (bfs billy.Filesystem, err error) {
+ f, err := fs.Open(GitDirName)
+ if err != nil {
+ return nil, err
+ }
+ defer ioutil.CheckClose(f, &err)
+
+ b, err := io.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+
+ line := string(b)
+ const prefix = "gitdir: "
+ if !strings.HasPrefix(line, prefix) {
+ return nil, fmt.Errorf(".git file has no %s prefix", prefix)
+ }
+
+ gitdir := strings.Split(line[len(prefix):], "\n")[0]
+ gitdir = strings.TrimSpace(gitdir)
+ if filepath.IsAbs(gitdir) {
+ return osfs.New(gitdir), nil
+ }
+
+ return osfs.New(fs.Join(path, gitdir)), nil
+}
+
+func dotGitCommonDirectory(fs billy.Filesystem) (commonDir billy.Filesystem, err error) {
+ f, err := fs.Open("commondir")
+ if os.IsNotExist(err) {
+ return nil, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ b, err := io.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+ if len(b) > 0 {
+ path := strings.TrimSpace(string(b))
+ if filepath.IsAbs(path) {
+ commonDir = osfs.New(path)
+ } else {
+ commonDir = osfs.New(filepath.Join(fs.Root(), path))
+ }
+ if _, err := commonDir.Stat(""); err != nil {
+ if os.IsNotExist(err) {
+ return nil, ErrRepositoryIncomplete
+ }
+
+ return nil, err
+ }
+ }
+
+ return commonDir, nil
+}
+
+// PlainClone a repository into the path with the given options, isBare defines
+// if the new repository will be bare or normal. If the path is not empty
+// ErrRepositoryAlreadyExists is returned.
+//
+// TODO(mcuadros): move isBare to CloneOptions in v5
+func PlainClone(path string, isBare bool, o *CloneOptions) (*Repository, error) {
+ return PlainCloneContext(context.Background(), path, isBare, o)
+}
+
+// PlainCloneContext a repository into the path with the given options, isBare
+// defines if the new repository will be bare or normal. If the path is not empty
+// ErrRepositoryAlreadyExists is returned.
+//
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects the
+// transport operations.
+//
+// TODO(mcuadros): move isBare to CloneOptions in v5
+// TODO(smola): refuse upfront to clone on a non-empty directory in v5, see #1027
+func PlainCloneContext(ctx context.Context, path string, isBare bool, o *CloneOptions) (*Repository, error) {
+ cleanup, cleanupParent, err := checkIfCleanupIsNeeded(path)
+ if err != nil {
+ return nil, err
+ }
+
+ if o.Mirror {
+ isBare = true
+ }
+ r, err := PlainInit(path, isBare)
+ if err != nil {
+ return nil, err
+ }
+
+ err = r.clone(ctx, o)
+ if err != nil && err != ErrRepositoryAlreadyExists {
+ if cleanup {
+ _ = cleanUpDir(path, cleanupParent)
+ }
+ }
+
+ return r, err
+}
+
+func newRepository(s storage.Storer, worktree billy.Filesystem) *Repository {
+ return &Repository{
+ Storer: s,
+ wt: worktree,
+ r: make(map[string]*Remote),
+ }
+}
+
+func checkIfCleanupIsNeeded(path string) (cleanup bool, cleanParent bool, err error) {
+ fi, err := osfs.Default.Stat(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return true, true, nil
+ }
+
+ return false, false, err
+ }
+
+ if !fi.IsDir() {
+ return false, false, fmt.Errorf("path is not a directory: %s", path)
+ }
+
+ files, err := osfs.Default.ReadDir(path)
+ if err != nil {
+ return false, false, err
+ }
+
+ if len(files) == 0 {
+ return true, false, nil
+ }
+
+ return false, false, nil
+}
+
+func cleanUpDir(path string, all bool) error {
+ if all {
+ return util.RemoveAll(osfs.Default, path)
+ }
+
+ files, err := osfs.Default.ReadDir(path)
+ if err != nil {
+ return err
+ }
+
+ for _, fi := range files {
+ if err := util.RemoveAll(osfs.Default, osfs.Default.Join(path, fi.Name())); err != nil {
+ return err
+ }
+ }
+
+ return err
+}
+
+// Config return the repository config. In a filesystem backed repository this
+// means read the `.git/config`.
+func (r *Repository) Config() (*config.Config, error) {
+ return r.Storer.Config()
+}
+
+// SetConfig marshall and writes the repository config. In a filesystem backed
+// repository this means write the `.git/config`. This function should be called
+// with the result of `Repository.Config` and never with the output of
+// `Repository.ConfigScoped`.
+func (r *Repository) SetConfig(cfg *config.Config) error {
+ return r.Storer.SetConfig(cfg)
+}
+
+// ConfigScoped returns the repository config, merged with requested scope and
+// lower. For example if, config.GlobalScope is given the local and global config
+// are returned merged in one config value.
+func (r *Repository) ConfigScoped(scope config.Scope) (*config.Config, error) {
+ // TODO(mcuadros): v6, add this as ConfigOptions.Scoped
+
+ var err error
+ system := config.NewConfig()
+ if scope >= config.SystemScope {
+ system, err = config.LoadConfig(config.SystemScope)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ global := config.NewConfig()
+ if scope >= config.GlobalScope {
+ global, err = config.LoadConfig(config.GlobalScope)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ local, err := r.Storer.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ _ = mergo.Merge(global, system)
+ _ = mergo.Merge(local, global)
+ return local, nil
+}
+
+// Remote return a remote if exists
+func (r *Repository) Remote(name string) (*Remote, error) {
+ cfg, err := r.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ c, ok := cfg.Remotes[name]
+ if !ok {
+ return nil, ErrRemoteNotFound
+ }
+
+ return NewRemote(r.Storer, c), nil
+}
+
+// Remotes returns a list with all the remotes
+func (r *Repository) Remotes() ([]*Remote, error) {
+ cfg, err := r.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ remotes := make([]*Remote, len(cfg.Remotes))
+
+ var i int
+ for _, c := range cfg.Remotes {
+ remotes[i] = NewRemote(r.Storer, c)
+ i++
+ }
+
+ return remotes, nil
+}
+
+// CreateRemote creates a new remote
+func (r *Repository) CreateRemote(c *config.RemoteConfig) (*Remote, error) {
+ if err := c.Validate(); err != nil {
+ return nil, err
+ }
+
+ remote := NewRemote(r.Storer, c)
+
+ cfg, err := r.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ if _, ok := cfg.Remotes[c.Name]; ok {
+ return nil, ErrRemoteExists
+ }
+
+ cfg.Remotes[c.Name] = c
+ return remote, r.Storer.SetConfig(cfg)
+}
+
+// CreateRemoteAnonymous creates a new anonymous remote. c.Name must be "anonymous".
+// It's used like 'git fetch git@github.com:src-d/go-git.git master:master'.
+func (r *Repository) CreateRemoteAnonymous(c *config.RemoteConfig) (*Remote, error) {
+ if err := c.Validate(); err != nil {
+ return nil, err
+ }
+
+ if c.Name != "anonymous" {
+ return nil, ErrAnonymousRemoteName
+ }
+
+ remote := NewRemote(r.Storer, c)
+
+ return remote, nil
+}
+
+// DeleteRemote delete a remote from the repository and delete the config
+func (r *Repository) DeleteRemote(name string) error {
+ cfg, err := r.Config()
+ if err != nil {
+ return err
+ }
+
+ if _, ok := cfg.Remotes[name]; !ok {
+ return ErrRemoteNotFound
+ }
+
+ delete(cfg.Remotes, name)
+ return r.Storer.SetConfig(cfg)
+}
+
+// Branch return a Branch if exists
+func (r *Repository) Branch(name string) (*config.Branch, error) {
+ cfg, err := r.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ b, ok := cfg.Branches[name]
+ if !ok {
+ return nil, ErrBranchNotFound
+ }
+
+ return b, nil
+}
+
+// CreateBranch creates a new Branch
+func (r *Repository) CreateBranch(c *config.Branch) error {
+ if err := c.Validate(); err != nil {
+ return err
+ }
+
+ cfg, err := r.Config()
+ if err != nil {
+ return err
+ }
+
+ if _, ok := cfg.Branches[c.Name]; ok {
+ return ErrBranchExists
+ }
+
+ cfg.Branches[c.Name] = c
+ return r.Storer.SetConfig(cfg)
+}
+
+// DeleteBranch delete a Branch from the repository and delete the config
+func (r *Repository) DeleteBranch(name string) error {
+ cfg, err := r.Config()
+ if err != nil {
+ return err
+ }
+
+ if _, ok := cfg.Branches[name]; !ok {
+ return ErrBranchNotFound
+ }
+
+ delete(cfg.Branches, name)
+ return r.Storer.SetConfig(cfg)
+}
+
+// CreateTag creates a tag. If opts is included, the tag is an annotated tag,
+// otherwise a lightweight tag is created.
+func (r *Repository) CreateTag(name string, hash plumbing.Hash, opts *CreateTagOptions) (*plumbing.Reference, error) {
+ rname := plumbing.NewTagReferenceName(name)
+ if err := rname.Validate(); err != nil {
+ return nil, err
+ }
+
+ _, err := r.Storer.Reference(rname)
+ switch err {
+ case nil:
+ // Tag exists, this is an error
+ return nil, ErrTagExists
+ case plumbing.ErrReferenceNotFound:
+ // Tag missing, available for creation, pass this
+ default:
+ // Some other error
+ return nil, err
+ }
+
+ var target plumbing.Hash
+ if opts != nil {
+ target, err = r.createTagObject(name, hash, opts)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ target = hash
+ }
+
+ ref := plumbing.NewHashReference(rname, target)
+ if err = r.Storer.SetReference(ref); err != nil {
+ return nil, err
+ }
+
+ return ref, nil
+}
+
+func (r *Repository) createTagObject(name string, hash plumbing.Hash, opts *CreateTagOptions) (plumbing.Hash, error) {
+ if err := opts.Validate(r, hash); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ rawobj, err := object.GetObject(r.Storer, hash)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ tag := &object.Tag{
+ Name: name,
+ Tagger: *opts.Tagger,
+ Message: opts.Message,
+ TargetType: rawobj.Type(),
+ Target: hash,
+ }
+
+ if opts.SignKey != nil {
+ sig, err := r.buildTagSignature(tag, opts.SignKey)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ tag.PGPSignature = sig
+ }
+
+ obj := r.Storer.NewEncodedObject()
+ if err := tag.Encode(obj); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return r.Storer.SetEncodedObject(obj)
+}
+
+func (r *Repository) buildTagSignature(tag *object.Tag, signKey *openpgp.Entity) (string, error) {
+ encoded := &plumbing.MemoryObject{}
+ if err := tag.Encode(encoded); err != nil {
+ return "", err
+ }
+
+ rdr, err := encoded.Reader()
+ if err != nil {
+ return "", err
+ }
+
+ var b bytes.Buffer
+ if err := openpgp.ArmoredDetachSign(&b, signKey, rdr, nil); err != nil {
+ return "", err
+ }
+
+ return b.String(), nil
+}
+
+// Tag returns a tag from the repository.
+//
+// If you want to check to see if the tag is an annotated tag, you can call
+// TagObject on the hash of the reference in ForEach:
+//
+// ref, err := r.Tag("v0.1.0")
+// if err != nil {
+// // Handle error
+// }
+//
+// obj, err := r.TagObject(ref.Hash())
+// switch err {
+// case nil:
+// // Tag object present
+// case plumbing.ErrObjectNotFound:
+// // Not a tag object
+// default:
+// // Some other error
+// }
+func (r *Repository) Tag(name string) (*plumbing.Reference, error) {
+ ref, err := r.Reference(plumbing.ReferenceName(path.Join("refs", "tags", name)), false)
+ if err != nil {
+ if err == plumbing.ErrReferenceNotFound {
+ // Return a friendly error for this one, versus just ReferenceNotFound.
+ return nil, ErrTagNotFound
+ }
+
+ return nil, err
+ }
+
+ return ref, nil
+}
+
+// DeleteTag deletes a tag from the repository.
+func (r *Repository) DeleteTag(name string) error {
+ _, err := r.Tag(name)
+ if err != nil {
+ return err
+ }
+
+ return r.Storer.RemoveReference(plumbing.ReferenceName(path.Join("refs", "tags", name)))
+}
+
+func (r *Repository) resolveToCommitHash(h plumbing.Hash) (plumbing.Hash, error) {
+ obj, err := r.Storer.EncodedObject(plumbing.AnyObject, h)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+ switch obj.Type() {
+ case plumbing.TagObject:
+ t, err := object.DecodeTag(r.Storer, obj)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+ return r.resolveToCommitHash(t.Target)
+ case plumbing.CommitObject:
+ return h, nil
+ default:
+ return plumbing.ZeroHash, ErrUnableToResolveCommit
+ }
+}
+
+// Clone clones a remote repository
+func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
+ if err := o.Validate(); err != nil {
+ return err
+ }
+
+ c := &config.RemoteConfig{
+ Name: o.RemoteName,
+ URLs: []string{o.URL},
+ Fetch: r.cloneRefSpec(o),
+ Mirror: o.Mirror,
+ }
+
+ if _, err := r.CreateRemote(c); err != nil {
+ return err
+ }
+
+ // When the repository to clone is on the local machine,
+ // instead of using hard links, automatically setup .git/objects/info/alternates
+ // to share the objects with the source repository
+ if o.Shared {
+ if !url.IsLocalEndpoint(o.URL) {
+ return ErrAlternatePathNotSupported
+ }
+ altpath := o.URL
+ remoteRepo, err := PlainOpen(o.URL)
+ if err != nil {
+ return fmt.Errorf("failed to open remote repository: %w", err)
+ }
+ conf, err := remoteRepo.Config()
+ if err != nil {
+ return fmt.Errorf("failed to read remote repository configuration: %w", err)
+ }
+ if !conf.Core.IsBare {
+ altpath = path.Join(altpath, GitDirName)
+ }
+ if err := r.Storer.AddAlternate(altpath); err != nil {
+ return fmt.Errorf("failed to add alternate file to git objects dir: %w", err)
+ }
+ }
+
+ ref, err := r.fetchAndUpdateReferences(ctx, &FetchOptions{
+ RefSpecs: c.Fetch,
+ Depth: o.Depth,
+ Auth: o.Auth,
+ Progress: o.Progress,
+ Tags: o.Tags,
+ RemoteName: o.RemoteName,
+ InsecureSkipTLS: o.InsecureSkipTLS,
+ CABundle: o.CABundle,
+ ProxyOptions: o.ProxyOptions,
+ }, o.ReferenceName)
+ if err != nil {
+ return err
+ }
+
+ if r.wt != nil && !o.NoCheckout {
+ w, err := r.Worktree()
+ if err != nil {
+ return err
+ }
+
+ head, err := r.Head()
+ if err != nil {
+ return err
+ }
+
+ if err := w.Reset(&ResetOptions{
+ Mode: MergeReset,
+ Commit: head.Hash(),
+ }); err != nil {
+ return err
+ }
+
+ if o.RecurseSubmodules != NoRecurseSubmodules {
+ if err := w.updateSubmodules(&SubmoduleUpdateOptions{
+ RecurseSubmodules: o.RecurseSubmodules,
+ Depth: func() int {
+ if o.ShallowSubmodules {
+ return 1
+ }
+ return 0
+ }(),
+ Auth: o.Auth,
+ }); err != nil {
+ return err
+ }
+ }
+ }
+
+ if err := r.updateRemoteConfigIfNeeded(o, c, ref); err != nil {
+ return err
+ }
+
+ if !o.Mirror && ref.Name().IsBranch() {
+ branchRef := ref.Name()
+ branchName := strings.Split(string(branchRef), "refs/heads/")[1]
+
+ b := &config.Branch{
+ Name: branchName,
+ Merge: branchRef,
+ }
+
+ if o.RemoteName == "" {
+ b.Remote = "origin"
+ } else {
+ b.Remote = o.RemoteName
+ }
+
+ if err := r.CreateBranch(b); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+const (
+ refspecTag = "+refs/tags/%s:refs/tags/%[1]s"
+ refspecSingleBranch = "+refs/heads/%s:refs/remotes/%s/%[1]s"
+ refspecSingleBranchHEAD = "+HEAD:refs/remotes/%s/HEAD"
+)
+
+func (r *Repository) cloneRefSpec(o *CloneOptions) []config.RefSpec {
+ switch {
+ case o.Mirror:
+ return []config.RefSpec{"+refs/*:refs/*"}
+ case o.ReferenceName.IsTag():
+ return []config.RefSpec{
+ config.RefSpec(fmt.Sprintf(refspecTag, o.ReferenceName.Short())),
+ }
+ case o.SingleBranch && o.ReferenceName == plumbing.HEAD:
+ return []config.RefSpec{
+ config.RefSpec(fmt.Sprintf(refspecSingleBranchHEAD, o.RemoteName)),
+ }
+ case o.SingleBranch:
+ return []config.RefSpec{
+ config.RefSpec(fmt.Sprintf(refspecSingleBranch, o.ReferenceName.Short(), o.RemoteName)),
+ }
+ default:
+ return []config.RefSpec{
+ config.RefSpec(fmt.Sprintf(config.DefaultFetchRefSpec, o.RemoteName)),
+ }
+ }
+}
+
+func (r *Repository) setIsBare(isBare bool) error {
+ cfg, err := r.Config()
+ if err != nil {
+ return err
+ }
+
+ cfg.Core.IsBare = isBare
+ return r.Storer.SetConfig(cfg)
+}
+
+func (r *Repository) updateRemoteConfigIfNeeded(o *CloneOptions, c *config.RemoteConfig, head *plumbing.Reference) error {
+ if !o.SingleBranch {
+ return nil
+ }
+
+ c.Fetch = r.cloneRefSpec(o)
+
+ cfg, err := r.Config()
+ if err != nil {
+ return err
+ }
+
+ cfg.Remotes[c.Name] = c
+ return r.Storer.SetConfig(cfg)
+}
+
+func (r *Repository) fetchAndUpdateReferences(
+ ctx context.Context, o *FetchOptions, ref plumbing.ReferenceName,
+) (*plumbing.Reference, error) {
+
+ if err := o.Validate(); err != nil {
+ return nil, err
+ }
+
+ remote, err := r.Remote(o.RemoteName)
+ if err != nil {
+ return nil, err
+ }
+
+ objsUpdated := true
+ remoteRefs, err := remote.fetch(ctx, o)
+ if err == NoErrAlreadyUpToDate {
+ objsUpdated = false
+ } else if err == packfile.ErrEmptyPackfile {
+ return nil, ErrFetching
+ } else if err != nil {
+ return nil, err
+ }
+
+ resolvedRef, err := expand_ref(remoteRefs, ref)
+ if err != nil {
+ return nil, err
+ }
+
+ refsUpdated, err := r.updateReferences(remote.c.Fetch, resolvedRef)
+ if err != nil {
+ return nil, err
+ }
+
+ if !objsUpdated && !refsUpdated {
+ return nil, NoErrAlreadyUpToDate
+ }
+
+ return resolvedRef, nil
+}
+
+func (r *Repository) updateReferences(spec []config.RefSpec,
+ resolvedRef *plumbing.Reference) (updated bool, err error) {
+
+ if !resolvedRef.Name().IsBranch() {
+ // Detached HEAD mode
+ h, err := r.resolveToCommitHash(resolvedRef.Hash())
+ if err != nil {
+ return false, err
+ }
+ head := plumbing.NewHashReference(plumbing.HEAD, h)
+ return updateReferenceStorerIfNeeded(r.Storer, head)
+ }
+
+ refs := []*plumbing.Reference{
+ // Create local reference for the resolved ref
+ resolvedRef,
+ // Create local symbolic HEAD
+ plumbing.NewSymbolicReference(plumbing.HEAD, resolvedRef.Name()),
+ }
+
+ refs = append(refs, r.calculateRemoteHeadReference(spec, resolvedRef)...)
+
+ for _, ref := range refs {
+ u, err := updateReferenceStorerIfNeeded(r.Storer, ref)
+ if err != nil {
+ return updated, err
+ }
+
+ if u {
+ updated = true
+ }
+ }
+
+ return
+}
+
+func (r *Repository) calculateRemoteHeadReference(spec []config.RefSpec,
+ resolvedHead *plumbing.Reference) []*plumbing.Reference {
+
+ var refs []*plumbing.Reference
+
+ // Create resolved HEAD reference with remote prefix if it does not
+ // exist. This is needed when using single branch and HEAD.
+ for _, rs := range spec {
+ name := resolvedHead.Name()
+ if !rs.Match(name) {
+ continue
+ }
+
+ name = rs.Dst(name)
+ _, err := r.Storer.Reference(name)
+ if err == plumbing.ErrReferenceNotFound {
+ refs = append(refs, plumbing.NewHashReference(name, resolvedHead.Hash()))
+ }
+ }
+
+ return refs
+}
+
+func checkAndUpdateReferenceStorerIfNeeded(
+ s storer.ReferenceStorer, r, old *plumbing.Reference) (
+ updated bool, err error) {
+ p, err := s.Reference(r.Name())
+ if err != nil && err != plumbing.ErrReferenceNotFound {
+ return false, err
+ }
+
+ // we use the string method to compare references, is the easiest way
+ if err == plumbing.ErrReferenceNotFound || r.String() != p.String() {
+ if err := s.CheckAndSetReference(r, old); err != nil {
+ return false, err
+ }
+
+ return true, nil
+ }
+
+ return false, nil
+}
+
+func updateReferenceStorerIfNeeded(
+ s storer.ReferenceStorer, r *plumbing.Reference) (updated bool, err error) {
+ return checkAndUpdateReferenceStorerIfNeeded(s, r, nil)
+}
+
+// Fetch fetches references along with the objects necessary to complete
+// their histories, from the remote named as FetchOptions.RemoteName.
+//
+// Returns nil if the operation is successful, NoErrAlreadyUpToDate if there are
+// no changes to be fetched, or an error.
+func (r *Repository) Fetch(o *FetchOptions) error {
+ return r.FetchContext(context.Background(), o)
+}
+
+// FetchContext fetches references along with the objects necessary to complete
+// their histories, from the remote named as FetchOptions.RemoteName.
+//
+// Returns nil if the operation is successful, NoErrAlreadyUpToDate if there are
+// no changes to be fetched, or an error.
+//
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects the
+// transport operations.
+func (r *Repository) FetchContext(ctx context.Context, o *FetchOptions) error {
+ if err := o.Validate(); err != nil {
+ return err
+ }
+
+ remote, err := r.Remote(o.RemoteName)
+ if err != nil {
+ return err
+ }
+
+ return remote.FetchContext(ctx, o)
+}
+
+// Push performs a push to the remote. Returns NoErrAlreadyUpToDate if
+// the remote was already up-to-date, from the remote named as
+// FetchOptions.RemoteName.
+func (r *Repository) Push(o *PushOptions) error {
+ return r.PushContext(context.Background(), o)
+}
+
+// PushContext performs a push to the remote. Returns NoErrAlreadyUpToDate if
+// the remote was already up-to-date, from the remote named as
+// FetchOptions.RemoteName.
+//
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects the
+// transport operations.
+func (r *Repository) PushContext(ctx context.Context, o *PushOptions) error {
+ if err := o.Validate(); err != nil {
+ return err
+ }
+
+ remote, err := r.Remote(o.RemoteName)
+ if err != nil {
+ return err
+ }
+
+ return remote.PushContext(ctx, o)
+}
+
+// Log returns the commit history from the given LogOptions.
+func (r *Repository) Log(o *LogOptions) (object.CommitIter, error) {
+ fn := commitIterFunc(o.Order)
+ if fn == nil {
+ return nil, fmt.Errorf("invalid Order=%v", o.Order)
+ }
+
+ var (
+ it object.CommitIter
+ err error
+ )
+ if o.All {
+ it, err = r.logAll(fn)
+ } else {
+ it, err = r.log(o.From, fn)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if o.FileName != nil {
+ // for `git log --all` also check parent (if the next commit comes from the real parent)
+ it = r.logWithFile(*o.FileName, it, o.All)
+ }
+ if o.PathFilter != nil {
+ it = r.logWithPathFilter(o.PathFilter, it, o.All)
+ }
+
+ if o.Since != nil || o.Until != nil {
+ limitOptions := object.LogLimitOptions{Since: o.Since, Until: o.Until}
+ it = r.logWithLimit(it, limitOptions)
+ }
+
+ return it, nil
+}
+
+func (r *Repository) log(from plumbing.Hash, commitIterFunc func(*object.Commit) object.CommitIter) (object.CommitIter, error) {
+ h := from
+ if from == plumbing.ZeroHash {
+ head, err := r.Head()
+ if err != nil {
+ return nil, err
+ }
+
+ h = head.Hash()
+ }
+
+ commit, err := r.CommitObject(h)
+ if err != nil {
+ return nil, err
+ }
+ return commitIterFunc(commit), nil
+}
+
+func (r *Repository) logAll(commitIterFunc func(*object.Commit) object.CommitIter) (object.CommitIter, error) {
+ return object.NewCommitAllIter(r.Storer, commitIterFunc)
+}
+
+func (*Repository) logWithFile(fileName string, commitIter object.CommitIter, checkParent bool) object.CommitIter {
+ return object.NewCommitPathIterFromIter(
+ func(path string) bool {
+ return path == fileName
+ },
+ commitIter,
+ checkParent,
+ )
+}
+
+func (*Repository) logWithPathFilter(pathFilter func(string) bool, commitIter object.CommitIter, checkParent bool) object.CommitIter {
+ return object.NewCommitPathIterFromIter(
+ pathFilter,
+ commitIter,
+ checkParent,
+ )
+}
+
+func (*Repository) logWithLimit(commitIter object.CommitIter, limitOptions object.LogLimitOptions) object.CommitIter {
+ return object.NewCommitLimitIterFromIter(commitIter, limitOptions)
+}
+
+func commitIterFunc(order LogOrder) func(c *object.Commit) object.CommitIter {
+ switch order {
+ case LogOrderDefault:
+ return func(c *object.Commit) object.CommitIter {
+ return object.NewCommitPreorderIter(c, nil, nil)
+ }
+ case LogOrderDFS:
+ return func(c *object.Commit) object.CommitIter {
+ return object.NewCommitPreorderIter(c, nil, nil)
+ }
+ case LogOrderDFSPost:
+ return func(c *object.Commit) object.CommitIter {
+ return object.NewCommitPostorderIter(c, nil)
+ }
+ case LogOrderBSF:
+ return func(c *object.Commit) object.CommitIter {
+ return object.NewCommitIterBSF(c, nil, nil)
+ }
+ case LogOrderCommitterTime:
+ return func(c *object.Commit) object.CommitIter {
+ return object.NewCommitIterCTime(c, nil, nil)
+ }
+ }
+ return nil
+}
+
+// Tags returns all the tag References in a repository.
+//
+// If you want to check to see if the tag is an annotated tag, you can call
+// TagObject on the hash Reference passed in through ForEach:
+//
+// iter, err := r.Tags()
+// if err != nil {
+// // Handle error
+// }
+//
+// if err := iter.ForEach(func (ref *plumbing.Reference) error {
+// obj, err := r.TagObject(ref.Hash())
+// switch err {
+// case nil:
+// // Tag object present
+// case plumbing.ErrObjectNotFound:
+// // Not a tag object
+// default:
+// // Some other error
+// return err
+// }
+// }); err != nil {
+// // Handle outer iterator error
+// }
+func (r *Repository) Tags() (storer.ReferenceIter, error) {
+ refIter, err := r.Storer.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+
+ return storer.NewReferenceFilteredIter(
+ func(r *plumbing.Reference) bool {
+ return r.Name().IsTag()
+ }, refIter), nil
+}
+
+// Branches returns all the References that are Branches.
+func (r *Repository) Branches() (storer.ReferenceIter, error) {
+ refIter, err := r.Storer.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+
+ return storer.NewReferenceFilteredIter(
+ func(r *plumbing.Reference) bool {
+ return r.Name().IsBranch()
+ }, refIter), nil
+}
+
+// Notes returns all the References that are notes. For more information:
+// https://git-scm.com/docs/git-notes
+func (r *Repository) Notes() (storer.ReferenceIter, error) {
+ refIter, err := r.Storer.IterReferences()
+ if err != nil {
+ return nil, err
+ }
+
+ return storer.NewReferenceFilteredIter(
+ func(r *plumbing.Reference) bool {
+ return r.Name().IsNote()
+ }, refIter), nil
+}
+
+// TreeObject return a Tree with the given hash. If not found
+// plumbing.ErrObjectNotFound is returned
+func (r *Repository) TreeObject(h plumbing.Hash) (*object.Tree, error) {
+ return object.GetTree(r.Storer, h)
+}
+
+// TreeObjects returns an unsorted TreeIter with all the trees in the repository
+func (r *Repository) TreeObjects() (*object.TreeIter, error) {
+ iter, err := r.Storer.IterEncodedObjects(plumbing.TreeObject)
+ if err != nil {
+ return nil, err
+ }
+
+ return object.NewTreeIter(r.Storer, iter), nil
+}
+
+// CommitObject return a Commit with the given hash. If not found
+// plumbing.ErrObjectNotFound is returned.
+func (r *Repository) CommitObject(h plumbing.Hash) (*object.Commit, error) {
+ return object.GetCommit(r.Storer, h)
+}
+
+// CommitObjects returns an unsorted CommitIter with all the commits in the repository.
+func (r *Repository) CommitObjects() (object.CommitIter, error) {
+ iter, err := r.Storer.IterEncodedObjects(plumbing.CommitObject)
+ if err != nil {
+ return nil, err
+ }
+
+ return object.NewCommitIter(r.Storer, iter), nil
+}
+
+// BlobObject returns a Blob with the given hash. If not found
+// plumbing.ErrObjectNotFound is returned.
+func (r *Repository) BlobObject(h plumbing.Hash) (*object.Blob, error) {
+ return object.GetBlob(r.Storer, h)
+}
+
+// BlobObjects returns an unsorted BlobIter with all the blobs in the repository.
+func (r *Repository) BlobObjects() (*object.BlobIter, error) {
+ iter, err := r.Storer.IterEncodedObjects(plumbing.BlobObject)
+ if err != nil {
+ return nil, err
+ }
+
+ return object.NewBlobIter(r.Storer, iter), nil
+}
+
+// TagObject returns a Tag with the given hash. If not found
+// plumbing.ErrObjectNotFound is returned. This method only returns
+// annotated Tags, no lightweight Tags.
+func (r *Repository) TagObject(h plumbing.Hash) (*object.Tag, error) {
+ return object.GetTag(r.Storer, h)
+}
+
+// TagObjects returns a unsorted TagIter that can step through all of the annotated
+// tags in the repository.
+func (r *Repository) TagObjects() (*object.TagIter, error) {
+ iter, err := r.Storer.IterEncodedObjects(plumbing.TagObject)
+ if err != nil {
+ return nil, err
+ }
+
+ return object.NewTagIter(r.Storer, iter), nil
+}
+
+// Object returns an Object with the given hash. If not found
+// plumbing.ErrObjectNotFound is returned.
+func (r *Repository) Object(t plumbing.ObjectType, h plumbing.Hash) (object.Object, error) {
+ obj, err := r.Storer.EncodedObject(t, h)
+ if err != nil {
+ return nil, err
+ }
+
+ return object.DecodeObject(r.Storer, obj)
+}
+
+// Objects returns an unsorted ObjectIter with all the objects in the repository.
+func (r *Repository) Objects() (*object.ObjectIter, error) {
+ iter, err := r.Storer.IterEncodedObjects(plumbing.AnyObject)
+ if err != nil {
+ return nil, err
+ }
+
+ return object.NewObjectIter(r.Storer, iter), nil
+}
+
+// Head returns the reference where HEAD is pointing to.
+func (r *Repository) Head() (*plumbing.Reference, error) {
+ return storer.ResolveReference(r.Storer, plumbing.HEAD)
+}
+
+// Reference returns the reference for a given reference name. If resolved is
+// true, any symbolic reference will be resolved.
+func (r *Repository) Reference(name plumbing.ReferenceName, resolved bool) (
+ *plumbing.Reference, error) {
+
+ if resolved {
+ return storer.ResolveReference(r.Storer, name)
+ }
+
+ return r.Storer.Reference(name)
+}
+
+// References returns an unsorted ReferenceIter for all references.
+func (r *Repository) References() (storer.ReferenceIter, error) {
+ return r.Storer.IterReferences()
+}
+
+// Worktree returns a worktree based on the given fs, if nil the default
+// worktree will be used.
+func (r *Repository) Worktree() (*Worktree, error) {
+ if r.wt == nil {
+ return nil, ErrIsBareRepository
+ }
+
+ return &Worktree{r: r, Filesystem: r.wt}, nil
+}
+
+func expand_ref(s storer.ReferenceStorer, ref plumbing.ReferenceName) (*plumbing.Reference, error) {
+ // For improving troubleshooting, this preserves the error for the provided `ref`,
+ // and returns the error for that specific ref in case all parse rules fails.
+ var ret error
+ for _, rule := range plumbing.RefRevParseRules {
+ resolvedRef, err := storer.ResolveReference(s, plumbing.ReferenceName(fmt.Sprintf(rule, ref)))
+
+ if err == nil {
+ return resolvedRef, nil
+ } else if ret == nil {
+ ret = err
+ }
+ }
+
+ return nil, ret
+}
+
+// ResolveRevision resolves revision to corresponding hash. It will always
+// resolve to a commit hash, not a tree or annotated tag.
+//
+// Implemented resolvers : HEAD, branch, tag, heads/branch, refs/heads/branch,
+// refs/tags/tag, refs/remotes/origin/branch, refs/remotes/origin/HEAD, tilde and caret (HEAD~1, master~^, tag~2, ref/heads/master~1, ...), selection by text (HEAD^{/fix nasty bug}), hash (prefix and full)
+func (r *Repository) ResolveRevision(in plumbing.Revision) (*plumbing.Hash, error) {
+ rev := in.String()
+ if rev == "" {
+ return &plumbing.ZeroHash, plumbing.ErrReferenceNotFound
+ }
+
+ p := revision.NewParserFromString(rev)
+ items, err := p.Parse()
+
+ if err != nil {
+ return nil, err
+ }
+
+ var commit *object.Commit
+
+ for _, item := range items {
+ switch item := item.(type) {
+ case revision.Ref:
+ revisionRef := item
+
+ var tryHashes []plumbing.Hash
+
+ tryHashes = append(tryHashes, r.resolveHashPrefix(string(revisionRef))...)
+
+ ref, err := expand_ref(r.Storer, plumbing.ReferenceName(revisionRef))
+ if err == nil {
+ tryHashes = append(tryHashes, ref.Hash())
+ }
+
+ // in ambiguous cases, `git rev-parse` will emit a warning, but
+ // will always return the oid in preference to a ref; we don't have
+ // the ability to emit a warning here, so (for speed purposes)
+ // don't bother to detect the ambiguity either, just return in the
+ // priority that git would.
+ gotOne := false
+ for _, hash := range tryHashes {
+ commitObj, err := r.CommitObject(hash)
+ if err == nil {
+ commit = commitObj
+ gotOne = true
+ break
+ }
+
+ tagObj, err := r.TagObject(hash)
+ if err == nil {
+ // If the tag target lookup fails here, this most likely
+ // represents some sort of repo corruption, so let the
+ // error bubble up.
+ tagCommit, err := tagObj.Commit()
+ if err != nil {
+ return &plumbing.ZeroHash, err
+ }
+ commit = tagCommit
+ gotOne = true
+ break
+ }
+ }
+
+ if !gotOne {
+ return &plumbing.ZeroHash, plumbing.ErrReferenceNotFound
+ }
+
+ case revision.CaretPath:
+ depth := item.Depth
+
+ if depth == 0 {
+ break
+ }
+
+ iter := commit.Parents()
+
+ c, err := iter.Next()
+
+ if err != nil {
+ return &plumbing.ZeroHash, err
+ }
+
+ if depth == 1 {
+ commit = c
+
+ break
+ }
+
+ c, err = iter.Next()
+
+ if err != nil {
+ return &plumbing.ZeroHash, err
+ }
+
+ commit = c
+ case revision.TildePath:
+ for i := 0; i < item.Depth; i++ {
+ c, err := commit.Parents().Next()
+
+ if err != nil {
+ return &plumbing.ZeroHash, err
+ }
+
+ commit = c
+ }
+ case revision.CaretReg:
+ history := object.NewCommitPreorderIter(commit, nil, nil)
+
+ re := item.Regexp
+ negate := item.Negate
+
+ var c *object.Commit
+
+ err := history.ForEach(func(hc *object.Commit) error {
+ if !negate && re.MatchString(hc.Message) {
+ c = hc
+ return storer.ErrStop
+ }
+
+ if negate && !re.MatchString(hc.Message) {
+ c = hc
+ return storer.ErrStop
+ }
+
+ return nil
+ })
+ if err != nil {
+ return &plumbing.ZeroHash, err
+ }
+
+ if c == nil {
+ return &plumbing.ZeroHash, fmt.Errorf("no commit message match regexp: %q", re.String())
+ }
+
+ commit = c
+ }
+ }
+
+ if commit == nil {
+ return &plumbing.ZeroHash, plumbing.ErrReferenceNotFound
+ }
+
+ return &commit.Hash, nil
+}
+
+// resolveHashPrefix returns a list of potential hashes that the given string
+// is a prefix of. It quietly swallows errors, returning nil.
+func (r *Repository) resolveHashPrefix(hashStr string) []plumbing.Hash {
+ // Handle complete and partial hashes.
+ // plumbing.NewHash forces args into a full 20 byte hash, which isn't suitable
+ // for partial hashes since they will become zero-filled.
+
+ if hashStr == "" {
+ return nil
+ }
+ if len(hashStr) == len(plumbing.ZeroHash)*2 {
+ // Only a full hash is possible.
+ hexb, err := hex.DecodeString(hashStr)
+ if err != nil {
+ return nil
+ }
+ var h plumbing.Hash
+ copy(h[:], hexb)
+ return []plumbing.Hash{h}
+ }
+
+ // Partial hash.
+ // hex.DecodeString only decodes to complete bytes, so only works with pairs of hex digits.
+ evenHex := hashStr[:len(hashStr)&^1]
+ hexb, err := hex.DecodeString(evenHex)
+ if err != nil {
+ return nil
+ }
+ candidates := expandPartialHash(r.Storer, hexb)
+ if len(evenHex) == len(hashStr) {
+ // The prefix was an exact number of bytes.
+ return candidates
+ }
+ // Do another prefix check to ensure the dangling nybble is correct.
+ var hashes []plumbing.Hash
+ for _, h := range candidates {
+ if strings.HasPrefix(h.String(), hashStr) {
+ hashes = append(hashes, h)
+ }
+ }
+ return hashes
+}
+
+type RepackConfig struct {
+ // UseRefDeltas configures whether packfile encoder will use reference deltas.
+ // By default OFSDeltaObject is used.
+ UseRefDeltas bool
+ // OnlyDeletePacksOlderThan if set to non-zero value
+ // selects only objects older than the time provided.
+ OnlyDeletePacksOlderThan time.Time
+}
+
+func (r *Repository) RepackObjects(cfg *RepackConfig) (err error) {
+ pos, ok := r.Storer.(storer.PackedObjectStorer)
+ if !ok {
+ return ErrPackedObjectsNotSupported
+ }
+
+ // Get the existing object packs.
+ hs, err := pos.ObjectPacks()
+ if err != nil {
+ return err
+ }
+
+ // Create a new pack.
+ nh, err := r.createNewObjectPack(cfg)
+ if err != nil {
+ return err
+ }
+
+ // Delete old packs.
+ for _, h := range hs {
+ // Skip if new hash is the same as an old one.
+ if h == nh {
+ continue
+ }
+ err = pos.DeleteOldObjectPackAndIndex(h, cfg.OnlyDeletePacksOlderThan)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Merge merges the reference branch into the current branch.
+//
+// If the merge is not possible (or supported) returns an error without changing
+// the HEAD for the current branch. Possible errors include:
+// - The merge strategy is not supported.
+// - The specific strategy cannot be used (e.g. using FastForwardMerge when one is not possible).
+func (r *Repository) Merge(ref plumbing.Reference, opts MergeOptions) error {
+ if opts.Strategy != FastForwardMerge {
+ return ErrUnsupportedMergeStrategy
+ }
+
+ // Ignore error as not having a shallow list is optional here.
+ shallowList, _ := r.Storer.Shallow()
+ var earliestShallow *plumbing.Hash
+ if len(shallowList) > 0 {
+ earliestShallow = &shallowList[0]
+ }
+
+ head, err := r.Head()
+ if err != nil {
+ return err
+ }
+
+ ff, err := isFastForward(r.Storer, head.Hash(), ref.Hash(), earliestShallow)
+ if err != nil {
+ return err
+ }
+
+ if !ff {
+ return ErrFastForwardMergeNotPossible
+ }
+
+ return r.Storer.SetReference(plumbing.NewHashReference(head.Name(), ref.Hash()))
+}
+
+// createNewObjectPack is a helper for RepackObjects taking care
+// of creating a new pack. It is used so the PackfileWriter
+// deferred close has the right scope.
+func (r *Repository) createNewObjectPack(cfg *RepackConfig) (h plumbing.Hash, err error) {
+ ow := newObjectWalker(r.Storer)
+ err = ow.walkAllRefs()
+ if err != nil {
+ return h, err
+ }
+ objs := make([]plumbing.Hash, 0, len(ow.seen))
+ for h := range ow.seen {
+ objs = append(objs, h)
+ }
+ pfw, ok := r.Storer.(storer.PackfileWriter)
+ if !ok {
+ return h, fmt.Errorf("Repository storer is not a storer.PackfileWriter")
+ }
+ wc, err := pfw.PackfileWriter()
+ if err != nil {
+ return h, err
+ }
+ defer ioutil.CheckClose(wc, &err)
+ scfg, err := r.Config()
+ if err != nil {
+ return h, err
+ }
+ enc := packfile.NewEncoder(wc, r.Storer, cfg.UseRefDeltas)
+ h, err = enc.Encode(objs, scfg.Pack.Window)
+ if err != nil {
+ return h, err
+ }
+
+ // Delete the packed, loose objects.
+ if los, ok := r.Storer.(storer.LooseObjectStorer); ok {
+ err = los.ForEachObjectHash(func(hash plumbing.Hash) error {
+ if ow.isSeen(hash) {
+ err = los.DeleteLooseObject(hash)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ if err != nil {
+ return h, err
+ }
+ }
+
+ return h, err
+}
+
+func expandPartialHash(st storer.EncodedObjectStorer, prefix []byte) (hashes []plumbing.Hash) {
+ // The fast version is implemented by storage/filesystem.ObjectStorage.
+ type fastIter interface {
+ HashesWithPrefix(prefix []byte) ([]plumbing.Hash, error)
+ }
+ if fi, ok := st.(fastIter); ok {
+ h, err := fi.HashesWithPrefix(prefix)
+ if err != nil {
+ return nil
+ }
+ return h
+ }
+
+ // Slow path.
+ iter, err := st.IterEncodedObjects(plumbing.AnyObject)
+ if err != nil {
+ return nil
+ }
+ iter.ForEach(func(obj plumbing.EncodedObject) error {
+ h := obj.Hash()
+ if bytes.HasPrefix(h[:], prefix) {
+ hashes = append(hashes, h)
+ }
+ return nil
+ })
+ return
+}
diff --git a/vendor/github.com/go-git/go-git/v5/signer.go b/vendor/github.com/go-git/go-git/v5/signer.go
new file mode 100644
index 00000000..e3ef7ebd
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/signer.go
@@ -0,0 +1,33 @@
+package git
+
+import (
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+// signableObject is an object which can be signed.
+type signableObject interface {
+ EncodeWithoutSignature(o plumbing.EncodedObject) error
+}
+
+// Signer is an interface for signing git objects.
+// message is a reader containing the encoded object to be signed.
+// Implementors should return the encoded signature and an error if any.
+// See https://git-scm.com/docs/gitformat-signature for more information.
+type Signer interface {
+ Sign(message io.Reader) ([]byte, error)
+}
+
+func signObject(signer Signer, obj signableObject) ([]byte, error) {
+ encoded := &plumbing.MemoryObject{}
+ if err := obj.EncodeWithoutSignature(encoded); err != nil {
+ return nil, err
+ }
+ r, err := encoded.Reader()
+ if err != nil {
+ return nil, err
+ }
+
+ return signer.Sign(r)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/status.go b/vendor/github.com/go-git/go-git/v5/status.go
new file mode 100644
index 00000000..7f18e022
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/status.go
@@ -0,0 +1,79 @@
+package git
+
+import (
+ "bytes"
+ "fmt"
+ "path/filepath"
+)
+
+// Status represents the current status of a Worktree.
+// The key of the map is the path of the file.
+type Status map[string]*FileStatus
+
+// File returns the FileStatus for a given path, if the FileStatus doesn't
+// exists a new FileStatus is added to the map using the path as key.
+func (s Status) File(path string) *FileStatus {
+ if _, ok := (s)[path]; !ok {
+ s[path] = &FileStatus{Worktree: Untracked, Staging: Untracked}
+ }
+
+ return s[path]
+}
+
+// IsUntracked checks if file for given path is 'Untracked'
+func (s Status) IsUntracked(path string) bool {
+ stat, ok := (s)[filepath.ToSlash(path)]
+ return ok && stat.Worktree == Untracked
+}
+
+// IsClean returns true if all the files are in Unmodified status.
+func (s Status) IsClean() bool {
+ for _, status := range s {
+ if status.Worktree != Unmodified || status.Staging != Unmodified {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (s Status) String() string {
+ buf := bytes.NewBuffer(nil)
+ for path, status := range s {
+ if status.Staging == Unmodified && status.Worktree == Unmodified {
+ continue
+ }
+
+ if status.Staging == Renamed {
+ path = fmt.Sprintf("%s -> %s", path, status.Extra)
+ }
+
+ fmt.Fprintf(buf, "%c%c %s\n", status.Staging, status.Worktree, path)
+ }
+
+ return buf.String()
+}
+
+// FileStatus contains the status of a file in the worktree
+type FileStatus struct {
+ // Staging is the status of a file in the staging area
+ Staging StatusCode
+ // Worktree is the status of a file in the worktree
+ Worktree StatusCode
+ // Extra contains extra information, such as the previous name in a rename
+ Extra string
+}
+
+// StatusCode status code of a file in the Worktree
+type StatusCode byte
+
+const (
+ Unmodified StatusCode = ' '
+ Untracked StatusCode = '?'
+ Modified StatusCode = 'M'
+ Added StatusCode = 'A'
+ Deleted StatusCode = 'D'
+ Renamed StatusCode = 'R'
+ Copied StatusCode = 'C'
+ UpdatedButUnmerged StatusCode = 'U'
+)
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/config.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/config.go
new file mode 100644
index 00000000..78a64646
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/config.go
@@ -0,0 +1,48 @@
+package filesystem
+
+import (
+ "os"
+
+ "github.com/go-git/go-git/v5/config"
+ "github.com/go-git/go-git/v5/storage/filesystem/dotgit"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+type ConfigStorage struct {
+ dir *dotgit.DotGit
+}
+
+func (c *ConfigStorage) Config() (conf *config.Config, err error) {
+ f, err := c.dir.Config()
+ if err != nil {
+ if os.IsNotExist(err) {
+ return config.NewConfig(), nil
+ }
+
+ return nil, err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+ return config.ReadConfig(f)
+}
+
+func (c *ConfigStorage) SetConfig(cfg *config.Config) (err error) {
+ if err = cfg.Validate(); err != nil {
+ return err
+ }
+
+ f, err := c.dir.ConfigWriter()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+
+ b, err := cfg.Marshal()
+ if err != nil {
+ return err
+ }
+
+ _, err = f.Write(b)
+ return err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/deltaobject.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/deltaobject.go
new file mode 100644
index 00000000..6ab2cdf3
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/deltaobject.go
@@ -0,0 +1,37 @@
+package filesystem
+
+import (
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+type deltaObject struct {
+ plumbing.EncodedObject
+ base plumbing.Hash
+ hash plumbing.Hash
+ size int64
+}
+
+func newDeltaObject(
+ obj plumbing.EncodedObject,
+ hash plumbing.Hash,
+ base plumbing.Hash,
+ size int64) plumbing.DeltaObject {
+ return &deltaObject{
+ EncodedObject: obj,
+ hash: hash,
+ base: base,
+ size: size,
+ }
+}
+
+func (o *deltaObject) BaseHash() plumbing.Hash {
+ return o.base
+}
+
+func (o *deltaObject) ActualSize() int64 {
+ return o.size
+}
+
+func (o *deltaObject) ActualHash() plumbing.Hash {
+ return o.hash
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go
new file mode 100644
index 00000000..31c46948
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go
@@ -0,0 +1,1255 @@
+// https://github.com/git/git/blob/master/Documentation/gitrepository-layout.txt
+package dotgit
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path"
+ "path/filepath"
+ "reflect"
+ "runtime"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/hash"
+ "github.com/go-git/go-git/v5/storage"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/helper/chroot"
+)
+
+const (
+ suffix = ".git"
+ packedRefsPath = "packed-refs"
+ configPath = "config"
+ indexPath = "index"
+ shallowPath = "shallow"
+ modulePath = "modules"
+ objectsPath = "objects"
+ packPath = "pack"
+ refsPath = "refs"
+ branchesPath = "branches"
+ hooksPath = "hooks"
+ infoPath = "info"
+ remotesPath = "remotes"
+ logsPath = "logs"
+ worktreesPath = "worktrees"
+ alternatesPath = "alternates"
+
+ tmpPackedRefsPrefix = "._packed-refs"
+
+ packPrefix = "pack-"
+ packExt = ".pack"
+ idxExt = ".idx"
+)
+
+var (
+ // ErrNotFound is returned by New when the path is not found.
+ ErrNotFound = errors.New("path not found")
+ // ErrIdxNotFound is returned by Idxfile when the idx file is not found
+ ErrIdxNotFound = errors.New("idx file not found")
+ // ErrPackfileNotFound is returned by Packfile when the packfile is not found
+ ErrPackfileNotFound = errors.New("packfile not found")
+ // ErrConfigNotFound is returned by Config when the config is not found
+ ErrConfigNotFound = errors.New("config file not found")
+ // ErrPackedRefsDuplicatedRef is returned when a duplicated reference is
+ // found in the packed-ref file. This is usually the case for corrupted git
+ // repositories.
+ ErrPackedRefsDuplicatedRef = errors.New("duplicated ref found in packed-ref file")
+ // ErrPackedRefsBadFormat is returned when the packed-ref file corrupt.
+ ErrPackedRefsBadFormat = errors.New("malformed packed-ref")
+ // ErrSymRefTargetNotFound is returned when a symbolic reference is
+ // targeting a non-existing object. This usually means the repository
+ // is corrupt.
+ ErrSymRefTargetNotFound = errors.New("symbolic reference target not found")
+ // ErrIsDir is returned when a reference file is attempting to be read,
+ // but the path specified is a directory.
+ ErrIsDir = errors.New("reference path is a directory")
+)
+
+// Options holds configuration for the storage.
+type Options struct {
+ // ExclusiveAccess means that the filesystem is not modified externally
+ // while the repo is open.
+ ExclusiveAccess bool
+ // KeepDescriptors makes the file descriptors to be reused but they will
+ // need to be manually closed calling Close().
+ KeepDescriptors bool
+ // AlternatesFS provides the billy filesystem to be used for Git Alternates.
+ // If none is provided, it falls back to using the underlying instance used for
+ // DotGit.
+ AlternatesFS billy.Filesystem
+}
+
+// The DotGit type represents a local git repository on disk. This
+// type is not zero-value-safe, use the New function to initialize it.
+type DotGit struct {
+ options Options
+ fs billy.Filesystem
+
+ // incoming object directory information
+ incomingChecked bool
+ incomingDirName string
+
+ objectList []plumbing.Hash // sorted
+ objectMap map[plumbing.Hash]struct{}
+ packList []plumbing.Hash
+ packMap map[plumbing.Hash]struct{}
+
+ files map[plumbing.Hash]billy.File
+}
+
+// New returns a DotGit value ready to be used. The path argument must
+// be the absolute path of a git repository directory (e.g.
+// "/foo/bar/.git").
+func New(fs billy.Filesystem) *DotGit {
+ return NewWithOptions(fs, Options{})
+}
+
+// NewWithOptions sets non default configuration options.
+// See New for complete help.
+func NewWithOptions(fs billy.Filesystem, o Options) *DotGit {
+ return &DotGit{
+ options: o,
+ fs: fs,
+ }
+}
+
+// Initialize creates all the folder scaffolding.
+func (d *DotGit) Initialize() error {
+ mustExists := []string{
+ d.fs.Join("objects", "info"),
+ d.fs.Join("objects", "pack"),
+ d.fs.Join("refs", "heads"),
+ d.fs.Join("refs", "tags"),
+ }
+
+ for _, path := range mustExists {
+ _, err := d.fs.Stat(path)
+ if err == nil {
+ continue
+ }
+
+ if !os.IsNotExist(err) {
+ return err
+ }
+
+ if err := d.fs.MkdirAll(path, os.ModeDir|os.ModePerm); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Close closes all opened files.
+func (d *DotGit) Close() error {
+ var firstError error
+ if d.files != nil {
+ for _, f := range d.files {
+ err := f.Close()
+ if err != nil && firstError == nil {
+ firstError = err
+ continue
+ }
+ }
+
+ d.files = nil
+ }
+
+ if firstError != nil {
+ return firstError
+ }
+
+ return nil
+}
+
+// ConfigWriter returns a file pointer for write to the config file
+func (d *DotGit) ConfigWriter() (billy.File, error) {
+ return d.fs.Create(configPath)
+}
+
+// Config returns a file pointer for read to the config file
+func (d *DotGit) Config() (billy.File, error) {
+ return d.fs.Open(configPath)
+}
+
+// IndexWriter returns a file pointer for write to the index file
+func (d *DotGit) IndexWriter() (billy.File, error) {
+ return d.fs.Create(indexPath)
+}
+
+// Index returns a file pointer for read to the index file
+func (d *DotGit) Index() (billy.File, error) {
+ return d.fs.Open(indexPath)
+}
+
+// ShallowWriter returns a file pointer for write to the shallow file
+func (d *DotGit) ShallowWriter() (billy.File, error) {
+ return d.fs.Create(shallowPath)
+}
+
+// Shallow returns a file pointer for read to the shallow file
+func (d *DotGit) Shallow() (billy.File, error) {
+ f, err := d.fs.Open(shallowPath)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil, nil
+ }
+
+ return nil, err
+ }
+
+ return f, nil
+}
+
+// NewObjectPack return a writer for a new packfile, it saves the packfile to
+// disk and also generates and save the index for the given packfile.
+func (d *DotGit) NewObjectPack() (*PackWriter, error) {
+ d.cleanPackList()
+ return newPackWrite(d.fs)
+}
+
+// ObjectPacks returns the list of availables packfiles
+func (d *DotGit) ObjectPacks() ([]plumbing.Hash, error) {
+ if !d.options.ExclusiveAccess {
+ return d.objectPacks()
+ }
+
+ err := d.genPackList()
+ if err != nil {
+ return nil, err
+ }
+
+ return d.packList, nil
+}
+
+func (d *DotGit) objectPacks() ([]plumbing.Hash, error) {
+ packDir := d.fs.Join(objectsPath, packPath)
+ files, err := d.fs.ReadDir(packDir)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil, nil
+ }
+
+ return nil, err
+ }
+
+ var packs []plumbing.Hash
+ for _, f := range files {
+ n := f.Name()
+ if !strings.HasSuffix(n, packExt) || !strings.HasPrefix(n, packPrefix) {
+ continue
+ }
+
+ h := plumbing.NewHash(n[5 : len(n)-5]) //pack-(hash).pack
+ if h.IsZero() {
+ // Ignore files with badly-formatted names.
+ continue
+ }
+ packs = append(packs, h)
+ }
+
+ return packs, nil
+}
+
+func (d *DotGit) objectPackPath(hash plumbing.Hash, extension string) string {
+ return d.fs.Join(objectsPath, packPath, fmt.Sprintf("pack-%s.%s", hash.String(), extension))
+}
+
+func (d *DotGit) objectPackOpen(hash plumbing.Hash, extension string) (billy.File, error) {
+ if d.options.KeepDescriptors && extension == "pack" {
+ if d.files == nil {
+ d.files = make(map[plumbing.Hash]billy.File)
+ }
+
+ f, ok := d.files[hash]
+ if ok {
+ return f, nil
+ }
+ }
+
+ err := d.hasPack(hash)
+ if err != nil {
+ return nil, err
+ }
+
+ path := d.objectPackPath(hash, extension)
+ pack, err := d.fs.Open(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil, ErrPackfileNotFound
+ }
+
+ return nil, err
+ }
+
+ if d.options.KeepDescriptors && extension == "pack" {
+ d.files[hash] = pack
+ }
+
+ return pack, nil
+}
+
+// ObjectPack returns a fs.File of the given packfile
+func (d *DotGit) ObjectPack(hash plumbing.Hash) (billy.File, error) {
+ err := d.hasPack(hash)
+ if err != nil {
+ return nil, err
+ }
+
+ return d.objectPackOpen(hash, `pack`)
+}
+
+// ObjectPackIdx returns a fs.File of the index file for a given packfile
+func (d *DotGit) ObjectPackIdx(hash plumbing.Hash) (billy.File, error) {
+ err := d.hasPack(hash)
+ if err != nil {
+ return nil, err
+ }
+
+ return d.objectPackOpen(hash, `idx`)
+}
+
+func (d *DotGit) DeleteOldObjectPackAndIndex(hash plumbing.Hash, t time.Time) error {
+ d.cleanPackList()
+
+ path := d.objectPackPath(hash, `pack`)
+ if !t.IsZero() {
+ fi, err := d.fs.Stat(path)
+ if err != nil {
+ return err
+ }
+ // too new, skip deletion.
+ if !fi.ModTime().Before(t) {
+ return nil
+ }
+ }
+ err := d.fs.Remove(path)
+ if err != nil {
+ return err
+ }
+ return d.fs.Remove(d.objectPackPath(hash, `idx`))
+}
+
+// NewObject return a writer for a new object file.
+func (d *DotGit) NewObject() (*ObjectWriter, error) {
+ d.cleanObjectList()
+
+ return newObjectWriter(d.fs)
+}
+
+// ObjectsWithPrefix returns the hashes of objects that have the given prefix.
+func (d *DotGit) ObjectsWithPrefix(prefix []byte) ([]plumbing.Hash, error) {
+ // Handle edge cases.
+ if len(prefix) < 1 {
+ return d.Objects()
+ } else if len(prefix) > len(plumbing.ZeroHash) {
+ return nil, nil
+ }
+
+ if d.options.ExclusiveAccess {
+ err := d.genObjectList()
+ if err != nil {
+ return nil, err
+ }
+
+ // Rely on d.objectList being sorted.
+ // Figure out the half-open interval defined by the prefix.
+ first := sort.Search(len(d.objectList), func(i int) bool {
+ // Same as plumbing.HashSlice.Less.
+ return bytes.Compare(d.objectList[i][:], prefix) >= 0
+ })
+ lim := len(d.objectList)
+ if limPrefix, overflow := incBytes(prefix); !overflow {
+ lim = sort.Search(len(d.objectList), func(i int) bool {
+ // Same as plumbing.HashSlice.Less.
+ return bytes.Compare(d.objectList[i][:], limPrefix) >= 0
+ })
+ }
+ return d.objectList[first:lim], nil
+ }
+
+ // This is the slow path.
+ var objects []plumbing.Hash
+ var n int
+ err := d.ForEachObjectHash(func(hash plumbing.Hash) error {
+ n++
+ if bytes.HasPrefix(hash[:], prefix) {
+ objects = append(objects, hash)
+ }
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ return objects, nil
+}
+
+// Objects returns a slice with the hashes of objects found under the
+// .git/objects/ directory.
+func (d *DotGit) Objects() ([]plumbing.Hash, error) {
+ if d.options.ExclusiveAccess {
+ err := d.genObjectList()
+ if err != nil {
+ return nil, err
+ }
+
+ return d.objectList, nil
+ }
+
+ var objects []plumbing.Hash
+ err := d.ForEachObjectHash(func(hash plumbing.Hash) error {
+ objects = append(objects, hash)
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ return objects, nil
+}
+
+// ForEachObjectHash iterates over the hashes of objects found under the
+// .git/objects/ directory and executes the provided function.
+func (d *DotGit) ForEachObjectHash(fun func(plumbing.Hash) error) error {
+ if !d.options.ExclusiveAccess {
+ return d.forEachObjectHash(fun)
+ }
+
+ err := d.genObjectList()
+ if err != nil {
+ return err
+ }
+
+ for _, h := range d.objectList {
+ err := fun(h)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (d *DotGit) forEachObjectHash(fun func(plumbing.Hash) error) error {
+ files, err := d.fs.ReadDir(objectsPath)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+
+ return err
+ }
+
+ for _, f := range files {
+ if f.IsDir() && len(f.Name()) == 2 && isHex(f.Name()) {
+ base := f.Name()
+ d, err := d.fs.ReadDir(d.fs.Join(objectsPath, base))
+ if err != nil {
+ return err
+ }
+
+ for _, o := range d {
+ h := plumbing.NewHash(base + o.Name())
+ if h.IsZero() {
+ // Ignore files with badly-formatted names.
+ continue
+ }
+ err = fun(h)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+func (d *DotGit) cleanObjectList() {
+ d.objectMap = nil
+ d.objectList = nil
+}
+
+func (d *DotGit) genObjectList() error {
+ if d.objectMap != nil {
+ return nil
+ }
+
+ d.objectMap = make(map[plumbing.Hash]struct{})
+ populate := func(h plumbing.Hash) error {
+ d.objectList = append(d.objectList, h)
+ d.objectMap[h] = struct{}{}
+
+ return nil
+ }
+ if err := d.forEachObjectHash(populate); err != nil {
+ return err
+ }
+ plumbing.HashesSort(d.objectList)
+ return nil
+}
+
+func (d *DotGit) hasObject(h plumbing.Hash) error {
+ if !d.options.ExclusiveAccess {
+ return nil
+ }
+
+ err := d.genObjectList()
+ if err != nil {
+ return err
+ }
+
+ _, ok := d.objectMap[h]
+ if !ok {
+ return plumbing.ErrObjectNotFound
+ }
+
+ return nil
+}
+
+func (d *DotGit) cleanPackList() {
+ d.packMap = nil
+ d.packList = nil
+}
+
+func (d *DotGit) genPackList() error {
+ if d.packMap != nil {
+ return nil
+ }
+
+ op, err := d.objectPacks()
+ if err != nil {
+ return err
+ }
+
+ d.packMap = make(map[plumbing.Hash]struct{})
+ d.packList = nil
+
+ for _, h := range op {
+ d.packList = append(d.packList, h)
+ d.packMap[h] = struct{}{}
+ }
+
+ return nil
+}
+
+func (d *DotGit) hasPack(h plumbing.Hash) error {
+ if !d.options.ExclusiveAccess {
+ return nil
+ }
+
+ err := d.genPackList()
+ if err != nil {
+ return err
+ }
+
+ _, ok := d.packMap[h]
+ if !ok {
+ return ErrPackfileNotFound
+ }
+
+ return nil
+}
+
+func (d *DotGit) objectPath(h plumbing.Hash) string {
+ hex := h.String()
+ return d.fs.Join(objectsPath, hex[0:2], hex[2:hash.HexSize])
+}
+
+// incomingObjectPath is intended to add support for a git pre-receive hook
+// to be written it adds support for go-git to find objects in an "incoming"
+// directory, so that the library can be used to write a pre-receive hook
+// that deals with the incoming objects.
+//
+// More on git hooks found here : https://git-scm.com/docs/githooks
+// More on 'quarantine'/incoming directory here:
+//
+// https://git-scm.com/docs/git-receive-pack
+func (d *DotGit) incomingObjectPath(h plumbing.Hash) string {
+ hString := h.String()
+
+ if d.incomingDirName == "" {
+ return d.fs.Join(objectsPath, hString[0:2], hString[2:hash.HexSize])
+ }
+
+ return d.fs.Join(objectsPath, d.incomingDirName, hString[0:2], hString[2:hash.HexSize])
+}
+
+// hasIncomingObjects searches for an incoming directory and keeps its name
+// so it doesn't have to be found each time an object is accessed.
+func (d *DotGit) hasIncomingObjects() bool {
+ if !d.incomingChecked {
+ directoryContents, err := d.fs.ReadDir(objectsPath)
+ if err == nil {
+ for _, file := range directoryContents {
+ if file.IsDir() && (strings.HasPrefix(file.Name(), "tmp_objdir-incoming-") ||
+ // Before Git 2.35 incoming commits directory had another prefix
+ strings.HasPrefix(file.Name(), "incoming-")) {
+ d.incomingDirName = file.Name()
+ }
+ }
+ }
+
+ d.incomingChecked = true
+ }
+
+ return d.incomingDirName != ""
+}
+
+// Object returns a fs.File pointing the object file, if exists
+func (d *DotGit) Object(h plumbing.Hash) (billy.File, error) {
+ err := d.hasObject(h)
+ if err != nil {
+ return nil, err
+ }
+
+ obj1, err1 := d.fs.Open(d.objectPath(h))
+ if os.IsNotExist(err1) && d.hasIncomingObjects() {
+ obj2, err2 := d.fs.Open(d.incomingObjectPath(h))
+ if err2 != nil {
+ return obj1, err1
+ }
+ return obj2, err2
+ }
+ return obj1, err1
+}
+
+// ObjectStat returns a os.FileInfo pointing the object file, if exists
+func (d *DotGit) ObjectStat(h plumbing.Hash) (os.FileInfo, error) {
+ err := d.hasObject(h)
+ if err != nil {
+ return nil, err
+ }
+
+ obj1, err1 := d.fs.Stat(d.objectPath(h))
+ if os.IsNotExist(err1) && d.hasIncomingObjects() {
+ obj2, err2 := d.fs.Stat(d.incomingObjectPath(h))
+ if err2 != nil {
+ return obj1, err1
+ }
+ return obj2, err2
+ }
+ return obj1, err1
+}
+
+// ObjectDelete removes the object file, if exists
+func (d *DotGit) ObjectDelete(h plumbing.Hash) error {
+ d.cleanObjectList()
+
+ err1 := d.fs.Remove(d.objectPath(h))
+ if os.IsNotExist(err1) && d.hasIncomingObjects() {
+ err2 := d.fs.Remove(d.incomingObjectPath(h))
+ if err2 != nil {
+ return err1
+ }
+ return err2
+ }
+ return err1
+}
+
+func (d *DotGit) readReferenceFrom(rd io.Reader, name string) (ref *plumbing.Reference, err error) {
+ b, err := io.ReadAll(rd)
+ if err != nil {
+ return nil, err
+ }
+
+ line := strings.TrimSpace(string(b))
+ return plumbing.NewReferenceFromStrings(name, line), nil
+}
+
+func (d *DotGit) checkReferenceAndTruncate(f billy.File, old *plumbing.Reference) error {
+ if old == nil {
+ return nil
+ }
+ ref, err := d.readReferenceFrom(f, old.Name().String())
+ if err != nil {
+ return err
+ }
+ if ref.Hash() != old.Hash() {
+ return storage.ErrReferenceHasChanged
+ }
+ _, err = f.Seek(0, io.SeekStart)
+ if err != nil {
+ return err
+ }
+ return f.Truncate(0)
+}
+
+func (d *DotGit) SetRef(r, old *plumbing.Reference) error {
+ var content string
+ switch r.Type() {
+ case plumbing.SymbolicReference:
+ content = fmt.Sprintf("ref: %s\n", r.Target())
+ case plumbing.HashReference:
+ content = fmt.Sprintln(r.Hash().String())
+ }
+
+ fileName := r.Name().String()
+
+ return d.setRef(fileName, content, old)
+}
+
+// Refs scans the git directory collecting references, which it returns.
+// Symbolic references are resolved and included in the output.
+func (d *DotGit) Refs() ([]*plumbing.Reference, error) {
+ var refs []*plumbing.Reference
+ var seen = make(map[plumbing.ReferenceName]bool)
+ if err := d.addRefsFromRefDir(&refs, seen); err != nil {
+ return nil, err
+ }
+
+ if err := d.addRefsFromPackedRefs(&refs, seen); err != nil {
+ return nil, err
+ }
+
+ if err := d.addRefFromHEAD(&refs); err != nil {
+ return nil, err
+ }
+
+ return refs, nil
+}
+
+// Ref returns the reference for a given reference name.
+func (d *DotGit) Ref(name plumbing.ReferenceName) (*plumbing.Reference, error) {
+ ref, err := d.readReferenceFile(".", name.String())
+ if err == nil {
+ return ref, nil
+ }
+
+ return d.packedRef(name)
+}
+
+func (d *DotGit) findPackedRefsInFile(f billy.File, recv refsRecv) error {
+ s := bufio.NewScanner(f)
+ for s.Scan() {
+ ref, err := d.processLine(s.Text())
+ if err != nil {
+ return err
+ }
+
+ if !recv(ref) {
+ // skip parse
+ return nil
+ }
+ }
+ if err := s.Err(); err != nil {
+ return err
+ }
+ return nil
+}
+
+// refsRecv: returning true means that the reference continues to be resolved, otherwise it is stopped, which will speed up the lookup of a single reference.
+type refsRecv func(*plumbing.Reference) bool
+
+func (d *DotGit) findPackedRefs(recv refsRecv) error {
+ f, err := d.fs.Open(packedRefsPath)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+ return d.findPackedRefsInFile(f, recv)
+}
+
+func (d *DotGit) packedRef(name plumbing.ReferenceName) (*plumbing.Reference, error) {
+ var ref *plumbing.Reference
+ if err := d.findPackedRefs(func(r *plumbing.Reference) bool {
+ if r != nil && r.Name() == name {
+ ref = r
+ // ref found
+ return false
+ }
+ return true
+ }); err != nil {
+ return nil, err
+ }
+ if ref != nil {
+ return ref, nil
+ }
+ return nil, plumbing.ErrReferenceNotFound
+}
+
+// RemoveRef removes a reference by name.
+func (d *DotGit) RemoveRef(name plumbing.ReferenceName) error {
+ path := d.fs.Join(".", name.String())
+ _, err := d.fs.Stat(path)
+ if err == nil {
+ err = d.fs.Remove(path)
+ // Drop down to remove it from the packed refs file, too.
+ }
+
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
+ return d.rewritePackedRefsWithoutRef(name)
+}
+
+func refsRecvFunc(refs *[]*plumbing.Reference, seen map[plumbing.ReferenceName]bool) refsRecv {
+ return func(r *plumbing.Reference) bool {
+ if r != nil && !seen[r.Name()] {
+ *refs = append(*refs, r)
+ seen[r.Name()] = true
+ }
+ return true
+ }
+}
+
+func (d *DotGit) addRefsFromPackedRefs(refs *[]*plumbing.Reference, seen map[plumbing.ReferenceName]bool) (err error) {
+ return d.findPackedRefs(refsRecvFunc(refs, seen))
+}
+
+func (d *DotGit) addRefsFromPackedRefsFile(refs *[]*plumbing.Reference, f billy.File, seen map[plumbing.ReferenceName]bool) (err error) {
+ return d.findPackedRefsInFile(f, refsRecvFunc(refs, seen))
+}
+
+func (d *DotGit) openAndLockPackedRefs(doCreate bool) (
+ pr billy.File, err error) {
+ var f billy.File
+ defer func() {
+ if err != nil && f != nil {
+ ioutil.CheckClose(f, &err)
+ }
+ }()
+
+ // File mode is retrieved from a constant defined in the target specific
+ // files (dotgit_rewrite_packed_refs_*). Some modes are not available
+ // in all filesystems.
+ openFlags := d.openAndLockPackedRefsMode()
+ if doCreate {
+ openFlags |= os.O_CREATE
+ }
+
+ // Keep trying to open and lock the file until we're sure the file
+ // didn't change between the open and the lock.
+ for {
+ f, err = d.fs.OpenFile(packedRefsPath, openFlags, 0600)
+ if err != nil {
+ if os.IsNotExist(err) && !doCreate {
+ return nil, nil
+ }
+
+ return nil, err
+ }
+ fi, err := d.fs.Stat(packedRefsPath)
+ if err != nil {
+ return nil, err
+ }
+ mtime := fi.ModTime()
+
+ err = f.Lock()
+ if err != nil {
+ return nil, err
+ }
+
+ fi, err = d.fs.Stat(packedRefsPath)
+ if err != nil {
+ return nil, err
+ }
+ if mtime.Equal(fi.ModTime()) {
+ break
+ }
+ // The file has changed since we opened it. Close and retry.
+ err = f.Close()
+ if err != nil {
+ return nil, err
+ }
+ }
+ return f, nil
+}
+
+func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err error) {
+ pr, err := d.openAndLockPackedRefs(false)
+ if err != nil {
+ return err
+ }
+ if pr == nil {
+ return nil
+ }
+ defer ioutil.CheckClose(pr, &err)
+
+ // Creating the temp file in the same directory as the target file
+ // improves our chances for rename operation to be atomic.
+ tmp, err := d.fs.TempFile("", tmpPackedRefsPrefix)
+ if err != nil {
+ return err
+ }
+ tmpName := tmp.Name()
+ defer func() {
+ ioutil.CheckClose(tmp, &err)
+ _ = d.fs.Remove(tmpName) // don't check err, we might have renamed it
+ }()
+
+ s := bufio.NewScanner(pr)
+ found := false
+ for s.Scan() {
+ line := s.Text()
+ ref, err := d.processLine(line)
+ if err != nil {
+ return err
+ }
+
+ if ref != nil && ref.Name() == name {
+ found = true
+ continue
+ }
+
+ if _, err := fmt.Fprintln(tmp, line); err != nil {
+ return err
+ }
+ }
+
+ if err := s.Err(); err != nil {
+ return err
+ }
+
+ if !found {
+ return nil
+ }
+
+ return d.rewritePackedRefsWhileLocked(tmp, pr)
+}
+
+// process lines from a packed-refs file
+func (d *DotGit) processLine(line string) (*plumbing.Reference, error) {
+ if len(line) == 0 {
+ return nil, nil
+ }
+
+ switch line[0] {
+ case '#': // comment - ignore
+ return nil, nil
+ case '^': // annotated tag commit of the previous line - ignore
+ return nil, nil
+ default:
+ ws := strings.Split(line, " ") // hash then ref
+ if len(ws) != 2 {
+ return nil, ErrPackedRefsBadFormat
+ }
+
+ return plumbing.NewReferenceFromStrings(ws[1], ws[0]), nil
+ }
+}
+
+func (d *DotGit) addRefsFromRefDir(refs *[]*plumbing.Reference, seen map[plumbing.ReferenceName]bool) error {
+ return d.walkReferencesTree(refs, []string{refsPath}, seen)
+}
+
+func (d *DotGit) walkReferencesTree(refs *[]*plumbing.Reference, relPath []string, seen map[plumbing.ReferenceName]bool) error {
+ files, err := d.fs.ReadDir(d.fs.Join(relPath...))
+ if err != nil {
+ if os.IsNotExist(err) {
+ // a race happened, and our directory is gone now
+ return nil
+ }
+
+ return err
+ }
+
+ for _, f := range files {
+ newRelPath := append(append([]string(nil), relPath...), f.Name())
+ if f.IsDir() {
+ if err = d.walkReferencesTree(refs, newRelPath, seen); err != nil {
+ return err
+ }
+
+ continue
+ }
+
+ ref, err := d.readReferenceFile(".", strings.Join(newRelPath, "/"))
+ if os.IsNotExist(err) {
+ // a race happened, and our file is gone now
+ continue
+ }
+ if err != nil {
+ return err
+ }
+
+ if ref != nil && !seen[ref.Name()] {
+ *refs = append(*refs, ref)
+ seen[ref.Name()] = true
+ }
+ }
+
+ return nil
+}
+
+func (d *DotGit) addRefFromHEAD(refs *[]*plumbing.Reference) error {
+ ref, err := d.readReferenceFile(".", "HEAD")
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+
+ return err
+ }
+
+ *refs = append(*refs, ref)
+ return nil
+}
+
+func (d *DotGit) readReferenceFile(path, name string) (ref *plumbing.Reference, err error) {
+ path = d.fs.Join(path, d.fs.Join(strings.Split(name, "/")...))
+ st, err := d.fs.Stat(path)
+ if err != nil {
+ return nil, err
+ }
+ if st.IsDir() {
+ return nil, ErrIsDir
+ }
+
+ f, err := d.fs.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer ioutil.CheckClose(f, &err)
+
+ return d.readReferenceFrom(f, name)
+}
+
+func (d *DotGit) CountLooseRefs() (int, error) {
+ var refs []*plumbing.Reference
+ var seen = make(map[plumbing.ReferenceName]bool)
+ if err := d.addRefsFromRefDir(&refs, seen); err != nil {
+ return 0, err
+ }
+
+ return len(refs), nil
+}
+
+// PackRefs packs all loose refs into the packed-refs file.
+//
+// This implementation only works under the assumption that the view
+// of the file system won't be updated during this operation. This
+// strategy would not work on a general file system though, without
+// locking each loose reference and checking it again before deleting
+// the file, because otherwise an updated reference could sneak in and
+// then be deleted by the packed-refs process. Alternatively, every
+// ref update could also lock packed-refs, so only one lock is
+// required during ref-packing. But that would worsen performance in
+// the common case.
+//
+// TODO: add an "all" boolean like the `git pack-refs --all` flag.
+// When `all` is false, it would only pack refs that have already been
+// packed, plus all tags.
+func (d *DotGit) PackRefs() (err error) {
+ // Lock packed-refs, and create it if it doesn't exist yet.
+ f, err := d.openAndLockPackedRefs(true)
+ if err != nil {
+ return err
+ }
+ defer ioutil.CheckClose(f, &err)
+
+ // Gather all refs using addRefsFromRefDir and addRefsFromPackedRefs.
+ var refs []*plumbing.Reference
+ seen := make(map[plumbing.ReferenceName]bool)
+ if err = d.addRefsFromRefDir(&refs, seen); err != nil {
+ return err
+ }
+ if len(refs) == 0 {
+ // Nothing to do!
+ return nil
+ }
+ numLooseRefs := len(refs)
+ if err = d.addRefsFromPackedRefsFile(&refs, f, seen); err != nil {
+ return err
+ }
+
+ // Write them all to a new temp packed-refs file.
+ tmp, err := d.fs.TempFile("", tmpPackedRefsPrefix)
+ if err != nil {
+ return err
+ }
+ tmpName := tmp.Name()
+ defer func() {
+ ioutil.CheckClose(tmp, &err)
+ _ = d.fs.Remove(tmpName) // don't check err, we might have renamed it
+ }()
+
+ w := bufio.NewWriter(tmp)
+ for _, ref := range refs {
+ _, err = w.WriteString(ref.String() + "\n")
+ if err != nil {
+ return err
+ }
+ }
+ err = w.Flush()
+ if err != nil {
+ return err
+ }
+
+ // Rename the temp packed-refs file.
+ err = d.rewritePackedRefsWhileLocked(tmp, f)
+ if err != nil {
+ return err
+ }
+
+ // Delete all the loose refs, while still holding the packed-refs
+ // lock.
+ for _, ref := range refs[:numLooseRefs] {
+ path := d.fs.Join(".", ref.Name().String())
+ err = d.fs.Remove(path)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Module return a billy.Filesystem pointing to the module folder
+func (d *DotGit) Module(name string) (billy.Filesystem, error) {
+ return d.fs.Chroot(d.fs.Join(modulePath, name))
+}
+
+func (d *DotGit) AddAlternate(remote string) error {
+ altpath := d.fs.Join(objectsPath, infoPath, alternatesPath)
+
+ f, err := d.fs.OpenFile(altpath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0640)
+ if err != nil {
+ return fmt.Errorf("cannot open file: %w", err)
+ }
+ defer f.Close()
+
+ // locking in windows throws an error, based on comments
+ // https://github.com/go-git/go-git/pull/860#issuecomment-1751823044
+ // do not lock on windows platform.
+ if runtime.GOOS != "windows" {
+ if err = f.Lock(); err != nil {
+ return fmt.Errorf("cannot lock file: %w", err)
+ }
+ defer f.Unlock()
+ }
+
+ line := path.Join(remote, objectsPath) + "\n"
+ _, err = io.WriteString(f, line)
+ if err != nil {
+ return fmt.Errorf("error writing 'alternates' file: %w", err)
+ }
+
+ return nil
+}
+
+// Alternates returns DotGit(s) based off paths in objects/info/alternates if
+// available. This can be used to checks if it's a shared repository.
+func (d *DotGit) Alternates() ([]*DotGit, error) {
+ altpath := d.fs.Join(objectsPath, infoPath, alternatesPath)
+ f, err := d.fs.Open(altpath)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ fs := d.options.AlternatesFS
+ if fs == nil {
+ fs = d.fs
+ }
+
+ var alternates []*DotGit
+ seen := make(map[string]struct{})
+
+ // Read alternate paths line-by-line and create DotGit objects.
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ path := scanner.Text()
+
+ // Avoid creating multiple dotgits for the same alternative path.
+ if _, ok := seen[path]; ok {
+ continue
+ }
+
+ seen[path] = struct{}{}
+
+ if filepath.IsAbs(path) {
+ // Handling absolute paths should be straight-forward. However, the default osfs (Chroot)
+ // tries to concatenate an abs path with the root path in some operations (e.g. Stat),
+ // which leads to unexpected errors. Therefore, make the path relative to the current FS instead.
+ if reflect.TypeOf(fs) == reflect.TypeOf(&chroot.ChrootHelper{}) {
+ path, err = filepath.Rel(fs.Root(), path)
+ if err != nil {
+ return nil, fmt.Errorf("cannot make path %q relative: %w", path, err)
+ }
+ }
+ } else {
+ // By Git conventions, relative paths should be based on the object database (.git/objects/info)
+ // location as per: https://www.kernel.org/pub/software/scm/git/docs/gitrepository-layout.html
+ // However, due to the nature of go-git and its filesystem handling via Billy, paths cannot
+ // cross its "chroot boundaries". Therefore, ignore any "../" and treat the path from the
+ // fs root. If this is not correct based on the dotgit fs, set a different one via AlternatesFS.
+ abs := filepath.Join(string(filepath.Separator), filepath.ToSlash(path))
+ path = filepath.FromSlash(abs)
+ }
+
+ // Aligns with upstream behavior: exit if target path is not a valid directory.
+ if fi, err := fs.Stat(path); err != nil || !fi.IsDir() {
+ return nil, fmt.Errorf("invalid object directory %q: %w", path, err)
+ }
+ afs, err := fs.Chroot(filepath.Dir(path))
+ if err != nil {
+ return nil, fmt.Errorf("cannot chroot %q: %w", path, err)
+ }
+ alternates = append(alternates, New(afs))
+ }
+
+ if err = scanner.Err(); err != nil {
+ return nil, err
+ }
+
+ return alternates, nil
+}
+
+// Fs returns the underlying filesystem of the DotGit folder.
+func (d *DotGit) Fs() billy.Filesystem {
+ return d.fs
+}
+
+func isHex(s string) bool {
+ for _, b := range []byte(s) {
+ if isNum(b) {
+ continue
+ }
+ if isHexAlpha(b) {
+ continue
+ }
+
+ return false
+ }
+
+ return true
+}
+
+func isNum(b byte) bool {
+ return b >= '0' && b <= '9'
+}
+
+func isHexAlpha(b byte) bool {
+ return b >= 'a' && b <= 'f' || b >= 'A' && b <= 'F'
+}
+
+// incBytes increments a byte slice, which involves incrementing the
+// right-most byte, and following carry leftward.
+// It makes a copy so that the provided slice's underlying array is not modified.
+// If the overall operation overflows (e.g. incBytes(0xff, 0xff)), the second return parameter indicates that.
+func incBytes(in []byte) (out []byte, overflow bool) {
+ out = make([]byte, len(in))
+ copy(out, in)
+ for i := len(out) - 1; i >= 0; i-- {
+ out[i]++
+ if out[i] != 0 {
+ return // Didn't overflow.
+ }
+ }
+ overflow = true
+ return
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_rewrite_packed_refs.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_rewrite_packed_refs.go
new file mode 100644
index 00000000..43263ead
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_rewrite_packed_refs.go
@@ -0,0 +1,81 @@
+package dotgit
+
+import (
+ "io"
+ "os"
+ "runtime"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+func (d *DotGit) openAndLockPackedRefsMode() int {
+ if billy.CapabilityCheck(d.fs, billy.ReadAndWriteCapability) {
+ return os.O_RDWR
+ }
+
+ return os.O_RDONLY
+}
+
+func (d *DotGit) rewritePackedRefsWhileLocked(
+ tmp billy.File, pr billy.File) error {
+ // Try plain rename. If we aren't using the bare Windows filesystem as the
+ // storage layer, we might be able to get away with a rename over a locked
+ // file.
+ err := d.fs.Rename(tmp.Name(), pr.Name())
+ if err == nil {
+ return nil
+ }
+
+ // If we are in a filesystem that does not support rename (e.g. sivafs)
+ // a full copy is done.
+ if err == billy.ErrNotSupported {
+ return d.copyNewFile(tmp, pr)
+ }
+
+ if runtime.GOOS != "windows" {
+ return err
+ }
+
+ // Otherwise, Windows doesn't let us rename over a locked file, so
+ // we have to do a straight copy. Unfortunately this could result
+ // in a partially-written file if the process fails before the
+ // copy completes.
+ return d.copyToExistingFile(tmp, pr)
+}
+
+func (d *DotGit) copyToExistingFile(tmp, pr billy.File) error {
+ _, err := pr.Seek(0, io.SeekStart)
+ if err != nil {
+ return err
+ }
+ err = pr.Truncate(0)
+ if err != nil {
+ return err
+ }
+ _, err = tmp.Seek(0, io.SeekStart)
+ if err != nil {
+ return err
+ }
+ _, err = io.Copy(pr, tmp)
+
+ return err
+}
+
+func (d *DotGit) copyNewFile(tmp billy.File, pr billy.File) (err error) {
+ prWrite, err := d.fs.Create(pr.Name())
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(prWrite, &err)
+
+ _, err = tmp.Seek(0, io.SeekStart)
+ if err != nil {
+ return err
+ }
+
+ _, err = io.Copy(prWrite, tmp)
+
+ return err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_setref.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_setref.go
new file mode 100644
index 00000000..c057f5c4
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit_setref.go
@@ -0,0 +1,90 @@
+package dotgit
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+func (d *DotGit) setRef(fileName, content string, old *plumbing.Reference) (err error) {
+ if billy.CapabilityCheck(d.fs, billy.ReadAndWriteCapability) {
+ return d.setRefRwfs(fileName, content, old)
+ }
+
+ return d.setRefNorwfs(fileName, content, old)
+}
+
+func (d *DotGit) setRefRwfs(fileName, content string, old *plumbing.Reference) (err error) {
+ // If we are not checking an old ref, just truncate the file.
+ mode := os.O_RDWR | os.O_CREATE
+ if old == nil {
+ mode |= os.O_TRUNC
+ }
+
+ f, err := d.fs.OpenFile(fileName, mode, 0666)
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+
+ // Lock is unlocked by the deferred Close above. This is because Unlock
+ // does not imply a fsync and thus there would be a race between
+ // Unlock+Close and other concurrent writers. Adding Sync to go-billy
+ // could work, but this is better (and avoids superfluous syncs).
+ err = f.Lock()
+ if err != nil {
+ return err
+ }
+
+ // this is a no-op to call even when old is nil.
+ err = d.checkReferenceAndTruncate(f, old)
+ if err != nil {
+ return err
+ }
+
+ _, err = f.Write([]byte(content))
+ return err
+}
+
+// There are some filesystems that don't support opening files in RDWD mode.
+// In these filesystems the standard SetRef function can not be used as it
+// reads the reference file to check that it's not modified before updating it.
+//
+// This version of the function writes the reference without extra checks
+// making it compatible with these simple filesystems. This is usually not
+// a problem as they should be accessed by only one process at a time.
+func (d *DotGit) setRefNorwfs(fileName, content string, old *plumbing.Reference) error {
+ _, err := d.fs.Stat(fileName)
+ if err == nil && old != nil {
+ fRead, err := d.fs.Open(fileName)
+ if err != nil {
+ return err
+ }
+
+ ref, err := d.readReferenceFrom(fRead, old.Name().String())
+ fRead.Close()
+
+ if err != nil {
+ return err
+ }
+
+ if ref.Hash() != old.Hash() {
+ return fmt.Errorf("reference has changed concurrently")
+ }
+ }
+
+ f, err := d.fs.Create(fileName)
+ if err != nil {
+ return err
+ }
+
+ defer f.Close()
+
+ _, err = f.Write([]byte(content))
+ return err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/reader.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/reader.go
new file mode 100644
index 00000000..975f92ac
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/reader.go
@@ -0,0 +1,79 @@
+package dotgit
+
+import (
+ "fmt"
+ "io"
+ "os"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/objfile"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+var _ (plumbing.EncodedObject) = &EncodedObject{}
+
+type EncodedObject struct {
+ dir *DotGit
+ h plumbing.Hash
+ t plumbing.ObjectType
+ sz int64
+}
+
+func (e *EncodedObject) Hash() plumbing.Hash {
+ return e.h
+}
+
+func (e *EncodedObject) Reader() (io.ReadCloser, error) {
+ f, err := e.dir.Object(e.h)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil, plumbing.ErrObjectNotFound
+ }
+
+ return nil, err
+ }
+ r, err := objfile.NewReader(f)
+ if err != nil {
+ return nil, err
+ }
+
+ t, size, err := r.Header()
+ if err != nil {
+ _ = r.Close()
+ return nil, err
+ }
+ if t != e.t {
+ _ = r.Close()
+ return nil, objfile.ErrHeader
+ }
+ if size != e.sz {
+ _ = r.Close()
+ return nil, objfile.ErrHeader
+ }
+ return ioutil.NewReadCloserWithCloser(r, f.Close), nil
+}
+
+func (e *EncodedObject) SetType(plumbing.ObjectType) {}
+
+func (e *EncodedObject) Type() plumbing.ObjectType {
+ return e.t
+}
+
+func (e *EncodedObject) Size() int64 {
+ return e.sz
+}
+
+func (e *EncodedObject) SetSize(int64) {}
+
+func (e *EncodedObject) Writer() (io.WriteCloser, error) {
+ return nil, fmt.Errorf("not supported")
+}
+
+func NewEncodedObject(dir *DotGit, h plumbing.Hash, t plumbing.ObjectType, size int64) *EncodedObject {
+ return &EncodedObject{
+ dir: dir,
+ h: h,
+ t: t,
+ sz: size,
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/repository_filesystem.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/repository_filesystem.go
new file mode 100644
index 00000000..8d243efe
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/repository_filesystem.go
@@ -0,0 +1,111 @@
+package dotgit
+
+import (
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+// RepositoryFilesystem is a billy.Filesystem compatible object wrapper
+// which handles dot-git filesystem operations and supports commondir according to git scm layout:
+// https://github.com/git/git/blob/master/Documentation/gitrepository-layout.txt
+type RepositoryFilesystem struct {
+ dotGitFs billy.Filesystem
+ commonDotGitFs billy.Filesystem
+}
+
+func NewRepositoryFilesystem(dotGitFs, commonDotGitFs billy.Filesystem) *RepositoryFilesystem {
+ return &RepositoryFilesystem{
+ dotGitFs: dotGitFs,
+ commonDotGitFs: commonDotGitFs,
+ }
+}
+
+func (fs *RepositoryFilesystem) mapToRepositoryFsByPath(path string) billy.Filesystem {
+ // Nothing to decide if commondir not defined
+ if fs.commonDotGitFs == nil {
+ return fs.dotGitFs
+ }
+
+ cleanPath := filepath.Clean(path)
+
+ // Check exceptions for commondir (https://git-scm.com/docs/gitrepository-layout#Documentation/gitrepository-layout.txt)
+ switch cleanPath {
+ case fs.dotGitFs.Join(logsPath, "HEAD"):
+ return fs.dotGitFs
+ case fs.dotGitFs.Join(refsPath, "bisect"), fs.dotGitFs.Join(refsPath, "rewritten"), fs.dotGitFs.Join(refsPath, "worktree"):
+ return fs.dotGitFs
+ }
+
+ // Determine dot-git root by first path element.
+ // There are some elements which should always use commondir when commondir defined.
+ // Usual dot-git root will be used for the rest of files.
+ switch strings.Split(cleanPath, string(filepath.Separator))[0] {
+ case objectsPath, refsPath, packedRefsPath, configPath, branchesPath, hooksPath, infoPath, remotesPath, logsPath, shallowPath, worktreesPath:
+ return fs.commonDotGitFs
+ default:
+ return fs.dotGitFs
+ }
+}
+
+func (fs *RepositoryFilesystem) Create(filename string) (billy.File, error) {
+ return fs.mapToRepositoryFsByPath(filename).Create(filename)
+}
+
+func (fs *RepositoryFilesystem) Open(filename string) (billy.File, error) {
+ return fs.mapToRepositoryFsByPath(filename).Open(filename)
+}
+
+func (fs *RepositoryFilesystem) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
+ return fs.mapToRepositoryFsByPath(filename).OpenFile(filename, flag, perm)
+}
+
+func (fs *RepositoryFilesystem) Stat(filename string) (os.FileInfo, error) {
+ return fs.mapToRepositoryFsByPath(filename).Stat(filename)
+}
+
+func (fs *RepositoryFilesystem) Rename(oldpath, newpath string) error {
+ return fs.mapToRepositoryFsByPath(oldpath).Rename(oldpath, newpath)
+}
+
+func (fs *RepositoryFilesystem) Remove(filename string) error {
+ return fs.mapToRepositoryFsByPath(filename).Remove(filename)
+}
+
+func (fs *RepositoryFilesystem) Join(elem ...string) string {
+ return fs.dotGitFs.Join(elem...)
+}
+
+func (fs *RepositoryFilesystem) TempFile(dir, prefix string) (billy.File, error) {
+ return fs.mapToRepositoryFsByPath(dir).TempFile(dir, prefix)
+}
+
+func (fs *RepositoryFilesystem) ReadDir(path string) ([]os.FileInfo, error) {
+ return fs.mapToRepositoryFsByPath(path).ReadDir(path)
+}
+
+func (fs *RepositoryFilesystem) MkdirAll(filename string, perm os.FileMode) error {
+ return fs.mapToRepositoryFsByPath(filename).MkdirAll(filename, perm)
+}
+
+func (fs *RepositoryFilesystem) Lstat(filename string) (os.FileInfo, error) {
+ return fs.mapToRepositoryFsByPath(filename).Lstat(filename)
+}
+
+func (fs *RepositoryFilesystem) Symlink(target, link string) error {
+ return fs.mapToRepositoryFsByPath(target).Symlink(target, link)
+}
+
+func (fs *RepositoryFilesystem) Readlink(link string) (string, error) {
+ return fs.mapToRepositoryFsByPath(link).Readlink(link)
+}
+
+func (fs *RepositoryFilesystem) Chroot(path string) (billy.Filesystem, error) {
+ return fs.mapToRepositoryFsByPath(path).Chroot(path)
+}
+
+func (fs *RepositoryFilesystem) Root() string {
+ return fs.dotGitFs.Root()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/writers.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/writers.go
new file mode 100644
index 00000000..849b7a17
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/writers.go
@@ -0,0 +1,285 @@
+package dotgit
+
+import (
+ "fmt"
+ "io"
+ "sync/atomic"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/idxfile"
+ "github.com/go-git/go-git/v5/plumbing/format/objfile"
+ "github.com/go-git/go-git/v5/plumbing/format/packfile"
+ "github.com/go-git/go-git/v5/plumbing/hash"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+// PackWriter is a io.Writer that generates the packfile index simultaneously,
+// a packfile.Decoder is used with a file reader to read the file being written
+// this operation is synchronized with the write operations.
+// The packfile is written in a temp file, when Close is called this file
+// is renamed/moved (depends on the Filesystem implementation) to the final
+// location, if the PackWriter is not used, nothing is written
+type PackWriter struct {
+ Notify func(plumbing.Hash, *idxfile.Writer)
+
+ fs billy.Filesystem
+ fr, fw billy.File
+ synced *syncedReader
+ checksum plumbing.Hash
+ parser *packfile.Parser
+ writer *idxfile.Writer
+ result chan error
+}
+
+func newPackWrite(fs billy.Filesystem) (*PackWriter, error) {
+ fw, err := fs.TempFile(fs.Join(objectsPath, packPath), "tmp_pack_")
+ if err != nil {
+ return nil, err
+ }
+
+ fr, err := fs.Open(fw.Name())
+ if err != nil {
+ return nil, err
+ }
+
+ writer := &PackWriter{
+ fs: fs,
+ fw: fw,
+ fr: fr,
+ synced: newSyncedReader(fw, fr),
+ result: make(chan error),
+ }
+
+ go writer.buildIndex()
+ return writer, nil
+}
+
+func (w *PackWriter) buildIndex() {
+ s := packfile.NewScanner(w.synced)
+ w.writer = new(idxfile.Writer)
+ var err error
+ w.parser, err = packfile.NewParser(s, w.writer)
+ if err != nil {
+ w.result <- err
+ return
+ }
+
+ checksum, err := w.parser.Parse()
+ if err != nil {
+ w.result <- err
+ return
+ }
+
+ w.checksum = checksum
+ w.result <- err
+}
+
+// waitBuildIndex waits until buildIndex function finishes, this can terminate
+// with a packfile.ErrEmptyPackfile, this means that nothing was written so we
+// ignore the error
+func (w *PackWriter) waitBuildIndex() error {
+ err := <-w.result
+ if err == packfile.ErrEmptyPackfile {
+ return nil
+ }
+
+ return err
+}
+
+func (w *PackWriter) Write(p []byte) (int, error) {
+ return w.synced.Write(p)
+}
+
+// Close closes all the file descriptors and save the final packfile, if nothing
+// was written, the tempfiles are deleted without writing a packfile.
+func (w *PackWriter) Close() error {
+ defer func() {
+ if w.Notify != nil && w.writer != nil && w.writer.Finished() {
+ w.Notify(w.checksum, w.writer)
+ }
+
+ close(w.result)
+ }()
+
+ if err := w.synced.Close(); err != nil {
+ return err
+ }
+
+ if err := w.waitBuildIndex(); err != nil {
+ return err
+ }
+
+ if err := w.fr.Close(); err != nil {
+ return err
+ }
+
+ if err := w.fw.Close(); err != nil {
+ return err
+ }
+
+ if w.writer == nil || !w.writer.Finished() {
+ return w.clean()
+ }
+
+ return w.save()
+}
+
+func (w *PackWriter) clean() error {
+ return w.fs.Remove(w.fw.Name())
+}
+
+func (w *PackWriter) save() error {
+ base := w.fs.Join(objectsPath, packPath, fmt.Sprintf("pack-%s", w.checksum))
+ idx, err := w.fs.Create(fmt.Sprintf("%s.idx", base))
+ if err != nil {
+ return err
+ }
+
+ if err := w.encodeIdx(idx); err != nil {
+ return err
+ }
+
+ if err := idx.Close(); err != nil {
+ return err
+ }
+
+ return w.fs.Rename(w.fw.Name(), fmt.Sprintf("%s.pack", base))
+}
+
+func (w *PackWriter) encodeIdx(writer io.Writer) error {
+ idx, err := w.writer.Index()
+ if err != nil {
+ return err
+ }
+
+ e := idxfile.NewEncoder(writer)
+ _, err = e.Encode(idx)
+ return err
+}
+
+type syncedReader struct {
+ w io.Writer
+ r io.ReadSeeker
+
+ blocked, done uint32
+ written, read uint64
+ news chan bool
+}
+
+func newSyncedReader(w io.Writer, r io.ReadSeeker) *syncedReader {
+ return &syncedReader{
+ w: w,
+ r: r,
+ news: make(chan bool),
+ }
+}
+
+func (s *syncedReader) Write(p []byte) (n int, err error) {
+ defer func() {
+ written := atomic.AddUint64(&s.written, uint64(n))
+ read := atomic.LoadUint64(&s.read)
+ if written > read {
+ s.wake()
+ }
+ }()
+
+ n, err = s.w.Write(p)
+ return
+}
+
+func (s *syncedReader) Read(p []byte) (n int, err error) {
+ defer func() { atomic.AddUint64(&s.read, uint64(n)) }()
+
+ for {
+ s.sleep()
+ n, err = s.r.Read(p)
+ if err == io.EOF && !s.isDone() && n == 0 {
+ continue
+ }
+
+ break
+ }
+
+ return
+}
+
+func (s *syncedReader) isDone() bool {
+ return atomic.LoadUint32(&s.done) == 1
+}
+
+func (s *syncedReader) isBlocked() bool {
+ return atomic.LoadUint32(&s.blocked) == 1
+}
+
+func (s *syncedReader) wake() {
+ if s.isBlocked() {
+ atomic.StoreUint32(&s.blocked, 0)
+ s.news <- true
+ }
+}
+
+func (s *syncedReader) sleep() {
+ read := atomic.LoadUint64(&s.read)
+ written := atomic.LoadUint64(&s.written)
+ if read >= written {
+ atomic.StoreUint32(&s.blocked, 1)
+ <-s.news
+ }
+
+}
+
+func (s *syncedReader) Seek(offset int64, whence int) (int64, error) {
+ if whence == io.SeekCurrent {
+ return s.r.Seek(offset, whence)
+ }
+
+ p, err := s.r.Seek(offset, whence)
+ atomic.StoreUint64(&s.read, uint64(p))
+
+ return p, err
+}
+
+func (s *syncedReader) Close() error {
+ atomic.StoreUint32(&s.done, 1)
+ close(s.news)
+ return nil
+}
+
+type ObjectWriter struct {
+ objfile.Writer
+ fs billy.Filesystem
+ f billy.File
+}
+
+func newObjectWriter(fs billy.Filesystem) (*ObjectWriter, error) {
+ f, err := fs.TempFile(fs.Join(objectsPath, packPath), "tmp_obj_")
+ if err != nil {
+ return nil, err
+ }
+
+ return &ObjectWriter{
+ Writer: (*objfile.NewWriter(f)),
+ fs: fs,
+ f: f,
+ }, nil
+}
+
+func (w *ObjectWriter) Close() error {
+ if err := w.Writer.Close(); err != nil {
+ return err
+ }
+
+ if err := w.f.Close(); err != nil {
+ return err
+ }
+
+ return w.save()
+}
+
+func (w *ObjectWriter) save() error {
+ hex := w.Hash().String()
+ file := w.fs.Join(objectsPath, hex[0:2], hex[2:hash.HexSize])
+
+ return w.fs.Rename(w.f.Name(), file)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/index.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/index.go
new file mode 100644
index 00000000..a19176f8
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/index.go
@@ -0,0 +1,54 @@
+package filesystem
+
+import (
+ "bufio"
+ "os"
+
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+ "github.com/go-git/go-git/v5/storage/filesystem/dotgit"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+type IndexStorage struct {
+ dir *dotgit.DotGit
+}
+
+func (s *IndexStorage) SetIndex(idx *index.Index) (err error) {
+ f, err := s.dir.IndexWriter()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+ bw := bufio.NewWriter(f)
+ defer func() {
+ if e := bw.Flush(); err == nil && e != nil {
+ err = e
+ }
+ }()
+
+ e := index.NewEncoder(bw)
+ err = e.Encode(idx)
+ return err
+}
+
+func (s *IndexStorage) Index() (i *index.Index, err error) {
+ idx := &index.Index{
+ Version: 2,
+ }
+
+ f, err := s.dir.Index()
+ if err != nil {
+ if os.IsNotExist(err) {
+ return idx, nil
+ }
+
+ return nil, err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+
+ d := index.NewDecoder(bufio.NewReader(f))
+ err = d.Decode(idx)
+ return idx, err
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/module.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/module.go
new file mode 100644
index 00000000..20336c11
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/module.go
@@ -0,0 +1,20 @@
+package filesystem
+
+import (
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ "github.com/go-git/go-git/v5/storage"
+ "github.com/go-git/go-git/v5/storage/filesystem/dotgit"
+)
+
+type ModuleStorage struct {
+ dir *dotgit.DotGit
+}
+
+func (s *ModuleStorage) Module(name string) (storage.Storer, error) {
+ fs, err := s.dir.Module(name)
+ if err != nil {
+ return nil, err
+ }
+
+ return NewStorage(fs, cache.NewObjectLRUDefault()), nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/object.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/object.go
new file mode 100644
index 00000000..e812fe93
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/object.go
@@ -0,0 +1,892 @@
+package filesystem
+
+import (
+ "bytes"
+ "io"
+ "os"
+ "sync"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ "github.com/go-git/go-git/v5/plumbing/format/idxfile"
+ "github.com/go-git/go-git/v5/plumbing/format/objfile"
+ "github.com/go-git/go-git/v5/plumbing/format/packfile"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/storage/filesystem/dotgit"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+type ObjectStorage struct {
+ options Options
+
+ // objectCache is an object cache uses to cache delta's bases and also recently
+ // loaded loose objects
+ objectCache cache.Object
+
+ dir *dotgit.DotGit
+ index map[plumbing.Hash]idxfile.Index
+
+ packList []plumbing.Hash
+ packListIdx int
+ packfiles map[plumbing.Hash]*packfile.Packfile
+}
+
+// NewObjectStorage creates a new ObjectStorage with the given .git directory and cache.
+func NewObjectStorage(dir *dotgit.DotGit, objectCache cache.Object) *ObjectStorage {
+ return NewObjectStorageWithOptions(dir, objectCache, Options{})
+}
+
+// NewObjectStorageWithOptions creates a new ObjectStorage with the given .git directory, cache and extra options
+func NewObjectStorageWithOptions(dir *dotgit.DotGit, objectCache cache.Object, ops Options) *ObjectStorage {
+ return &ObjectStorage{
+ options: ops,
+ objectCache: objectCache,
+ dir: dir,
+ }
+}
+
+func (s *ObjectStorage) requireIndex() error {
+ if s.index != nil {
+ return nil
+ }
+
+ s.index = make(map[plumbing.Hash]idxfile.Index)
+ packs, err := s.dir.ObjectPacks()
+ if err != nil {
+ return err
+ }
+
+ for _, h := range packs {
+ if err := s.loadIdxFile(h); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Reindex indexes again all packfiles. Useful if git changed packfiles externally
+func (s *ObjectStorage) Reindex() {
+ s.index = nil
+}
+
+func (s *ObjectStorage) loadIdxFile(h plumbing.Hash) (err error) {
+ f, err := s.dir.ObjectPackIdx(h)
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+
+ idxf := idxfile.NewMemoryIndex()
+ d := idxfile.NewDecoder(f)
+ if err = d.Decode(idxf); err != nil {
+ return err
+ }
+
+ s.index[h] = idxf
+ return err
+}
+
+func (s *ObjectStorage) NewEncodedObject() plumbing.EncodedObject {
+ return &plumbing.MemoryObject{}
+}
+
+func (s *ObjectStorage) PackfileWriter() (io.WriteCloser, error) {
+ if err := s.requireIndex(); err != nil {
+ return nil, err
+ }
+
+ w, err := s.dir.NewObjectPack()
+ if err != nil {
+ return nil, err
+ }
+
+ w.Notify = func(h plumbing.Hash, writer *idxfile.Writer) {
+ index, err := writer.Index()
+ if err == nil {
+ s.index[h] = index
+ }
+ }
+
+ return w, nil
+}
+
+// SetEncodedObject adds a new object to the storage.
+func (s *ObjectStorage) SetEncodedObject(o plumbing.EncodedObject) (h plumbing.Hash, err error) {
+ if o.Type() == plumbing.OFSDeltaObject || o.Type() == plumbing.REFDeltaObject {
+ return plumbing.ZeroHash, plumbing.ErrInvalidType
+ }
+
+ ow, err := s.dir.NewObject()
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ defer ioutil.CheckClose(ow, &err)
+
+ or, err := o.Reader()
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ defer ioutil.CheckClose(or, &err)
+
+ if err = ow.WriteHeader(o.Type(), o.Size()); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ if _, err = io.Copy(ow, or); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return o.Hash(), err
+}
+
+// LazyWriter returns a lazy ObjectWriter that is bound to a DotGit file.
+// It first write the header passing on the object type and size, so
+// that the object contents can be written later, without the need to
+// create a MemoryObject and buffering its entire contents into memory.
+func (s *ObjectStorage) LazyWriter() (w io.WriteCloser, wh func(typ plumbing.ObjectType, sz int64) error, err error) {
+ ow, err := s.dir.NewObject()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return ow, ow.WriteHeader, nil
+}
+
+// HasEncodedObject returns nil if the object exists, without actually
+// reading the object data from storage.
+func (s *ObjectStorage) HasEncodedObject(h plumbing.Hash) (err error) {
+ // Check unpacked objects
+ f, err := s.dir.Object(h)
+ if err != nil {
+ if !os.IsNotExist(err) {
+ return err
+ }
+ // Fall through to check packed objects.
+ } else {
+ defer ioutil.CheckClose(f, &err)
+ return nil
+ }
+
+ // Check packed objects.
+ if err := s.requireIndex(); err != nil {
+ return err
+ }
+ _, _, offset := s.findObjectInPackfile(h)
+ if offset == -1 {
+ return plumbing.ErrObjectNotFound
+ }
+ return nil
+}
+
+func (s *ObjectStorage) encodedObjectSizeFromUnpacked(h plumbing.Hash) (
+ size int64, err error) {
+ f, err := s.dir.Object(h)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return 0, plumbing.ErrObjectNotFound
+ }
+
+ return 0, err
+ }
+
+ r, err := objfile.NewReader(f)
+ if err != nil {
+ return 0, err
+ }
+ defer ioutil.CheckClose(r, &err)
+
+ _, size, err = r.Header()
+ return size, err
+}
+
+func (s *ObjectStorage) packfile(idx idxfile.Index, pack plumbing.Hash) (*packfile.Packfile, error) {
+ if p := s.packfileFromCache(pack); p != nil {
+ return p, nil
+ }
+
+ f, err := s.dir.ObjectPack(pack)
+ if err != nil {
+ return nil, err
+ }
+
+ var p *packfile.Packfile
+ if s.objectCache != nil {
+ p = packfile.NewPackfileWithCache(idx, s.dir.Fs(), f, s.objectCache, s.options.LargeObjectThreshold)
+ } else {
+ p = packfile.NewPackfile(idx, s.dir.Fs(), f, s.options.LargeObjectThreshold)
+ }
+
+ return p, s.storePackfileInCache(pack, p)
+}
+
+func (s *ObjectStorage) packfileFromCache(hash plumbing.Hash) *packfile.Packfile {
+ if s.packfiles == nil {
+ if s.options.KeepDescriptors {
+ s.packfiles = make(map[plumbing.Hash]*packfile.Packfile)
+ } else if s.options.MaxOpenDescriptors > 0 {
+ s.packList = make([]plumbing.Hash, s.options.MaxOpenDescriptors)
+ s.packfiles = make(map[plumbing.Hash]*packfile.Packfile, s.options.MaxOpenDescriptors)
+ }
+ }
+
+ return s.packfiles[hash]
+}
+
+func (s *ObjectStorage) storePackfileInCache(hash plumbing.Hash, p *packfile.Packfile) error {
+ if s.options.KeepDescriptors {
+ s.packfiles[hash] = p
+ return nil
+ }
+
+ if s.options.MaxOpenDescriptors <= 0 {
+ return nil
+ }
+
+ // start over as the limit of packList is hit
+ if s.packListIdx >= len(s.packList) {
+ s.packListIdx = 0
+ }
+
+ // close the existing packfile if open
+ if next := s.packList[s.packListIdx]; !next.IsZero() {
+ open := s.packfiles[next]
+ delete(s.packfiles, next)
+ if open != nil {
+ if err := open.Close(); err != nil {
+ return err
+ }
+ }
+ }
+
+ // cache newly open packfile
+ s.packList[s.packListIdx] = hash
+ s.packfiles[hash] = p
+ s.packListIdx++
+
+ return nil
+}
+
+func (s *ObjectStorage) encodedObjectSizeFromPackfile(h plumbing.Hash) (
+ size int64, err error) {
+ if err := s.requireIndex(); err != nil {
+ return 0, err
+ }
+
+ pack, _, offset := s.findObjectInPackfile(h)
+ if offset == -1 {
+ return 0, plumbing.ErrObjectNotFound
+ }
+
+ idx := s.index[pack]
+ hash, err := idx.FindHash(offset)
+ if err == nil {
+ obj, ok := s.objectCache.Get(hash)
+ if ok {
+ return obj.Size(), nil
+ }
+ } else if err != nil && err != plumbing.ErrObjectNotFound {
+ return 0, err
+ }
+
+ p, err := s.packfile(idx, pack)
+ if err != nil {
+ return 0, err
+ }
+
+ if !s.options.KeepDescriptors && s.options.MaxOpenDescriptors == 0 {
+ defer ioutil.CheckClose(p, &err)
+ }
+
+ return p.GetSizeByOffset(offset)
+}
+
+// EncodedObjectSize returns the plaintext size of the given object,
+// without actually reading the full object data from storage.
+func (s *ObjectStorage) EncodedObjectSize(h plumbing.Hash) (
+ size int64, err error) {
+ size, err = s.encodedObjectSizeFromUnpacked(h)
+ if err != nil && err != plumbing.ErrObjectNotFound {
+ return 0, err
+ } else if err == nil {
+ return size, nil
+ }
+
+ return s.encodedObjectSizeFromPackfile(h)
+}
+
+// EncodedObject returns the object with the given hash, by searching for it in
+// the packfile and the git object directories.
+func (s *ObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) {
+ var obj plumbing.EncodedObject
+ var err error
+
+ if s.index != nil {
+ obj, err = s.getFromPackfile(h, false)
+ if err == plumbing.ErrObjectNotFound {
+ obj, err = s.getFromUnpacked(h)
+ }
+ } else {
+ obj, err = s.getFromUnpacked(h)
+ if err == plumbing.ErrObjectNotFound {
+ obj, err = s.getFromPackfile(h, false)
+ }
+ }
+
+ // If the error is still object not found, check if it's a shared object
+ // repository.
+ if err == plumbing.ErrObjectNotFound {
+ dotgits, e := s.dir.Alternates()
+ if e == nil {
+ // Create a new object storage with the DotGit(s) and check for the
+ // required hash object. Skip when not found.
+ for _, dg := range dotgits {
+ o := NewObjectStorage(dg, s.objectCache)
+ enobj, enerr := o.EncodedObject(t, h)
+ if enerr != nil {
+ continue
+ }
+ return enobj, nil
+ }
+ }
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if plumbing.AnyObject != t && obj.Type() != t {
+ return nil, plumbing.ErrObjectNotFound
+ }
+
+ return obj, nil
+}
+
+// DeltaObject returns the object with the given hash, by searching for
+// it in the packfile and the git object directories.
+func (s *ObjectStorage) DeltaObject(t plumbing.ObjectType,
+ h plumbing.Hash) (plumbing.EncodedObject, error) {
+ obj, err := s.getFromUnpacked(h)
+ if err == plumbing.ErrObjectNotFound {
+ obj, err = s.getFromPackfile(h, true)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if plumbing.AnyObject != t && obj.Type() != t {
+ return nil, plumbing.ErrObjectNotFound
+ }
+
+ return obj, nil
+}
+
+func (s *ObjectStorage) getFromUnpacked(h plumbing.Hash) (obj plumbing.EncodedObject, err error) {
+ f, err := s.dir.Object(h)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil, plumbing.ErrObjectNotFound
+ }
+
+ return nil, err
+ }
+ defer ioutil.CheckClose(f, &err)
+
+ if cacheObj, found := s.objectCache.Get(h); found {
+ return cacheObj, nil
+ }
+
+ r, err := objfile.NewReader(f)
+ if err != nil {
+ return nil, err
+ }
+
+ defer ioutil.CheckClose(r, &err)
+
+ t, size, err := r.Header()
+ if err != nil {
+ return nil, err
+ }
+
+ if s.options.LargeObjectThreshold > 0 && size > s.options.LargeObjectThreshold {
+ obj = dotgit.NewEncodedObject(s.dir, h, t, size)
+ return obj, nil
+ }
+
+ obj = s.NewEncodedObject()
+
+ obj.SetType(t)
+ obj.SetSize(size)
+ w, err := obj.Writer()
+ if err != nil {
+ return nil, err
+ }
+
+ defer ioutil.CheckClose(w, &err)
+
+ s.objectCache.Put(obj)
+
+ bufp := copyBufferPool.Get().(*[]byte)
+ buf := *bufp
+ _, err = io.CopyBuffer(w, r, buf)
+ copyBufferPool.Put(bufp)
+
+ return obj, err
+}
+
+var copyBufferPool = sync.Pool{
+ New: func() interface{} {
+ b := make([]byte, 32*1024)
+ return &b
+ },
+}
+
+// Get returns the object with the given hash, by searching for it in
+// the packfile.
+func (s *ObjectStorage) getFromPackfile(h plumbing.Hash, canBeDelta bool) (
+ plumbing.EncodedObject, error) {
+
+ if err := s.requireIndex(); err != nil {
+ return nil, err
+ }
+
+ pack, hash, offset := s.findObjectInPackfile(h)
+ if offset == -1 {
+ return nil, plumbing.ErrObjectNotFound
+ }
+
+ idx := s.index[pack]
+ p, err := s.packfile(idx, pack)
+ if err != nil {
+ return nil, err
+ }
+
+ if !s.options.KeepDescriptors && s.options.MaxOpenDescriptors == 0 {
+ defer ioutil.CheckClose(p, &err)
+ }
+
+ if canBeDelta {
+ return s.decodeDeltaObjectAt(p, offset, hash)
+ }
+
+ return s.decodeObjectAt(p, offset)
+}
+
+func (s *ObjectStorage) decodeObjectAt(
+ p *packfile.Packfile,
+ offset int64,
+) (plumbing.EncodedObject, error) {
+ hash, err := p.FindHash(offset)
+ if err == nil {
+ obj, ok := s.objectCache.Get(hash)
+ if ok {
+ return obj, nil
+ }
+ }
+
+ if err != nil && err != plumbing.ErrObjectNotFound {
+ return nil, err
+ }
+
+ return p.GetByOffset(offset)
+}
+
+func (s *ObjectStorage) decodeDeltaObjectAt(
+ p *packfile.Packfile,
+ offset int64,
+ hash plumbing.Hash,
+) (plumbing.EncodedObject, error) {
+ scan := p.Scanner()
+ header, err := scan.SeekObjectHeader(offset)
+ if err != nil {
+ return nil, err
+ }
+
+ var (
+ base plumbing.Hash
+ )
+
+ switch header.Type {
+ case plumbing.REFDeltaObject:
+ base = header.Reference
+ case plumbing.OFSDeltaObject:
+ base, err = p.FindHash(header.OffsetReference)
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return s.decodeObjectAt(p, offset)
+ }
+
+ obj := &plumbing.MemoryObject{}
+ obj.SetType(header.Type)
+ w, err := obj.Writer()
+ if err != nil {
+ return nil, err
+ }
+
+ if _, _, err := scan.NextObject(w); err != nil {
+ return nil, err
+ }
+
+ return newDeltaObject(obj, hash, base, header.Length), nil
+}
+
+func (s *ObjectStorage) findObjectInPackfile(h plumbing.Hash) (plumbing.Hash, plumbing.Hash, int64) {
+ for packfile, index := range s.index {
+ offset, err := index.FindOffset(h)
+ if err == nil {
+ return packfile, h, offset
+ }
+ }
+
+ return plumbing.ZeroHash, plumbing.ZeroHash, -1
+}
+
+// HashesWithPrefix returns all objects with a hash that starts with a prefix by searching for
+// them in the packfile and the git object directories.
+func (s *ObjectStorage) HashesWithPrefix(prefix []byte) ([]plumbing.Hash, error) {
+ hashes, err := s.dir.ObjectsWithPrefix(prefix)
+ if err != nil {
+ return nil, err
+ }
+
+ seen := hashListAsMap(hashes)
+
+ // TODO: This could be faster with some idxfile changes,
+ // or diving into the packfile.
+ if err := s.requireIndex(); err != nil {
+ return nil, err
+ }
+ for _, index := range s.index {
+ ei, err := index.Entries()
+ if err != nil {
+ return nil, err
+ }
+ for {
+ e, err := ei.Next()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return nil, err
+ }
+ if bytes.HasPrefix(e.Hash[:], prefix) {
+ if _, ok := seen[e.Hash]; ok {
+ continue
+ }
+ hashes = append(hashes, e.Hash)
+ }
+ }
+ ei.Close()
+ }
+
+ return hashes, nil
+}
+
+// IterEncodedObjects returns an iterator for all the objects in the packfile
+// with the given type.
+func (s *ObjectStorage) IterEncodedObjects(t plumbing.ObjectType) (storer.EncodedObjectIter, error) {
+ objects, err := s.dir.Objects()
+ if err != nil {
+ return nil, err
+ }
+
+ seen := make(map[plumbing.Hash]struct{})
+ var iters []storer.EncodedObjectIter
+ if len(objects) != 0 {
+ iters = append(iters, &objectsIter{s: s, t: t, h: objects})
+ seen = hashListAsMap(objects)
+ }
+
+ packi, err := s.buildPackfileIters(t, seen)
+ if err != nil {
+ return nil, err
+ }
+
+ iters = append(iters, packi)
+ return storer.NewMultiEncodedObjectIter(iters), nil
+}
+
+func (s *ObjectStorage) buildPackfileIters(
+ t plumbing.ObjectType,
+ seen map[plumbing.Hash]struct{},
+) (storer.EncodedObjectIter, error) {
+ if err := s.requireIndex(); err != nil {
+ return nil, err
+ }
+
+ packs, err := s.dir.ObjectPacks()
+ if err != nil {
+ return nil, err
+ }
+ return &lazyPackfilesIter{
+ hashes: packs,
+ open: func(h plumbing.Hash) (storer.EncodedObjectIter, error) {
+ pack, err := s.dir.ObjectPack(h)
+ if err != nil {
+ return nil, err
+ }
+ return newPackfileIter(
+ s.dir.Fs(), pack, t, seen, s.index[h],
+ s.objectCache, s.options.KeepDescriptors,
+ s.options.LargeObjectThreshold,
+ )
+ },
+ }, nil
+}
+
+// Close closes all opened files.
+func (s *ObjectStorage) Close() error {
+ var firstError error
+ if s.options.KeepDescriptors || s.options.MaxOpenDescriptors > 0 {
+ for _, packfile := range s.packfiles {
+ err := packfile.Close()
+ if firstError == nil && err != nil {
+ firstError = err
+ }
+ }
+ }
+
+ s.packfiles = nil
+ s.dir.Close()
+
+ return firstError
+}
+
+type lazyPackfilesIter struct {
+ hashes []plumbing.Hash
+ open func(h plumbing.Hash) (storer.EncodedObjectIter, error)
+ cur storer.EncodedObjectIter
+}
+
+func (it *lazyPackfilesIter) Next() (plumbing.EncodedObject, error) {
+ for {
+ if it.cur == nil {
+ if len(it.hashes) == 0 {
+ return nil, io.EOF
+ }
+ h := it.hashes[0]
+ it.hashes = it.hashes[1:]
+
+ sub, err := it.open(h)
+ if err == io.EOF {
+ continue
+ } else if err != nil {
+ return nil, err
+ }
+ it.cur = sub
+ }
+ ob, err := it.cur.Next()
+ if err == io.EOF {
+ it.cur.Close()
+ it.cur = nil
+ continue
+ } else if err != nil {
+ return nil, err
+ }
+ return ob, nil
+ }
+}
+
+func (it *lazyPackfilesIter) ForEach(cb func(plumbing.EncodedObject) error) error {
+ return storer.ForEachIterator(it, cb)
+}
+
+func (it *lazyPackfilesIter) Close() {
+ if it.cur != nil {
+ it.cur.Close()
+ it.cur = nil
+ }
+ it.hashes = nil
+}
+
+type packfileIter struct {
+ pack billy.File
+ iter storer.EncodedObjectIter
+ seen map[plumbing.Hash]struct{}
+
+ // tells whether the pack file should be left open after iteration or not
+ keepPack bool
+}
+
+// NewPackfileIter returns a new EncodedObjectIter for the provided packfile
+// and object type. Packfile and index file will be closed after they're
+// used. If keepPack is true the packfile won't be closed after the iteration
+// finished.
+func NewPackfileIter(
+ fs billy.Filesystem,
+ f billy.File,
+ idxFile billy.File,
+ t plumbing.ObjectType,
+ keepPack bool,
+ largeObjectThreshold int64,
+) (storer.EncodedObjectIter, error) {
+ idx := idxfile.NewMemoryIndex()
+ if err := idxfile.NewDecoder(idxFile).Decode(idx); err != nil {
+ return nil, err
+ }
+
+ if err := idxFile.Close(); err != nil {
+ return nil, err
+ }
+
+ seen := make(map[plumbing.Hash]struct{})
+ return newPackfileIter(fs, f, t, seen, idx, nil, keepPack, largeObjectThreshold)
+}
+
+func newPackfileIter(
+ fs billy.Filesystem,
+ f billy.File,
+ t plumbing.ObjectType,
+ seen map[plumbing.Hash]struct{},
+ index idxfile.Index,
+ cache cache.Object,
+ keepPack bool,
+ largeObjectThreshold int64,
+) (storer.EncodedObjectIter, error) {
+ var p *packfile.Packfile
+ if cache != nil {
+ p = packfile.NewPackfileWithCache(index, fs, f, cache, largeObjectThreshold)
+ } else {
+ p = packfile.NewPackfile(index, fs, f, largeObjectThreshold)
+ }
+
+ iter, err := p.GetByType(t)
+ if err != nil {
+ return nil, err
+ }
+
+ return &packfileIter{
+ pack: f,
+ iter: iter,
+ seen: seen,
+ keepPack: keepPack,
+ }, nil
+}
+
+func (iter *packfileIter) Next() (plumbing.EncodedObject, error) {
+ for {
+ obj, err := iter.iter.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ if _, ok := iter.seen[obj.Hash()]; ok {
+ continue
+ }
+
+ return obj, nil
+ }
+}
+
+func (iter *packfileIter) ForEach(cb func(plumbing.EncodedObject) error) error {
+ for {
+ o, err := iter.Next()
+ if err != nil {
+ if err == io.EOF {
+ iter.Close()
+ return nil
+ }
+ return err
+ }
+
+ if err := cb(o); err != nil {
+ return err
+ }
+ }
+}
+
+func (iter *packfileIter) Close() {
+ iter.iter.Close()
+ if !iter.keepPack {
+ _ = iter.pack.Close()
+ }
+}
+
+type objectsIter struct {
+ s *ObjectStorage
+ t plumbing.ObjectType
+ h []plumbing.Hash
+}
+
+func (iter *objectsIter) Next() (plumbing.EncodedObject, error) {
+ if len(iter.h) == 0 {
+ return nil, io.EOF
+ }
+
+ obj, err := iter.s.getFromUnpacked(iter.h[0])
+ iter.h = iter.h[1:]
+
+ if err != nil {
+ return nil, err
+ }
+
+ if iter.t != plumbing.AnyObject && iter.t != obj.Type() {
+ return iter.Next()
+ }
+
+ return obj, err
+}
+
+func (iter *objectsIter) ForEach(cb func(plumbing.EncodedObject) error) error {
+ for {
+ o, err := iter.Next()
+ if err != nil {
+ if err == io.EOF {
+ return nil
+ }
+ return err
+ }
+
+ if err := cb(o); err != nil {
+ return err
+ }
+ }
+}
+
+func (iter *objectsIter) Close() {
+ iter.h = []plumbing.Hash{}
+}
+
+func hashListAsMap(l []plumbing.Hash) map[plumbing.Hash]struct{} {
+ m := make(map[plumbing.Hash]struct{}, len(l))
+ for _, h := range l {
+ m[h] = struct{}{}
+ }
+ return m
+}
+
+func (s *ObjectStorage) ForEachObjectHash(fun func(plumbing.Hash) error) error {
+ err := s.dir.ForEachObjectHash(fun)
+ if err == storer.ErrStop {
+ return nil
+ }
+ return err
+}
+
+func (s *ObjectStorage) LooseObjectTime(hash plumbing.Hash) (time.Time, error) {
+ fi, err := s.dir.ObjectStat(hash)
+ if err != nil {
+ return time.Time{}, err
+ }
+ return fi.ModTime(), nil
+}
+
+func (s *ObjectStorage) DeleteLooseObject(hash plumbing.Hash) error {
+ return s.dir.ObjectDelete(hash)
+}
+
+func (s *ObjectStorage) ObjectPacks() ([]plumbing.Hash, error) {
+ return s.dir.ObjectPacks()
+}
+
+func (s *ObjectStorage) DeleteOldObjectPackAndIndex(h plumbing.Hash, t time.Time) error {
+ return s.dir.DeleteOldObjectPackAndIndex(h, t)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/reference.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/reference.go
new file mode 100644
index 00000000..aabcd730
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/reference.go
@@ -0,0 +1,44 @@
+package filesystem
+
+import (
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/storage/filesystem/dotgit"
+)
+
+type ReferenceStorage struct {
+ dir *dotgit.DotGit
+}
+
+func (r *ReferenceStorage) SetReference(ref *plumbing.Reference) error {
+ return r.dir.SetRef(ref, nil)
+}
+
+func (r *ReferenceStorage) CheckAndSetReference(ref, old *plumbing.Reference) error {
+ return r.dir.SetRef(ref, old)
+}
+
+func (r *ReferenceStorage) Reference(n plumbing.ReferenceName) (*plumbing.Reference, error) {
+ return r.dir.Ref(n)
+}
+
+func (r *ReferenceStorage) IterReferences() (storer.ReferenceIter, error) {
+ refs, err := r.dir.Refs()
+ if err != nil {
+ return nil, err
+ }
+
+ return storer.NewReferenceSliceIter(refs), nil
+}
+
+func (r *ReferenceStorage) RemoveReference(n plumbing.ReferenceName) error {
+ return r.dir.RemoveRef(n)
+}
+
+func (r *ReferenceStorage) CountLooseRefs() (int, error) {
+ return r.dir.CountLooseRefs()
+}
+
+func (r *ReferenceStorage) PackRefs() error {
+ return r.dir.PackRefs()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/shallow.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/shallow.go
new file mode 100644
index 00000000..ac48fdfb
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/shallow.go
@@ -0,0 +1,54 @@
+package filesystem
+
+import (
+ "bufio"
+ "fmt"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/storage/filesystem/dotgit"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+)
+
+// ShallowStorage where the shallow commits are stored, an internal to
+// manipulate the shallow file
+type ShallowStorage struct {
+ dir *dotgit.DotGit
+}
+
+// SetShallow save the shallows in the shallow file in the .git folder as one
+// commit per line represented by 40-byte hexadecimal object terminated by a
+// newline.
+func (s *ShallowStorage) SetShallow(commits []plumbing.Hash) error {
+ f, err := s.dir.ShallowWriter()
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+ for _, h := range commits {
+ if _, err := fmt.Fprintf(f, "%s\n", h); err != nil {
+ return err
+ }
+ }
+
+ return err
+}
+
+// Shallow returns the shallow commits reading from shallo file from .git
+func (s *ShallowStorage) Shallow() ([]plumbing.Hash, error) {
+ f, err := s.dir.Shallow()
+ if f == nil || err != nil {
+ return nil, err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+
+ var hash []plumbing.Hash
+
+ scn := bufio.NewScanner(f)
+ for scn.Scan() {
+ hash = append(hash, plumbing.NewHash(scn.Text()))
+ }
+
+ return hash, scn.Err()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go
new file mode 100644
index 00000000..951ea00c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go
@@ -0,0 +1,85 @@
+// Package filesystem is a storage backend base on filesystems
+package filesystem
+
+import (
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ "github.com/go-git/go-git/v5/storage/filesystem/dotgit"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+// Storage is an implementation of git.Storer that stores data on disk in the
+// standard git format (this is, the .git directory). Zero values of this type
+// are not safe to use, see the NewStorage function below.
+type Storage struct {
+ fs billy.Filesystem
+ dir *dotgit.DotGit
+
+ ObjectStorage
+ ReferenceStorage
+ IndexStorage
+ ShallowStorage
+ ConfigStorage
+ ModuleStorage
+}
+
+// Options holds configuration for the storage.
+type Options struct {
+ // ExclusiveAccess means that the filesystem is not modified externally
+ // while the repo is open.
+ ExclusiveAccess bool
+ // KeepDescriptors makes the file descriptors to be reused but they will
+ // need to be manually closed calling Close().
+ KeepDescriptors bool
+ // MaxOpenDescriptors is the max number of file descriptors to keep
+ // open. If KeepDescriptors is true, all file descriptors will remain open.
+ MaxOpenDescriptors int
+ // LargeObjectThreshold maximum object size (in bytes) that will be read in to memory.
+ // If left unset or set to 0 there is no limit
+ LargeObjectThreshold int64
+ // AlternatesFS provides the billy filesystem to be used for Git Alternates.
+ // If none is provided, it falls back to using the underlying instance used for
+ // DotGit.
+ AlternatesFS billy.Filesystem
+}
+
+// NewStorage returns a new Storage backed by a given `fs.Filesystem` and cache.
+func NewStorage(fs billy.Filesystem, cache cache.Object) *Storage {
+ return NewStorageWithOptions(fs, cache, Options{})
+}
+
+// NewStorageWithOptions returns a new Storage with extra options,
+// backed by a given `fs.Filesystem` and cache.
+func NewStorageWithOptions(fs billy.Filesystem, cache cache.Object, ops Options) *Storage {
+ dirOps := dotgit.Options{
+ ExclusiveAccess: ops.ExclusiveAccess,
+ AlternatesFS: ops.AlternatesFS,
+ }
+ dir := dotgit.NewWithOptions(fs, dirOps)
+
+ return &Storage{
+ fs: fs,
+ dir: dir,
+
+ ObjectStorage: *NewObjectStorageWithOptions(dir, cache, ops),
+ ReferenceStorage: ReferenceStorage{dir: dir},
+ IndexStorage: IndexStorage{dir: dir},
+ ShallowStorage: ShallowStorage{dir: dir},
+ ConfigStorage: ConfigStorage{dir: dir},
+ ModuleStorage: ModuleStorage{dir: dir},
+ }
+}
+
+// Filesystem returns the underlying filesystem
+func (s *Storage) Filesystem() billy.Filesystem {
+ return s.fs
+}
+
+// Init initializes .git directory
+func (s *Storage) Init() error {
+ return s.dir.Initialize()
+}
+
+func (s *Storage) AddAlternate(remote string) error {
+ return s.dir.AddAlternate(remote)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/memory/storage.go b/vendor/github.com/go-git/go-git/v5/storage/memory/storage.go
new file mode 100644
index 00000000..79211c7c
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/memory/storage.go
@@ -0,0 +1,324 @@
+// Package memory is a storage backend base on memory
+package memory
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/go-git/go-git/v5/config"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/storage"
+)
+
+var ErrUnsupportedObjectType = fmt.Errorf("unsupported object type")
+
+// Storage is an implementation of git.Storer that stores data on memory, being
+// ephemeral. The use of this storage should be done in controlled environments,
+// since the representation in memory of some repository can fill the machine
+// memory. in the other hand this storage has the best performance.
+type Storage struct {
+ ConfigStorage
+ ObjectStorage
+ ShallowStorage
+ IndexStorage
+ ReferenceStorage
+ ModuleStorage
+}
+
+// NewStorage returns a new Storage base on memory
+func NewStorage() *Storage {
+ return &Storage{
+ ReferenceStorage: make(ReferenceStorage),
+ ConfigStorage: ConfigStorage{},
+ ShallowStorage: ShallowStorage{},
+ ObjectStorage: ObjectStorage{
+ Objects: make(map[plumbing.Hash]plumbing.EncodedObject),
+ Commits: make(map[plumbing.Hash]plumbing.EncodedObject),
+ Trees: make(map[plumbing.Hash]plumbing.EncodedObject),
+ Blobs: make(map[plumbing.Hash]plumbing.EncodedObject),
+ Tags: make(map[plumbing.Hash]plumbing.EncodedObject),
+ },
+ ModuleStorage: make(ModuleStorage),
+ }
+}
+
+type ConfigStorage struct {
+ config *config.Config
+}
+
+func (c *ConfigStorage) SetConfig(cfg *config.Config) error {
+ if err := cfg.Validate(); err != nil {
+ return err
+ }
+
+ c.config = cfg
+ return nil
+}
+
+func (c *ConfigStorage) Config() (*config.Config, error) {
+ if c.config == nil {
+ c.config = config.NewConfig()
+ }
+
+ return c.config, nil
+}
+
+type IndexStorage struct {
+ index *index.Index
+}
+
+func (c *IndexStorage) SetIndex(idx *index.Index) error {
+ c.index = idx
+ return nil
+}
+
+func (c *IndexStorage) Index() (*index.Index, error) {
+ if c.index == nil {
+ c.index = &index.Index{Version: 2}
+ }
+
+ return c.index, nil
+}
+
+type ObjectStorage struct {
+ Objects map[plumbing.Hash]plumbing.EncodedObject
+ Commits map[plumbing.Hash]plumbing.EncodedObject
+ Trees map[plumbing.Hash]plumbing.EncodedObject
+ Blobs map[plumbing.Hash]plumbing.EncodedObject
+ Tags map[plumbing.Hash]plumbing.EncodedObject
+}
+
+func (o *ObjectStorage) NewEncodedObject() plumbing.EncodedObject {
+ return &plumbing.MemoryObject{}
+}
+
+func (o *ObjectStorage) SetEncodedObject(obj plumbing.EncodedObject) (plumbing.Hash, error) {
+ h := obj.Hash()
+ o.Objects[h] = obj
+
+ switch obj.Type() {
+ case plumbing.CommitObject:
+ o.Commits[h] = o.Objects[h]
+ case plumbing.TreeObject:
+ o.Trees[h] = o.Objects[h]
+ case plumbing.BlobObject:
+ o.Blobs[h] = o.Objects[h]
+ case plumbing.TagObject:
+ o.Tags[h] = o.Objects[h]
+ default:
+ return h, ErrUnsupportedObjectType
+ }
+
+ return h, nil
+}
+
+func (o *ObjectStorage) HasEncodedObject(h plumbing.Hash) (err error) {
+ if _, ok := o.Objects[h]; !ok {
+ return plumbing.ErrObjectNotFound
+ }
+ return nil
+}
+
+func (o *ObjectStorage) EncodedObjectSize(h plumbing.Hash) (
+ size int64, err error) {
+ obj, ok := o.Objects[h]
+ if !ok {
+ return 0, plumbing.ErrObjectNotFound
+ }
+
+ return obj.Size(), nil
+}
+
+func (o *ObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) {
+ obj, ok := o.Objects[h]
+ if !ok || (plumbing.AnyObject != t && obj.Type() != t) {
+ return nil, plumbing.ErrObjectNotFound
+ }
+
+ return obj, nil
+}
+
+func (o *ObjectStorage) IterEncodedObjects(t plumbing.ObjectType) (storer.EncodedObjectIter, error) {
+ var series []plumbing.EncodedObject
+ switch t {
+ case plumbing.AnyObject:
+ series = flattenObjectMap(o.Objects)
+ case plumbing.CommitObject:
+ series = flattenObjectMap(o.Commits)
+ case plumbing.TreeObject:
+ series = flattenObjectMap(o.Trees)
+ case plumbing.BlobObject:
+ series = flattenObjectMap(o.Blobs)
+ case plumbing.TagObject:
+ series = flattenObjectMap(o.Tags)
+ }
+
+ return storer.NewEncodedObjectSliceIter(series), nil
+}
+
+func flattenObjectMap(m map[plumbing.Hash]plumbing.EncodedObject) []plumbing.EncodedObject {
+ objects := make([]plumbing.EncodedObject, 0, len(m))
+ for _, obj := range m {
+ objects = append(objects, obj)
+ }
+ return objects
+}
+
+func (o *ObjectStorage) Begin() storer.Transaction {
+ return &TxObjectStorage{
+ Storage: o,
+ Objects: make(map[plumbing.Hash]plumbing.EncodedObject),
+ }
+}
+
+func (o *ObjectStorage) ForEachObjectHash(fun func(plumbing.Hash) error) error {
+ for h := range o.Objects {
+ err := fun(h)
+ if err != nil {
+ if err == storer.ErrStop {
+ return nil
+ }
+ return err
+ }
+ }
+ return nil
+}
+
+func (o *ObjectStorage) ObjectPacks() ([]plumbing.Hash, error) {
+ return nil, nil
+}
+func (o *ObjectStorage) DeleteOldObjectPackAndIndex(plumbing.Hash, time.Time) error {
+ return nil
+}
+
+var errNotSupported = fmt.Errorf("not supported")
+
+func (o *ObjectStorage) LooseObjectTime(hash plumbing.Hash) (time.Time, error) {
+ return time.Time{}, errNotSupported
+}
+func (o *ObjectStorage) DeleteLooseObject(plumbing.Hash) error {
+ return errNotSupported
+}
+
+func (o *ObjectStorage) AddAlternate(remote string) error {
+ return errNotSupported
+}
+
+type TxObjectStorage struct {
+ Storage *ObjectStorage
+ Objects map[plumbing.Hash]plumbing.EncodedObject
+}
+
+func (tx *TxObjectStorage) SetEncodedObject(obj plumbing.EncodedObject) (plumbing.Hash, error) {
+ h := obj.Hash()
+ tx.Objects[h] = obj
+
+ return h, nil
+}
+
+func (tx *TxObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) {
+ obj, ok := tx.Objects[h]
+ if !ok || (plumbing.AnyObject != t && obj.Type() != t) {
+ return nil, plumbing.ErrObjectNotFound
+ }
+
+ return obj, nil
+}
+
+func (tx *TxObjectStorage) Commit() error {
+ for h, obj := range tx.Objects {
+ delete(tx.Objects, h)
+ if _, err := tx.Storage.SetEncodedObject(obj); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (tx *TxObjectStorage) Rollback() error {
+ tx.Objects = make(map[plumbing.Hash]plumbing.EncodedObject)
+ return nil
+}
+
+type ReferenceStorage map[plumbing.ReferenceName]*plumbing.Reference
+
+func (r ReferenceStorage) SetReference(ref *plumbing.Reference) error {
+ if ref != nil {
+ r[ref.Name()] = ref
+ }
+
+ return nil
+}
+
+func (r ReferenceStorage) CheckAndSetReference(ref, old *plumbing.Reference) error {
+ if ref == nil {
+ return nil
+ }
+
+ if old != nil {
+ tmp := r[ref.Name()]
+ if tmp != nil && tmp.Hash() != old.Hash() {
+ return storage.ErrReferenceHasChanged
+ }
+ }
+ r[ref.Name()] = ref
+ return nil
+}
+
+func (r ReferenceStorage) Reference(n plumbing.ReferenceName) (*plumbing.Reference, error) {
+ ref, ok := r[n]
+ if !ok {
+ return nil, plumbing.ErrReferenceNotFound
+ }
+
+ return ref, nil
+}
+
+func (r ReferenceStorage) IterReferences() (storer.ReferenceIter, error) {
+ var refs []*plumbing.Reference
+ for _, ref := range r {
+ refs = append(refs, ref)
+ }
+
+ return storer.NewReferenceSliceIter(refs), nil
+}
+
+func (r ReferenceStorage) CountLooseRefs() (int, error) {
+ return len(r), nil
+}
+
+func (r ReferenceStorage) PackRefs() error {
+ return nil
+}
+
+func (r ReferenceStorage) RemoveReference(n plumbing.ReferenceName) error {
+ delete(r, n)
+ return nil
+}
+
+type ShallowStorage []plumbing.Hash
+
+func (s *ShallowStorage) SetShallow(commits []plumbing.Hash) error {
+ *s = commits
+ return nil
+}
+
+func (s ShallowStorage) Shallow() ([]plumbing.Hash, error) {
+ return s, nil
+}
+
+type ModuleStorage map[string]*Storage
+
+func (s ModuleStorage) Module(name string) (storage.Storer, error) {
+ if m, ok := s[name]; ok {
+ return m, nil
+ }
+
+ m := NewStorage()
+ s[name] = m
+
+ return m, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/storage/storer.go b/vendor/github.com/go-git/go-git/v5/storage/storer.go
new file mode 100644
index 00000000..4800ac7b
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/storage/storer.go
@@ -0,0 +1,30 @@
+package storage
+
+import (
+ "errors"
+
+ "github.com/go-git/go-git/v5/config"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+)
+
+var ErrReferenceHasChanged = errors.New("reference has changed concurrently")
+
+// Storer is a generic storage of objects, references and any information
+// related to a particular repository. The package github.com/go-git/go-git/v5/storage
+// contains two implementation a filesystem base implementation (such as `.git`)
+// and a memory implementations being ephemeral
+type Storer interface {
+ storer.EncodedObjectStorer
+ storer.ReferenceStorer
+ storer.ShallowStorer
+ storer.IndexStorer
+ config.ConfigStorer
+ ModuleStorer
+}
+
+// ModuleStorer allows interact with the modules' Storers
+type ModuleStorer interface {
+ // Module returns a Storer representing a submodule, if not exists returns a
+ // new empty Storer is returned
+ Module(name string) (Storer, error)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/submodule.go b/vendor/github.com/go-git/go-git/v5/submodule.go
new file mode 100644
index 00000000..84f020dc
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/submodule.go
@@ -0,0 +1,398 @@
+package git
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "path"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-git/v5/config"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+ "github.com/go-git/go-git/v5/plumbing/transport"
+)
+
+var (
+ ErrSubmoduleAlreadyInitialized = errors.New("submodule already initialized")
+ ErrSubmoduleNotInitialized = errors.New("submodule not initialized")
+)
+
+// Submodule a submodule allows you to keep another Git repository in a
+// subdirectory of your repository.
+type Submodule struct {
+ // initialized defines if a submodule was already initialized.
+ initialized bool
+
+ c *config.Submodule
+ w *Worktree
+}
+
+// Config returns the submodule config
+func (s *Submodule) Config() *config.Submodule {
+ return s.c
+}
+
+// Init initialize the submodule reading the recorded Entry in the index for
+// the given submodule
+func (s *Submodule) Init() error {
+ cfg, err := s.w.r.Config()
+ if err != nil {
+ return err
+ }
+
+ _, ok := cfg.Submodules[s.c.Name]
+ if ok {
+ return ErrSubmoduleAlreadyInitialized
+ }
+
+ s.initialized = true
+
+ cfg.Submodules[s.c.Name] = s.c
+ return s.w.r.Storer.SetConfig(cfg)
+}
+
+// Status returns the status of the submodule.
+func (s *Submodule) Status() (*SubmoduleStatus, error) {
+ idx, err := s.w.r.Storer.Index()
+ if err != nil {
+ return nil, err
+ }
+
+ return s.status(idx)
+}
+
+func (s *Submodule) status(idx *index.Index) (*SubmoduleStatus, error) {
+ status := &SubmoduleStatus{
+ Path: s.c.Path,
+ }
+
+ e, err := idx.Entry(s.c.Path)
+ if err != nil && err != index.ErrEntryNotFound {
+ return nil, err
+ }
+
+ if e != nil {
+ status.Expected = e.Hash
+ }
+
+ if !s.initialized {
+ return status, nil
+ }
+
+ r, err := s.Repository()
+ if err != nil {
+ return nil, err
+ }
+
+ head, err := r.Head()
+ if err == nil {
+ status.Current = head.Hash()
+ }
+
+ if err != nil && err == plumbing.ErrReferenceNotFound {
+ err = nil
+ }
+
+ return status, err
+}
+
+// Repository returns the Repository represented by this submodule
+func (s *Submodule) Repository() (*Repository, error) {
+ if !s.initialized {
+ return nil, ErrSubmoduleNotInitialized
+ }
+
+ storer, err := s.w.r.Storer.Module(s.c.Name)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = storer.Reference(plumbing.HEAD)
+ if err != nil && err != plumbing.ErrReferenceNotFound {
+ return nil, err
+ }
+
+ var exists bool
+ if err == nil {
+ exists = true
+ }
+
+ var worktree billy.Filesystem
+ if worktree, err = s.w.Filesystem.Chroot(s.c.Path); err != nil {
+ return nil, err
+ }
+
+ if exists {
+ return Open(storer, worktree)
+ }
+
+ r, err := Init(storer, worktree)
+ if err != nil {
+ return nil, err
+ }
+
+ moduleEndpoint, err := transport.NewEndpoint(s.c.URL)
+ if err != nil {
+ return nil, err
+ }
+
+ if !path.IsAbs(moduleEndpoint.Path) && moduleEndpoint.Protocol == "file" {
+ remotes, err := s.w.r.Remotes()
+ if err != nil {
+ return nil, err
+ }
+
+ rootEndpoint, err := transport.NewEndpoint(remotes[0].c.URLs[0])
+ if err != nil {
+ return nil, err
+ }
+
+ rootEndpoint.Path = path.Join(rootEndpoint.Path, moduleEndpoint.Path)
+ *moduleEndpoint = *rootEndpoint
+ }
+
+ _, err = r.CreateRemote(&config.RemoteConfig{
+ Name: DefaultRemoteName,
+ URLs: []string{moduleEndpoint.String()},
+ })
+
+ return r, err
+}
+
+// Update the registered submodule to match what the superproject expects, the
+// submodule should be initialized first calling the Init method or setting in
+// the options SubmoduleUpdateOptions.Init equals true
+func (s *Submodule) Update(o *SubmoduleUpdateOptions) error {
+ return s.UpdateContext(context.Background(), o)
+}
+
+// UpdateContext the registered submodule to match what the superproject
+// expects, the submodule should be initialized first calling the Init method or
+// setting in the options SubmoduleUpdateOptions.Init equals true.
+//
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects the
+// transport operations.
+func (s *Submodule) UpdateContext(ctx context.Context, o *SubmoduleUpdateOptions) error {
+ return s.update(ctx, o, plumbing.ZeroHash)
+}
+
+func (s *Submodule) update(ctx context.Context, o *SubmoduleUpdateOptions, forceHash plumbing.Hash) error {
+ if !s.initialized && !o.Init {
+ return ErrSubmoduleNotInitialized
+ }
+
+ if !s.initialized && o.Init {
+ if err := s.Init(); err != nil {
+ return err
+ }
+ }
+
+ idx, err := s.w.r.Storer.Index()
+ if err != nil {
+ return err
+ }
+
+ hash := forceHash
+ if hash.IsZero() {
+ e, err := idx.Entry(s.c.Path)
+ if err != nil {
+ return err
+ }
+
+ hash = e.Hash
+ }
+
+ r, err := s.Repository()
+ if err != nil {
+ return err
+ }
+
+ if err := s.fetchAndCheckout(ctx, r, o, hash); err != nil {
+ return err
+ }
+
+ return s.doRecursiveUpdate(r, o)
+}
+
+func (s *Submodule) doRecursiveUpdate(r *Repository, o *SubmoduleUpdateOptions) error {
+ if o.RecurseSubmodules == NoRecurseSubmodules {
+ return nil
+ }
+
+ w, err := r.Worktree()
+ if err != nil {
+ return err
+ }
+
+ l, err := w.Submodules()
+ if err != nil {
+ return err
+ }
+
+ new := &SubmoduleUpdateOptions{}
+ *new = *o
+
+ new.RecurseSubmodules--
+ return l.Update(new)
+}
+
+func (s *Submodule) fetchAndCheckout(
+ ctx context.Context, r *Repository, o *SubmoduleUpdateOptions, hash plumbing.Hash,
+) error {
+ if !o.NoFetch {
+ err := r.FetchContext(ctx, &FetchOptions{Auth: o.Auth, Depth: o.Depth})
+ if err != nil && err != NoErrAlreadyUpToDate {
+ return err
+ }
+ }
+
+ w, err := r.Worktree()
+ if err != nil {
+ return err
+ }
+
+ // Handle a case when submodule refers to an orphaned commit that's still reachable
+ // through Git server using a special protocol capability[1].
+ //
+ // [1]: https://git-scm.com/docs/protocol-capabilities#_allow_reachable_sha1_in_want
+ if !o.NoFetch {
+ if _, err := w.r.Object(plumbing.AnyObject, hash); err != nil {
+ refSpec := config.RefSpec("+" + hash.String() + ":" + hash.String())
+
+ err := r.FetchContext(ctx, &FetchOptions{
+ Auth: o.Auth,
+ RefSpecs: []config.RefSpec{refSpec},
+ Depth: o.Depth,
+ })
+ if err != nil && err != NoErrAlreadyUpToDate && err != ErrExactSHA1NotSupported {
+ return err
+ }
+ }
+ }
+
+ if err := w.Checkout(&CheckoutOptions{Hash: hash}); err != nil {
+ return err
+ }
+
+ head := plumbing.NewHashReference(plumbing.HEAD, hash)
+ return r.Storer.SetReference(head)
+}
+
+// Submodules list of several submodules from the same repository.
+type Submodules []*Submodule
+
+// Init initializes the submodules in this list.
+func (s Submodules) Init() error {
+ for _, sub := range s {
+ if err := sub.Init(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Update updates all the submodules in this list.
+func (s Submodules) Update(o *SubmoduleUpdateOptions) error {
+ return s.UpdateContext(context.Background(), o)
+}
+
+// UpdateContext updates all the submodules in this list.
+//
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects the
+// transport operations.
+func (s Submodules) UpdateContext(ctx context.Context, o *SubmoduleUpdateOptions) error {
+ for _, sub := range s {
+ if err := sub.UpdateContext(ctx, o); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Status returns the status of the submodules.
+func (s Submodules) Status() (SubmodulesStatus, error) {
+ var list SubmodulesStatus
+
+ var r *Repository
+ for _, sub := range s {
+ if r == nil {
+ r = sub.w.r
+ }
+
+ idx, err := r.Storer.Index()
+ if err != nil {
+ return nil, err
+ }
+
+ status, err := sub.status(idx)
+ if err != nil {
+ return nil, err
+ }
+
+ list = append(list, status)
+ }
+
+ return list, nil
+}
+
+// SubmodulesStatus contains the status for all submodiles in the worktree
+type SubmodulesStatus []*SubmoduleStatus
+
+// String is equivalent to `git submodule status`
+func (s SubmodulesStatus) String() string {
+ buf := bytes.NewBuffer(nil)
+ for _, sub := range s {
+ fmt.Fprintln(buf, sub)
+ }
+
+ return buf.String()
+}
+
+// SubmoduleStatus contains the status for a submodule in the worktree
+type SubmoduleStatus struct {
+ Path string
+ Current plumbing.Hash
+ Expected plumbing.Hash
+ Branch plumbing.ReferenceName
+}
+
+// IsClean is the HEAD of the submodule is equals to the expected commit
+func (s *SubmoduleStatus) IsClean() bool {
+ return s.Current == s.Expected
+}
+
+// String is equivalent to `git submodule status `
+//
+// This will print the SHA-1 of the currently checked out commit for a
+// submodule, along with the submodule path and the output of git describe fo
+// the SHA-1. Each SHA-1 will be prefixed with - if the submodule is not
+// initialized, + if the currently checked out submodule commit does not match
+// the SHA-1 found in the index of the containing repository.
+func (s *SubmoduleStatus) String() string {
+ var extra string
+ var status = ' '
+
+ if s.Current.IsZero() {
+ status = '-'
+ } else if !s.IsClean() {
+ status = '+'
+ }
+
+ if len(s.Branch) != 0 {
+ extra = string(s.Branch[5:])
+ } else if !s.Current.IsZero() {
+ extra = s.Current.String()[:7]
+ }
+
+ if extra != "" {
+ extra = fmt.Sprintf(" (%s)", extra)
+ }
+
+ return fmt.Sprintf("%c%s %s%s", status, s.Expected, s.Path, extra)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/binary/read.go b/vendor/github.com/go-git/go-git/v5/utils/binary/read.go
new file mode 100644
index 00000000..b8f9df1a
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/binary/read.go
@@ -0,0 +1,180 @@
+// Package binary implements syntax-sugar functions on top of the standard
+// library binary package
+package binary
+
+import (
+ "bufio"
+ "encoding/binary"
+ "io"
+
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+// Read reads structured binary data from r into data. Bytes are read and
+// decoded in BigEndian order
+// https://golang.org/pkg/encoding/binary/#Read
+func Read(r io.Reader, data ...interface{}) error {
+ for _, v := range data {
+ if err := binary.Read(r, binary.BigEndian, v); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// ReadUntil reads from r untin delim is found
+func ReadUntil(r io.Reader, delim byte) ([]byte, error) {
+ if bufr, ok := r.(*bufio.Reader); ok {
+ return ReadUntilFromBufioReader(bufr, delim)
+ }
+
+ var buf [1]byte
+ value := make([]byte, 0, 16)
+ for {
+ if _, err := io.ReadFull(r, buf[:]); err != nil {
+ if err == io.EOF {
+ return nil, err
+ }
+
+ return nil, err
+ }
+
+ if buf[0] == delim {
+ return value, nil
+ }
+
+ value = append(value, buf[0])
+ }
+}
+
+// ReadUntilFromBufioReader is like bufio.ReadBytes but drops the delimiter
+// from the result.
+func ReadUntilFromBufioReader(r *bufio.Reader, delim byte) ([]byte, error) {
+ value, err := r.ReadBytes(delim)
+ if err != nil || len(value) == 0 {
+ return nil, err
+ }
+
+ return value[:len(value)-1], nil
+}
+
+// ReadVariableWidthInt reads and returns an int in Git VLQ special format:
+//
+// Ordinary VLQ has some redundancies, example: the number 358 can be
+// encoded as the 2-octet VLQ 0x8166 or the 3-octet VLQ 0x808166 or the
+// 4-octet VLQ 0x80808166 and so forth.
+//
+// To avoid these redundancies, the VLQ format used in Git removes this
+// prepending redundancy and extends the representable range of shorter
+// VLQs by adding an offset to VLQs of 2 or more octets in such a way
+// that the lowest possible value for such an (N+1)-octet VLQ becomes
+// exactly one more than the maximum possible value for an N-octet VLQ.
+// In particular, since a 1-octet VLQ can store a maximum value of 127,
+// the minimum 2-octet VLQ (0x8000) is assigned the value 128 instead of
+// 0. Conversely, the maximum value of such a 2-octet VLQ (0xff7f) is
+// 16511 instead of just 16383. Similarly, the minimum 3-octet VLQ
+// (0x808000) has a value of 16512 instead of zero, which means
+// that the maximum 3-octet VLQ (0xffff7f) is 2113663 instead of
+// just 2097151. And so forth.
+//
+// This is how the offset is saved in C:
+//
+// dheader[pos] = ofs & 127;
+// while (ofs >>= 7)
+// dheader[--pos] = 128 | (--ofs & 127);
+//
+func ReadVariableWidthInt(r io.Reader) (int64, error) {
+ var c byte
+ if err := Read(r, &c); err != nil {
+ return 0, err
+ }
+
+ var v = int64(c & maskLength)
+ for c&maskContinue > 0 {
+ v++
+ if err := Read(r, &c); err != nil {
+ return 0, err
+ }
+
+ v = (v << lengthBits) + int64(c&maskLength)
+ }
+
+ return v, nil
+}
+
+const (
+ maskContinue = uint8(128) // 1000 000
+ maskLength = uint8(127) // 0111 1111
+ lengthBits = uint8(7) // subsequent bytes has 7 bits to store the length
+)
+
+// ReadUint64 reads 8 bytes and returns them as a BigEndian uint32
+func ReadUint64(r io.Reader) (uint64, error) {
+ var v uint64
+ if err := binary.Read(r, binary.BigEndian, &v); err != nil {
+ return 0, err
+ }
+
+ return v, nil
+}
+
+// ReadUint32 reads 4 bytes and returns them as a BigEndian uint32
+func ReadUint32(r io.Reader) (uint32, error) {
+ var v uint32
+ if err := binary.Read(r, binary.BigEndian, &v); err != nil {
+ return 0, err
+ }
+
+ return v, nil
+}
+
+// ReadUint16 reads 2 bytes and returns them as a BigEndian uint16
+func ReadUint16(r io.Reader) (uint16, error) {
+ var v uint16
+ if err := binary.Read(r, binary.BigEndian, &v); err != nil {
+ return 0, err
+ }
+
+ return v, nil
+}
+
+// ReadHash reads a plumbing.Hash from r
+func ReadHash(r io.Reader) (plumbing.Hash, error) {
+ var h plumbing.Hash
+ if err := binary.Read(r, binary.BigEndian, h[:]); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return h, nil
+}
+
+const sniffLen = 8000
+
+// IsBinary detects if data is a binary value based on:
+// http://git.kernel.org/cgit/git/git.git/tree/xdiff-interface.c?id=HEAD#n198
+func IsBinary(r io.Reader) (bool, error) {
+ reader := bufio.NewReader(r)
+ c := 0
+ for {
+ if c == sniffLen {
+ break
+ }
+
+ b, err := reader.ReadByte()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return false, err
+ }
+
+ if b == byte(0) {
+ return true, nil
+ }
+
+ c++
+ }
+
+ return false, nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/binary/write.go b/vendor/github.com/go-git/go-git/v5/utils/binary/write.go
new file mode 100644
index 00000000..c08c73a0
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/binary/write.go
@@ -0,0 +1,50 @@
+package binary
+
+import (
+ "encoding/binary"
+ "io"
+)
+
+// Write writes the binary representation of data into w, using BigEndian order
+// https://golang.org/pkg/encoding/binary/#Write
+func Write(w io.Writer, data ...interface{}) error {
+ for _, v := range data {
+ if err := binary.Write(w, binary.BigEndian, v); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func WriteVariableWidthInt(w io.Writer, n int64) error {
+ buf := []byte{byte(n & 0x7f)}
+ n >>= 7
+ for n != 0 {
+ n--
+ buf = append([]byte{0x80 | (byte(n & 0x7f))}, buf...)
+ n >>= 7
+ }
+
+ _, err := w.Write(buf)
+
+ return err
+}
+
+// WriteUint64 writes the binary representation of a uint64 into w, in BigEndian
+// order
+func WriteUint64(w io.Writer, value uint64) error {
+ return binary.Write(w, binary.BigEndian, value)
+}
+
+// WriteUint32 writes the binary representation of a uint32 into w, in BigEndian
+// order
+func WriteUint32(w io.Writer, value uint32) error {
+ return binary.Write(w, binary.BigEndian, value)
+}
+
+// WriteUint16 writes the binary representation of a uint16 into w, in BigEndian
+// order
+func WriteUint16(w io.Writer, value uint16) error {
+ return binary.Write(w, binary.BigEndian, value)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/diff/diff.go b/vendor/github.com/go-git/go-git/v5/utils/diff/diff.go
new file mode 100644
index 00000000..70054949
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/diff/diff.go
@@ -0,0 +1,61 @@
+// Package diff implements line oriented diffs, similar to the ancient
+// Unix diff command.
+//
+// The current implementation is just a wrapper around Sergi's
+// go-diff/diffmatchpatch library, which is a go port of Neil
+// Fraser's google-diff-match-patch code
+package diff
+
+import (
+ "bytes"
+ "time"
+
+ "github.com/sergi/go-diff/diffmatchpatch"
+)
+
+// Do computes the (line oriented) modifications needed to turn the src
+// string into the dst string. The underlying algorithm is Meyers,
+// its complexity is O(N*d) where N is min(lines(src), lines(dst)) and d
+// is the size of the diff.
+func Do(src, dst string) (diffs []diffmatchpatch.Diff) {
+ // the default timeout is time.Second which may be too small under heavy load
+ return DoWithTimeout(src, dst, time.Hour)
+}
+
+// DoWithTimeout computes the (line oriented) modifications needed to turn the src
+// string into the dst string. The `timeout` argument specifies the maximum
+// amount of time it is allowed to spend in this function. If the timeout
+// is exceeded, the parts of the strings which were not considered are turned into
+// a bulk delete+insert and the half-baked suboptimal result is returned at once.
+// The underlying algorithm is Meyers, its complexity is O(N*d) where N is
+// min(lines(src), lines(dst)) and d is the size of the diff.
+func DoWithTimeout(src, dst string, timeout time.Duration) (diffs []diffmatchpatch.Diff) {
+ dmp := diffmatchpatch.New()
+ dmp.DiffTimeout = timeout
+ wSrc, wDst, warray := dmp.DiffLinesToRunes(src, dst)
+ diffs = dmp.DiffMainRunes(wSrc, wDst, false)
+ diffs = dmp.DiffCharsToLines(diffs, warray)
+ return diffs
+}
+
+// Dst computes and returns the destination text.
+func Dst(diffs []diffmatchpatch.Diff) string {
+ var text bytes.Buffer
+ for _, d := range diffs {
+ if d.Type != diffmatchpatch.DiffDelete {
+ text.WriteString(d.Text)
+ }
+ }
+ return text.String()
+}
+
+// Src computes and returns the source text
+func Src(diffs []diffmatchpatch.Diff) string {
+ var text bytes.Buffer
+ for _, d := range diffs {
+ if d.Type != diffmatchpatch.DiffInsert {
+ text.WriteString(d.Text)
+ }
+ }
+ return text.String()
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/ioutil/common.go b/vendor/github.com/go-git/go-git/v5/utils/ioutil/common.go
new file mode 100644
index 00000000..235af717
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/ioutil/common.go
@@ -0,0 +1,210 @@
+// Package ioutil implements some I/O utility functions.
+package ioutil
+
+import (
+ "bufio"
+ "context"
+ "errors"
+ "io"
+
+ ctxio "github.com/jbenet/go-context/io"
+)
+
+type readPeeker interface {
+ io.Reader
+ Peek(int) ([]byte, error)
+}
+
+var (
+ ErrEmptyReader = errors.New("reader is empty")
+)
+
+// NonEmptyReader takes a reader and returns it if it is not empty, or
+// `ErrEmptyReader` if it is empty. If there is an error when reading the first
+// byte of the given reader, it will be propagated.
+func NonEmptyReader(r io.Reader) (io.Reader, error) {
+ pr, ok := r.(readPeeker)
+ if !ok {
+ pr = bufio.NewReader(r)
+ }
+
+ _, err := pr.Peek(1)
+ if err == io.EOF {
+ return nil, ErrEmptyReader
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ return pr, nil
+}
+
+type readCloser struct {
+ io.Reader
+ closer io.Closer
+}
+
+func (r *readCloser) Close() error {
+ return r.closer.Close()
+}
+
+// NewReadCloser creates an `io.ReadCloser` with the given `io.Reader` and
+// `io.Closer`.
+func NewReadCloser(r io.Reader, c io.Closer) io.ReadCloser {
+ return &readCloser{Reader: r, closer: c}
+}
+
+type readCloserCloser struct {
+ io.ReadCloser
+ closer func() error
+}
+
+func (r *readCloserCloser) Close() (err error) {
+ defer func() {
+ if err == nil {
+ err = r.closer()
+ return
+ }
+ _ = r.closer()
+ }()
+ return r.ReadCloser.Close()
+}
+
+// NewReadCloserWithCloser creates an `io.ReadCloser` with the given `io.ReaderCloser` and
+// `io.Closer` that ensures that the closer is closed on close
+func NewReadCloserWithCloser(r io.ReadCloser, c func() error) io.ReadCloser {
+ return &readCloserCloser{ReadCloser: r, closer: c}
+}
+
+type writeCloser struct {
+ io.Writer
+ closer io.Closer
+}
+
+func (r *writeCloser) Close() error {
+ return r.closer.Close()
+}
+
+// NewWriteCloser creates an `io.WriteCloser` with the given `io.Writer` and
+// `io.Closer`.
+func NewWriteCloser(w io.Writer, c io.Closer) io.WriteCloser {
+ return &writeCloser{Writer: w, closer: c}
+}
+
+type writeNopCloser struct {
+ io.Writer
+}
+
+func (writeNopCloser) Close() error { return nil }
+
+// WriteNopCloser returns a WriteCloser with a no-op Close method wrapping
+// the provided Writer w.
+func WriteNopCloser(w io.Writer) io.WriteCloser {
+ return writeNopCloser{w}
+}
+
+type readerAtAsReader struct {
+ io.ReaderAt
+ offset int64
+}
+
+func (r *readerAtAsReader) Read(bs []byte) (int, error) {
+ n, err := r.ReaderAt.ReadAt(bs, r.offset)
+ r.offset += int64(n)
+ return n, err
+}
+
+func NewReaderUsingReaderAt(r io.ReaderAt, offset int64) io.Reader {
+ return &readerAtAsReader{
+ ReaderAt: r,
+ offset: offset,
+ }
+}
+
+// CheckClose calls Close on the given io.Closer. If the given *error points to
+// nil, it will be assigned the error returned by Close. Otherwise, any error
+// returned by Close will be ignored. CheckClose is usually called with defer.
+func CheckClose(c io.Closer, err *error) {
+ if cerr := c.Close(); cerr != nil && *err == nil {
+ *err = cerr
+ }
+}
+
+// NewContextWriter wraps a writer to make it respect given Context.
+// If there is a blocking write, the returned Writer will return whenever the
+// context is cancelled (the return values are n=0 and err=ctx.Err()).
+func NewContextWriter(ctx context.Context, w io.Writer) io.Writer {
+ return ctxio.NewWriter(ctx, w)
+}
+
+// NewContextReader wraps a reader to make it respect given Context.
+// If there is a blocking read, the returned Reader will return whenever the
+// context is cancelled (the return values are n=0 and err=ctx.Err()).
+func NewContextReader(ctx context.Context, r io.Reader) io.Reader {
+ return ctxio.NewReader(ctx, r)
+}
+
+// NewContextWriteCloser as NewContextWriter but with io.Closer interface.
+func NewContextWriteCloser(ctx context.Context, w io.WriteCloser) io.WriteCloser {
+ ctxw := ctxio.NewWriter(ctx, w)
+ return NewWriteCloser(ctxw, w)
+}
+
+// NewContextReadCloser as NewContextReader but with io.Closer interface.
+func NewContextReadCloser(ctx context.Context, r io.ReadCloser) io.ReadCloser {
+ ctxr := ctxio.NewReader(ctx, r)
+ return NewReadCloser(ctxr, r)
+}
+
+type readerOnError struct {
+ io.Reader
+ notify func(error)
+}
+
+// NewReaderOnError returns a io.Reader that call the notify function when an
+// unexpected (!io.EOF) error happens, after call Read function.
+func NewReaderOnError(r io.Reader, notify func(error)) io.Reader {
+ return &readerOnError{r, notify}
+}
+
+// NewReadCloserOnError returns a io.ReadCloser that call the notify function
+// when an unexpected (!io.EOF) error happens, after call Read function.
+func NewReadCloserOnError(r io.ReadCloser, notify func(error)) io.ReadCloser {
+ return NewReadCloser(NewReaderOnError(r, notify), r)
+}
+
+func (r *readerOnError) Read(buf []byte) (n int, err error) {
+ n, err = r.Reader.Read(buf)
+ if err != nil && err != io.EOF {
+ r.notify(err)
+ }
+
+ return
+}
+
+type writerOnError struct {
+ io.Writer
+ notify func(error)
+}
+
+// NewWriterOnError returns a io.Writer that call the notify function when an
+// unexpected (!io.EOF) error happens, after call Write function.
+func NewWriterOnError(w io.Writer, notify func(error)) io.Writer {
+ return &writerOnError{w, notify}
+}
+
+// NewWriteCloserOnError returns a io.WriteCloser that call the notify function
+// when an unexpected (!io.EOF) error happens, after call Write function.
+func NewWriteCloserOnError(w io.WriteCloser, notify func(error)) io.WriteCloser {
+ return NewWriteCloser(NewWriterOnError(w, notify), w)
+}
+
+func (r *writerOnError) Write(p []byte) (n int, err error) {
+ n, err = r.Writer.Write(p)
+ if err != nil && err != io.EOF {
+ r.notify(err)
+ }
+
+ return
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/change.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/change.go
new file mode 100644
index 00000000..cc6dc890
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/change.go
@@ -0,0 +1,149 @@
+package merkletrie
+
+import (
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+// Action values represent the kind of things a Change can represent:
+// insertion, deletions or modifications of files.
+type Action int
+
+// The set of possible actions in a change.
+const (
+ _ Action = iota
+ Insert
+ Delete
+ Modify
+)
+
+// String returns the action as a human readable text.
+func (a Action) String() string {
+ switch a {
+ case Insert:
+ return "Insert"
+ case Delete:
+ return "Delete"
+ case Modify:
+ return "Modify"
+ default:
+ panic(fmt.Sprintf("unsupported action: %d", a))
+ }
+}
+
+// A Change value represent how a noder has change between to merkletries.
+type Change struct {
+ // The noder before the change or nil if it was inserted.
+ From noder.Path
+ // The noder after the change or nil if it was deleted.
+ To noder.Path
+}
+
+// Action is convenience method that returns what Action c represents.
+func (c *Change) Action() (Action, error) {
+ if c.From == nil && c.To == nil {
+ return Action(0), fmt.Errorf("malformed change: nil from and to")
+ }
+ if c.From == nil {
+ return Insert, nil
+ }
+ if c.To == nil {
+ return Delete, nil
+ }
+
+ return Modify, nil
+}
+
+// NewInsert returns a new Change representing the insertion of n.
+func NewInsert(n noder.Path) Change { return Change{To: n} }
+
+// NewDelete returns a new Change representing the deletion of n.
+func NewDelete(n noder.Path) Change { return Change{From: n} }
+
+// NewModify returns a new Change representing that a has been modified and
+// it is now b.
+func NewModify(a, b noder.Path) Change {
+ return Change{
+ From: a,
+ To: b,
+ }
+}
+
+// String returns a single change in human readable form, using the
+// format: '<' + action + space + path + '>'. The contents of the file
+// before or after the change are not included in this format.
+//
+// Example: inserting a file at the path a/b/c.txt will return "".
+func (c Change) String() string {
+ action, err := c.Action()
+ if err != nil {
+ panic(err)
+ }
+
+ var path string
+ if action == Delete {
+ path = c.From.String()
+ } else {
+ path = c.To.String()
+ }
+
+ return fmt.Sprintf("<%s %s>", action, path)
+}
+
+// Changes is a list of changes between to merkletries.
+type Changes []Change
+
+// NewChanges returns an empty list of changes.
+func NewChanges() Changes {
+ return Changes{}
+}
+
+// Add adds the change c to the list of changes.
+func (l *Changes) Add(c Change) {
+ *l = append(*l, c)
+}
+
+// AddRecursiveInsert adds the required changes to insert all the
+// file-like noders found in root, recursively.
+func (l *Changes) AddRecursiveInsert(root noder.Path) error {
+ return l.addRecursive(root, NewInsert)
+}
+
+// AddRecursiveDelete adds the required changes to delete all the
+// file-like noders found in root, recursively.
+func (l *Changes) AddRecursiveDelete(root noder.Path) error {
+ return l.addRecursive(root, NewDelete)
+}
+
+type noderToChangeFn func(noder.Path) Change // NewInsert or NewDelete
+
+func (l *Changes) addRecursive(root noder.Path, ctor noderToChangeFn) error {
+ if !root.IsDir() {
+ l.Add(ctor(root))
+ return nil
+ }
+
+ i, err := NewIterFromPath(root)
+ if err != nil {
+ return err
+ }
+
+ var current noder.Path
+ for {
+ if current, err = i.Step(); err != nil {
+ if err == io.EOF {
+ break
+ }
+ return err
+ }
+ if current.IsDir() {
+ continue
+ }
+ l.Add(ctor(current))
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/difftree.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/difftree.go
new file mode 100644
index 00000000..8090942d
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/difftree.go
@@ -0,0 +1,453 @@
+package merkletrie
+
+// The focus of this difftree implementation is to save time by
+// skipping whole directories if their hash is the same in both
+// trees.
+//
+// The diff algorithm implemented here is based on the doubleiter
+// type defined in this same package; we will iterate over both
+// trees at the same time, while comparing the current noders in
+// each iterator. Depending on how they differ we will output the
+// corresponding changes and move the iterators further over both
+// trees.
+//
+// The table bellow show all the possible comparison results, along
+// with what changes should we produce and how to advance the
+// iterators.
+//
+// The table is implemented by the switches in this function,
+// diffTwoNodes, diffTwoNodesSameName and diffTwoDirs.
+//
+// Many Bothans died to bring us this information, make sure you
+// understand the table before modifying this code.
+
+// # Cases
+//
+// When comparing noders in both trees you will find yourself in
+// one of 169 possible cases, but if we ignore moves, we can
+// simplify a lot the search space into the following table:
+//
+// - "-": nothing, no file or directory
+// - a<>: an empty file named "a".
+// - a<1>: a file named "a", with "1" as its contents.
+// - a<2>: a file named "a", with "2" as its contents.
+// - a(): an empty dir named "a".
+// - a(...): a dir named "a", with some files and/or dirs inside (possibly
+// empty).
+// - a(;;;): a dir named "a", with some other files and/or dirs inside
+// (possibly empty), which different from the ones in "a(...)".
+//
+// \ to - a<> a<1> a<2> a() a(...) a(;;;)
+// from \
+// - 00 01 02 03 04 05 06
+// a<> 10 11 12 13 14 15 16
+// a<1> 20 21 22 23 24 25 26
+// a<2> 30 31 32 33 34 35 36
+// a() 40 41 42 43 44 45 46
+// a(...) 50 51 52 53 54 55 56
+// a(;;;) 60 61 62 63 64 65 66
+//
+// Every (from, to) combination in the table is a special case, but
+// some of them can be merged into some more general cases, for
+// instance 11 and 22 can be merged into the general case: both
+// noders are equal.
+//
+// Here is a full list of all the cases that are similar and how to
+// merge them together into more general cases. Each general case
+// is labeled with an uppercase letter for further reference, and it
+// is followed by the pseudocode of the checks you have to perform
+// on both noders to see if you are in such a case, the actions to
+// perform (i.e. what changes to output) and how to advance the
+// iterators of each tree to continue the comparison process.
+//
+// ## A. Impossible: 00
+//
+// ## B. Same thing on both sides: 11, 22, 33, 44, 55, 66
+// - check: `SameName() && SameHash()`
+// - action: do nothing.
+// - advance: `FromNext(); ToNext()`
+//
+// ### C. To was created: 01, 02, 03, 04, 05, 06
+// - check: `DifferentName() && ToBeforeFrom()`
+// - action: insertRecursively(to)
+// - advance: `ToNext()`
+//
+// ### D. From was deleted: 10, 20, 30, 40, 50, 60
+// - check: `DifferentName() && FromBeforeTo()`
+// - action: `DeleteRecursively(from)`
+// - advance: `FromNext()`
+//
+// ### E. Empty file to file with contents: 12, 13
+// - check: `SameName() && DifferentHash() && FromIsFile() &&
+// ToIsFile() && FromIsEmpty()`
+// - action: `modifyFile(from, to)`
+// - advance: `FromNext()` or `FromStep()`
+//
+// ### E'. file with contents to empty file: 21, 31
+// - check: `SameName() && DifferentHash() && FromIsFile() &&
+// ToIsFile() && ToIsEmpty()`
+// - action: `modifyFile(from, to)`
+// - advance: `FromNext()` or `FromStep()`
+//
+// ### F. empty file to empty dir with the same name: 14
+// - check: `SameName() && FromIsFile() && FromIsEmpty() &&
+// ToIsDir() && ToIsEmpty()`
+// - action: `DeleteFile(from); InsertEmptyDir(to)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### F'. empty dir to empty file of the same name: 41
+// - check: `SameName() && FromIsDir() && FromIsEmpty &&
+// ToIsFile() && ToIsEmpty()`
+// - action: `DeleteEmptyDir(from); InsertFile(to)`
+// - advance: `FromNext(); ToNext()` or step for any of them.
+//
+// ### G. empty file to non-empty dir of the same name: 15, 16
+// - check: `SameName() && FromIsFile() && ToIsDir() &&
+// FromIsEmpty() && ToIsNotEmpty()`
+// - action: `DeleteFile(from); InsertDirRecursively(to)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### G'. non-empty dir to empty file of the same name: 51, 61
+// - check: `SameName() && FromIsDir() && FromIsNotEmpty() &&
+// ToIsFile() && FromIsEmpty()`
+// - action: `DeleteDirRecursively(from); InsertFile(to)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### H. modify file contents: 23, 32
+// - check: `SameName() && FromIsFile() && ToIsFile() &&
+// FromIsNotEmpty() && ToIsNotEmpty()`
+// - action: `ModifyFile(from, to)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### I. file with contents to empty dir: 24, 34
+// - check: `SameName() && DifferentHash() && FromIsFile() &&
+// FromIsNotEmpty() && ToIsDir() && ToIsEmpty()`
+// - action: `DeleteFile(from); InsertEmptyDir(to)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### I'. empty dir to file with contents: 42, 43
+// - check: `SameName() && DifferentHash() && FromIsDir() &&
+// FromIsEmpty() && ToIsFile() && ToIsEmpty()`
+// - action: `DeleteDir(from); InsertFile(to)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### J. file with contents to dir with contents: 25, 26, 35, 36
+// - check: `SameName() && DifferentHash() && FromIsFile() &&
+// FromIsNotEmpty() && ToIsDir() && ToIsNotEmpty()`
+// - action: `DeleteFile(from); InsertDirRecursively(to)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### J'. dir with contents to file with contents: 52, 62, 53, 63
+// - check: `SameName() && DifferentHash() && FromIsDir() &&
+// FromIsNotEmpty() && ToIsFile() && ToIsNotEmpty()`
+// - action: `DeleteDirRecursively(from); InsertFile(to)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### K. empty dir to dir with contents: 45, 46
+// - check: `SameName() && DifferentHash() && FromIsDir() &&
+// FromIsEmpty() && ToIsDir() && ToIsNotEmpty()`
+// - action: `InsertChildrenRecursively(to)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### K'. dir with contents to empty dir: 54, 64
+// - check: `SameName() && DifferentHash() && FromIsDir() &&
+// FromIsEmpty() && ToIsDir() && ToIsNotEmpty()`
+// - action: `DeleteChildrenRecursively(from)`
+// - advance: `FromNext(); ToNext()`
+//
+// ### L. dir with contents to dir with different contents: 56, 65
+// - check: `SameName() && DifferentHash() && FromIsDir() &&
+// FromIsNotEmpty() && ToIsDir() && ToIsNotEmpty()`
+// - action: nothing
+// - advance: `FromStep(); ToStep()`
+//
+//
+
+// All these cases can be further simplified by a truth table
+// reduction process, in which we gather similar checks together to
+// make the final code easier to read and understand.
+//
+// The first 6 columns are the outputs of the checks to perform on
+// both noders. I have labeled them 1 to 6, this is what they mean:
+//
+// 1: SameName()
+// 2: SameHash()
+// 3: FromIsDir()
+// 4: ToIsDir()
+// 5: FromIsEmpty()
+// 6: ToIsEmpty()
+//
+// The from and to columns are a fsnoder example of the elements
+// that you will find on each tree under the specified comparison
+// results (columns 1 to 6).
+//
+// The type column identifies the case we are into, from the list above.
+//
+// The type' column identifies the new set of reduced cases, using
+// lowercase letters, and they are explained after the table.
+//
+// The last column is the set of actions and advances for each case.
+//
+// "---" means impossible except in case of hash collision.
+//
+// advance meaning:
+// - NN: from.Next(); to.Next()
+// - SS: from.Step(); to.Step()
+//
+// 1 2 3 4 5 6 | from | to |type|type'|action ; advance
+// ------------+--------+--------+----+------------------------------------
+// 0 0 0 0 0 0 | | | | | if !SameName() {
+// . | | | | | if FromBeforeTo() {
+// . | | | D | d | delete(from); from.Next()
+// . | | | | | } else {
+// . | | | C | c | insert(to); to.Next()
+// . | | | | | }
+// 0 1 1 1 1 1 | | | | | }
+// 1 0 0 0 0 0 | a<1> | a<2> | H | e | modify(from, to); NN
+// 1 0 0 0 0 1 | a<1> | a<> | E' | e | modify(from, to); NN
+// 1 0 0 0 1 0 | a<> | a<1> | E | e | modify(from, to); NN
+// 1 0 0 0 1 1 | ---- | ---- | | e |
+// 1 0 0 1 0 0 | a<1> | a(...) | J | f | delete(from); insert(to); NN
+// 1 0 0 1 0 1 | a<1> | a() | I | f | delete(from); insert(to); NN
+// 1 0 0 1 1 0 | a<> | a(...) | G | f | delete(from); insert(to); NN
+// 1 0 0 1 1 1 | a<> | a() | F | f | delete(from); insert(to); NN
+// 1 0 1 0 0 0 | a(...) | a<1> | J' | f | delete(from); insert(to); NN
+// 1 0 1 0 0 1 | a(...) | a<> | G' | f | delete(from); insert(to); NN
+// 1 0 1 0 1 0 | a() | a<1> | I' | f | delete(from); insert(to); NN
+// 1 0 1 0 1 1 | a() | a<> | F' | f | delete(from); insert(to); NN
+// 1 0 1 1 0 0 | a(...) | a(;;;) | L | g | nothing; SS
+// 1 0 1 1 0 1 | a(...) | a() | K' | h | deleteChildren(from); NN
+// 1 0 1 1 1 0 | a() | a(...) | K | i | insertChildren(to); NN
+// 1 0 1 1 1 1 | ---- | ---- | | |
+// 1 1 0 0 0 0 | a<1> | a<1> | B | b | nothing; NN
+// 1 1 0 0 0 1 | ---- | ---- | | b |
+// 1 1 0 0 1 0 | ---- | ---- | | b |
+// 1 1 0 0 1 1 | a<> | a<> | B | b | nothing; NN
+// 1 1 0 1 0 0 | ---- | ---- | | b |
+// 1 1 0 1 0 1 | ---- | ---- | | b |
+// 1 1 0 1 1 0 | ---- | ---- | | b |
+// 1 1 0 1 1 1 | ---- | ---- | | b |
+// 1 1 1 0 0 0 | ---- | ---- | | b |
+// 1 1 1 0 0 1 | ---- | ---- | | b |
+// 1 1 1 0 1 0 | ---- | ---- | | b |
+// 1 1 1 0 1 1 | ---- | ---- | | b |
+// 1 1 1 1 0 0 | a(...) | a(...) | B | b | nothing; NN
+// 1 1 1 1 0 1 | ---- | ---- | | b |
+// 1 1 1 1 1 0 | ---- | ---- | | b |
+// 1 1 1 1 1 1 | a() | a() | B | b | nothing; NN
+//
+// c and d:
+// if !SameName()
+// d if FromBeforeTo()
+// c else
+// b: SameName) && sameHash()
+// e: SameName() && !sameHash() && BothAreFiles()
+// f: SameName() && !sameHash() && FileAndDir()
+// g: SameName() && !sameHash() && BothAreDirs() && NoneIsEmpty
+// i: SameName() && !sameHash() && BothAreDirs() && FromIsEmpty
+// h: else of i
+
+import (
+ "context"
+ "errors"
+ "fmt"
+
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+var (
+ // ErrCanceled is returned whenever the operation is canceled.
+ ErrCanceled = errors.New("operation canceled")
+)
+
+// DiffTree calculates the list of changes between two merkletries. It
+// uses the provided hashEqual callback to compare noders.
+func DiffTree(
+ fromTree,
+ toTree noder.Noder,
+ hashEqual noder.Equal,
+) (Changes, error) {
+ return DiffTreeContext(context.Background(), fromTree, toTree, hashEqual)
+}
+
+// DiffTreeContext calculates the list of changes between two merkletries. It
+// uses the provided hashEqual callback to compare noders.
+// Error will be returned if context expires
+// Provided context must be non nil
+func DiffTreeContext(ctx context.Context, fromTree, toTree noder.Noder,
+ hashEqual noder.Equal) (Changes, error) {
+ ret := NewChanges()
+
+ ii, err := newDoubleIter(fromTree, toTree, hashEqual)
+ if err != nil {
+ return nil, err
+ }
+
+ for {
+ select {
+ case <-ctx.Done():
+ return nil, ErrCanceled
+ default:
+ }
+
+ from := ii.from.current
+ to := ii.to.current
+
+ switch r := ii.remaining(); r {
+ case noMoreNoders:
+ return ret, nil
+ case onlyFromRemains:
+ if err = ret.AddRecursiveDelete(from); err != nil {
+ return nil, err
+ }
+ if err = ii.nextFrom(); err != nil {
+ return nil, err
+ }
+ case onlyToRemains:
+ if to.Skip() {
+ if err = ret.AddRecursiveDelete(to); err != nil {
+ return nil, err
+ }
+ } else {
+ if err = ret.AddRecursiveInsert(to); err != nil {
+ return nil, err
+ }
+ }
+ if err = ii.nextTo(); err != nil {
+ return nil, err
+ }
+ case bothHaveNodes:
+ if from.Skip() {
+ if err = ret.AddRecursiveDelete(from); err != nil {
+ return nil, err
+ }
+ if err := ii.nextBoth(); err != nil {
+ return nil, err
+ }
+ break
+ }
+ if to.Skip() {
+ if err = ret.AddRecursiveDelete(to); err != nil {
+ return nil, err
+ }
+ if err := ii.nextBoth(); err != nil {
+ return nil, err
+ }
+ break
+ }
+
+ if err = diffNodes(&ret, ii); err != nil {
+ return nil, err
+ }
+ default:
+ panic(fmt.Sprintf("unknown remaining value: %d", r))
+ }
+ }
+}
+
+func diffNodes(changes *Changes, ii *doubleIter) error {
+ from := ii.from.current
+ to := ii.to.current
+ var err error
+
+ // compare their full paths as strings
+ switch from.Compare(to) {
+ case -1:
+ if err = changes.AddRecursiveDelete(from); err != nil {
+ return err
+ }
+ if err = ii.nextFrom(); err != nil {
+ return err
+ }
+ case 1:
+ if err = changes.AddRecursiveInsert(to); err != nil {
+ return err
+ }
+ if err = ii.nextTo(); err != nil {
+ return err
+ }
+ default:
+ if err := diffNodesSameName(changes, ii); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func diffNodesSameName(changes *Changes, ii *doubleIter) error {
+ from := ii.from.current
+ to := ii.to.current
+
+ status, err := ii.compare()
+ if err != nil {
+ return err
+ }
+
+ switch {
+ case status.sameHash:
+ // do nothing
+ if err = ii.nextBoth(); err != nil {
+ return err
+ }
+ case status.bothAreFiles:
+ changes.Add(NewModify(from, to))
+ if err = ii.nextBoth(); err != nil {
+ return err
+ }
+ case status.fileAndDir:
+ if err = changes.AddRecursiveDelete(from); err != nil {
+ return err
+ }
+ if err = changes.AddRecursiveInsert(to); err != nil {
+ return err
+ }
+ if err = ii.nextBoth(); err != nil {
+ return err
+ }
+ case status.bothAreDirs:
+ if err = diffDirs(changes, ii); err != nil {
+ return err
+ }
+ default:
+ return fmt.Errorf("bad status from double iterator")
+ }
+
+ return nil
+}
+
+func diffDirs(changes *Changes, ii *doubleIter) error {
+ from := ii.from.current
+ to := ii.to.current
+
+ status, err := ii.compare()
+ if err != nil {
+ return err
+ }
+
+ switch {
+ case status.fromIsEmptyDir:
+ if err = changes.AddRecursiveInsert(to); err != nil {
+ return err
+ }
+ if err = ii.nextBoth(); err != nil {
+ return err
+ }
+ case status.toIsEmptyDir:
+ if err = changes.AddRecursiveDelete(from); err != nil {
+ return err
+ }
+ if err = ii.nextBoth(); err != nil {
+ return err
+ }
+ case !status.fromIsEmptyDir && !status.toIsEmptyDir:
+ // do nothing
+ if err = ii.stepBoth(); err != nil {
+ return err
+ }
+ default:
+ return fmt.Errorf("both dirs are empty but has different hash")
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/doc.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/doc.go
new file mode 100644
index 00000000..5204024a
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/doc.go
@@ -0,0 +1,34 @@
+/*
+Package merkletrie provides support for n-ary trees that are at the same
+time Merkle trees and Radix trees (tries).
+
+Git trees are Radix n-ary trees in virtue of the names of their
+tree entries. At the same time, git trees are Merkle trees thanks to
+their hashes.
+
+This package defines Merkle tries as nodes that should have:
+
+- a hash: the Merkle part of the Merkle trie
+
+- a key: the Radix part of the Merkle trie
+
+The Merkle hash condition is not enforced by this package though. This
+means that the hash of a node doesn't have to take into account the hashes of
+their children, which is good for testing purposes.
+
+Nodes in the Merkle trie are abstracted by the Noder interface. The
+intended use is that git trees implements this interface, either
+directly or using a simple wrapper.
+
+This package provides an iterator for merkletries that can skip whole
+directory-like noders and an efficient merkletrie comparison algorithm.
+
+When comparing git trees, the simple approach of alphabetically sorting
+their elements and comparing the resulting lists is too slow as it
+depends linearly on the number of files in the trees: When a directory
+has lots of files but none of them has been modified, this approach is
+very expensive. We can do better by prunning whole directories that
+have not change, just by looking at their hashes. This package provides
+the tools to do exactly that.
+*/
+package merkletrie
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/doubleiter.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/doubleiter.go
new file mode 100644
index 00000000..4a4341b3
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/doubleiter.go
@@ -0,0 +1,187 @@
+package merkletrie
+
+import (
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+// A doubleIter is a convenience type to keep track of the current
+// noders in two merkletries that are going to be iterated in parallel.
+// It has methods for:
+//
+// - iterating over the merkletries, both at the same time or
+// individually: nextFrom, nextTo, nextBoth, stepBoth
+//
+// - checking if there are noders left in one or both of them with the
+// remaining method and its associated returned type.
+//
+// - comparing the current noders of both merkletries in several ways,
+// with the compare method and its associated returned type.
+type doubleIter struct {
+ from struct {
+ iter *Iter
+ current noder.Path // nil if no more nodes
+ }
+ to struct {
+ iter *Iter
+ current noder.Path // nil if no more nodes
+ }
+ hashEqual noder.Equal
+}
+
+// NewdoubleIter returns a new doubleIter for the merkletries "from" and
+// "to". The hashEqual callback function will be used by the doubleIter
+// to compare the hash of the noders in the merkletries. The doubleIter
+// will be initialized to the first elements in each merkletrie if any.
+func newDoubleIter(from, to noder.Noder, hashEqual noder.Equal) (
+ *doubleIter, error) {
+ var ii doubleIter
+ var err error
+
+ if ii.from.iter, err = NewIter(from); err != nil {
+ return nil, fmt.Errorf("from: %s", err)
+ }
+ if ii.from.current, err = ii.from.iter.Next(); turnEOFIntoNil(err) != nil {
+ return nil, fmt.Errorf("from: %s", err)
+ }
+
+ if ii.to.iter, err = NewIter(to); err != nil {
+ return nil, fmt.Errorf("to: %s", err)
+ }
+ if ii.to.current, err = ii.to.iter.Next(); turnEOFIntoNil(err) != nil {
+ return nil, fmt.Errorf("to: %s", err)
+ }
+
+ ii.hashEqual = hashEqual
+
+ return &ii, nil
+}
+
+func turnEOFIntoNil(e error) error {
+ if e != nil && e != io.EOF {
+ return e
+ }
+ return nil
+}
+
+// NextBoth makes d advance to the next noder in both merkletries. If
+// any of them is a directory, it skips its contents.
+func (d *doubleIter) nextBoth() error {
+ if err := d.nextFrom(); err != nil {
+ return err
+ }
+ if err := d.nextTo(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// NextFrom makes d advance to the next noder in the "from" merkletrie,
+// skipping its contents if it is a directory.
+func (d *doubleIter) nextFrom() (err error) {
+ d.from.current, err = d.from.iter.Next()
+ return turnEOFIntoNil(err)
+}
+
+// NextTo makes d advance to the next noder in the "to" merkletrie,
+// skipping its contents if it is a directory.
+func (d *doubleIter) nextTo() (err error) {
+ d.to.current, err = d.to.iter.Next()
+ return turnEOFIntoNil(err)
+}
+
+// StepBoth makes d advance to the next noder in both merkletries,
+// getting deeper into directories if that is the case.
+func (d *doubleIter) stepBoth() (err error) {
+ if d.from.current, err = d.from.iter.Step(); turnEOFIntoNil(err) != nil {
+ return err
+ }
+ if d.to.current, err = d.to.iter.Step(); turnEOFIntoNil(err) != nil {
+ return err
+ }
+ return nil
+}
+
+// Remaining returns if there are no more noders in the tree, if both
+// have noders or if one of them doesn't.
+func (d *doubleIter) remaining() remaining {
+ if d.from.current == nil && d.to.current == nil {
+ return noMoreNoders
+ }
+
+ if d.from.current == nil && d.to.current != nil {
+ return onlyToRemains
+ }
+
+ if d.from.current != nil && d.to.current == nil {
+ return onlyFromRemains
+ }
+
+ return bothHaveNodes
+}
+
+// Remaining values tells you whether both trees still have noders, or
+// only one of them or none of them.
+type remaining int
+
+const (
+ noMoreNoders remaining = iota
+ onlyToRemains
+ onlyFromRemains
+ bothHaveNodes
+)
+
+// Compare returns the comparison between the current elements in the
+// merkletries.
+func (d *doubleIter) compare() (s comparison, err error) {
+ s.sameHash = d.hashEqual(d.from.current, d.to.current)
+
+ fromIsDir := d.from.current.IsDir()
+ toIsDir := d.to.current.IsDir()
+
+ s.bothAreDirs = fromIsDir && toIsDir
+ s.bothAreFiles = !fromIsDir && !toIsDir
+ s.fileAndDir = !s.bothAreDirs && !s.bothAreFiles
+
+ fromNumChildren, err := d.from.current.NumChildren()
+ if err != nil {
+ return comparison{}, fmt.Errorf("from: %s", err)
+ }
+
+ toNumChildren, err := d.to.current.NumChildren()
+ if err != nil {
+ return comparison{}, fmt.Errorf("to: %s", err)
+ }
+
+ s.fromIsEmptyDir = fromIsDir && fromNumChildren == 0
+ s.toIsEmptyDir = toIsDir && toNumChildren == 0
+
+ return
+}
+
+// Answers to a lot of questions you can ask about how to noders are
+// equal or different.
+type comparison struct {
+ // the following are only valid if both nodes have the same name
+ // (i.e. nameComparison == 0)
+
+ // Do both nodes have the same hash?
+ sameHash bool
+ // Are both nodes files?
+ bothAreFiles bool
+
+ // the following are only valid if any of the noders are dirs,
+ // this is, if !bothAreFiles
+
+ // Is one a file and the other a dir?
+ fileAndDir bool
+ // Are both nodes dirs?
+ bothAreDirs bool
+ // Is the from node an empty dir?
+ fromIsEmptyDir bool
+ // Is the to Node an empty dir?
+ toIsEmptyDir bool
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/filesystem/node.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/filesystem/node.go
new file mode 100644
index 00000000..33800627
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/filesystem/node.go
@@ -0,0 +1,205 @@
+package filesystem
+
+import (
+ "io"
+ "os"
+ "path"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+var ignore = map[string]bool{
+ ".git": true,
+}
+
+// The node represents a file or a directory in a billy.Filesystem. It
+// implements the interface noder.Noder of merkletrie package.
+//
+// This implementation implements a "standard" hash method being able to be
+// compared with any other noder.Noder implementation inside of go-git.
+type node struct {
+ fs billy.Filesystem
+ submodules map[string]plumbing.Hash
+
+ path string
+ hash []byte
+ children []noder.Noder
+ isDir bool
+ mode os.FileMode
+ size int64
+}
+
+// NewRootNode returns the root node based on a given billy.Filesystem.
+//
+// In order to provide the submodule hash status, a map[string]plumbing.Hash
+// should be provided where the key is the path of the submodule and the commit
+// of the submodule HEAD
+func NewRootNode(
+ fs billy.Filesystem,
+ submodules map[string]plumbing.Hash,
+) noder.Noder {
+ return &node{fs: fs, submodules: submodules, isDir: true}
+}
+
+// Hash the hash of a filesystem is the result of concatenating the computed
+// plumbing.Hash of the file as a Blob and its plumbing.FileMode; that way the
+// difftree algorithm will detect changes in the contents of files and also in
+// their mode.
+//
+// Please note that the hash is calculated on first invocation of Hash(),
+// meaning that it will not update when the underlying file changes
+// between invocations.
+//
+// The hash of a directory is always a 24-bytes slice of zero values
+func (n *node) Hash() []byte {
+ if n.hash == nil {
+ n.calculateHash()
+ }
+ return n.hash
+}
+
+func (n *node) Name() string {
+ return path.Base(n.path)
+}
+
+func (n *node) IsDir() bool {
+ return n.isDir
+}
+
+func (n *node) Skip() bool {
+ return false
+}
+
+func (n *node) Children() ([]noder.Noder, error) {
+ if err := n.calculateChildren(); err != nil {
+ return nil, err
+ }
+
+ return n.children, nil
+}
+
+func (n *node) NumChildren() (int, error) {
+ if err := n.calculateChildren(); err != nil {
+ return -1, err
+ }
+
+ return len(n.children), nil
+}
+
+func (n *node) calculateChildren() error {
+ if !n.IsDir() {
+ return nil
+ }
+
+ if len(n.children) != 0 {
+ return nil
+ }
+
+ files, err := n.fs.ReadDir(n.path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
+ }
+
+ for _, file := range files {
+ if _, ok := ignore[file.Name()]; ok {
+ continue
+ }
+
+ if file.Mode()&os.ModeSocket != 0 {
+ continue
+ }
+
+ c, err := n.newChildNode(file)
+ if err != nil {
+ return err
+ }
+
+ n.children = append(n.children, c)
+ }
+
+ return nil
+}
+
+func (n *node) newChildNode(file os.FileInfo) (*node, error) {
+ path := path.Join(n.path, file.Name())
+
+ node := &node{
+ fs: n.fs,
+ submodules: n.submodules,
+
+ path: path,
+ isDir: file.IsDir(),
+ size: file.Size(),
+ mode: file.Mode(),
+ }
+
+ if _, isSubmodule := n.submodules[path]; isSubmodule {
+ node.isDir = false
+ }
+
+ return node, nil
+}
+
+func (n *node) calculateHash() {
+ if n.isDir {
+ n.hash = make([]byte, 24)
+ return
+ }
+ mode, err := filemode.NewFromOSFileMode(n.mode)
+ if err != nil {
+ n.hash = plumbing.ZeroHash[:]
+ return
+ }
+ if submoduleHash, isSubmodule := n.submodules[n.path]; isSubmodule {
+ n.hash = append(submoduleHash[:], filemode.Submodule.Bytes()...)
+ return
+ }
+ var hash plumbing.Hash
+ if n.mode&os.ModeSymlink != 0 {
+ hash = n.doCalculateHashForSymlink()
+ } else {
+ hash = n.doCalculateHashForRegular()
+ }
+ n.hash = append(hash[:], mode.Bytes()...)
+}
+
+func (n *node) doCalculateHashForRegular() plumbing.Hash {
+ f, err := n.fs.Open(n.path)
+ if err != nil {
+ return plumbing.ZeroHash
+ }
+
+ defer f.Close()
+
+ h := plumbing.NewHasher(plumbing.BlobObject, n.size)
+ if _, err := io.Copy(h, f); err != nil {
+ return plumbing.ZeroHash
+ }
+
+ return h.Sum()
+}
+
+func (n *node) doCalculateHashForSymlink() plumbing.Hash {
+ target, err := n.fs.Readlink(n.path)
+ if err != nil {
+ return plumbing.ZeroHash
+ }
+
+ h := plumbing.NewHasher(plumbing.BlobObject, n.size)
+ if _, err := h.Write([]byte(target)); err != nil {
+ return plumbing.ZeroHash
+ }
+
+ return h.Sum()
+}
+
+func (n *node) String() string {
+ return n.path
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/index/node.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/index/node.go
new file mode 100644
index 00000000..c1809f7e
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/index/node.go
@@ -0,0 +1,95 @@
+package index
+
+import (
+ "path"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+// The node represents a index.Entry or a directory inferred from the path
+// of all entries. It implements the interface noder.Noder of merkletrie
+// package.
+//
+// This implementation implements a "standard" hash method being able to be
+// compared with any other noder.Noder implementation inside of go-git
+type node struct {
+ path string
+ entry *index.Entry
+ children []noder.Noder
+ isDir bool
+ skip bool
+}
+
+// NewRootNode returns the root node of a computed tree from a index.Index,
+func NewRootNode(idx *index.Index) noder.Noder {
+ const rootNode = ""
+
+ m := map[string]*node{rootNode: {isDir: true}}
+
+ for _, e := range idx.Entries {
+ parts := strings.Split(e.Name, string("/"))
+
+ var fullpath string
+ for _, part := range parts {
+ parent := fullpath
+ fullpath = path.Join(fullpath, part)
+
+ if _, ok := m[fullpath]; ok {
+ continue
+ }
+
+ n := &node{path: fullpath, skip: e.SkipWorktree}
+ if fullpath == e.Name {
+ n.entry = e
+ } else {
+ n.isDir = true
+ }
+
+ m[n.path] = n
+ m[parent].children = append(m[parent].children, n)
+ }
+ }
+
+ return m[rootNode]
+}
+
+func (n *node) String() string {
+ return n.path
+}
+
+func (n *node) Skip() bool {
+ return n.skip
+}
+
+// Hash the hash of a filesystem is a 24-byte slice, is the result of
+// concatenating the computed plumbing.Hash of the file as a Blob and its
+// plumbing.FileMode; that way the difftree algorithm will detect changes in the
+// contents of files and also in their mode.
+//
+// If the node is computed and not based on a index.Entry the hash is equals
+// to a 24-bytes slices of zero values.
+func (n *node) Hash() []byte {
+ if n.entry == nil {
+ return make([]byte, 24)
+ }
+
+ return append(n.entry.Hash[:], n.entry.Mode.Bytes()...)
+}
+
+func (n *node) Name() string {
+ return path.Base(n.path)
+}
+
+func (n *node) IsDir() bool {
+ return n.isDir
+}
+
+func (n *node) Children() ([]noder.Noder, error) {
+ return n.children, nil
+}
+
+func (n *node) NumChildren() (int, error) {
+ return len(n.children), nil
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/internal/frame/frame.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/internal/frame/frame.go
new file mode 100644
index 00000000..131878a1
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/internal/frame/frame.go
@@ -0,0 +1,91 @@
+package frame
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+ "strings"
+
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+// A Frame is a collection of siblings in a trie, sorted alphabetically
+// by name.
+type Frame struct {
+ // siblings, sorted in reverse alphabetical order by name
+ stack []noder.Noder
+}
+
+type byName []noder.Noder
+
+func (a byName) Len() int { return len(a) }
+func (a byName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a byName) Less(i, j int) bool {
+ return strings.Compare(a[i].Name(), a[j].Name()) < 0
+}
+
+// New returns a frame with the children of the provided node.
+func New(n noder.Noder) (*Frame, error) {
+ children, err := n.Children()
+ if err != nil {
+ return nil, err
+ }
+
+ sort.Sort(sort.Reverse(byName(children)))
+ return &Frame{
+ stack: children,
+ }, nil
+}
+
+// String returns the quoted names of the noders in the frame sorted in
+// alphabetical order by name, surrounded by square brackets and
+// separated by comas.
+//
+// Examples:
+// []
+// ["a", "b"]
+func (f *Frame) String() string {
+ var buf bytes.Buffer
+ _ = buf.WriteByte('[')
+
+ sep := ""
+ for i := f.Len() - 1; i >= 0; i-- {
+ _, _ = buf.WriteString(sep)
+ sep = ", "
+ _, _ = buf.WriteString(fmt.Sprintf("%q", f.stack[i].Name()))
+ }
+
+ _ = buf.WriteByte(']')
+
+ return buf.String()
+}
+
+// First returns, but dont extract, the noder with the alphabetically
+// smaller name in the frame and true if the frame was not empty.
+// Otherwise it returns nil and false.
+func (f *Frame) First() (noder.Noder, bool) {
+ if f.Len() == 0 {
+ return nil, false
+ }
+
+ top := f.Len() - 1
+
+ return f.stack[top], true
+}
+
+// Drop extracts the noder with the alphabetically smaller name in the
+// frame or does nothing if the frame was empty.
+func (f *Frame) Drop() {
+ if f.Len() == 0 {
+ return
+ }
+
+ top := f.Len() - 1
+ f.stack[top] = nil
+ f.stack = f.stack[:top]
+}
+
+// Len returns the number of noders in the frame.
+func (f *Frame) Len() int {
+ return len(f.stack)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/iter.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/iter.go
new file mode 100644
index 00000000..d75afec4
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/iter.go
@@ -0,0 +1,216 @@
+package merkletrie
+
+import (
+ "fmt"
+ "io"
+
+ "github.com/go-git/go-git/v5/utils/merkletrie/internal/frame"
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+// Iter is an iterator for merkletries (only the trie part of the
+// merkletrie is relevant here, it does not use the Hasher interface).
+//
+// The iteration is performed in depth-first pre-order. Entries at each
+// depth are traversed in (case-sensitive) alphabetical order.
+//
+// This is the kind of traversal you will expect when listing ordinary
+// files and directories recursively, for example:
+//
+// Trie Traversal order
+// ---- ---------------
+// .
+// / | \ c
+// / | \ d/
+// d c z ===> d/a
+// / \ d/b
+// b a z
+//
+//
+// This iterator is somewhat especial as you can chose to skip whole
+// "directories" when iterating:
+//
+// - The Step method will iterate normally.
+//
+// - the Next method will not descend deeper into the tree.
+//
+// For example, if the iterator is at `d/`, the Step method will return
+// `d/a` while the Next would have returned `z` instead (skipping `d/`
+// and its descendants). The name of the these two methods are based on
+// the well known "next" and "step" operations, quite common in
+// debuggers, like gdb.
+//
+// The paths returned by the iterator will be relative, if the iterator
+// was created from a single node, or absolute, if the iterator was
+// created from the path to the node (the path will be prefixed to all
+// returned paths).
+type Iter struct {
+ // Tells if the iteration has started.
+ hasStarted bool
+ // The top of this stack has the current node and its siblings. The
+ // rest of the stack keeps the ancestors of the current node and
+ // their corresponding siblings. The current element is always the
+ // top element of the top frame.
+ //
+ // When "step"ping into a node, its children are pushed as a new
+ // frame.
+ //
+ // When "next"ing pass a node, the current element is dropped by
+ // popping the top frame.
+ frameStack []*frame.Frame
+ // The base path used to turn the relative paths used internally by
+ // the iterator into absolute paths used by external applications.
+ // For relative iterator this will be nil.
+ base noder.Path
+}
+
+// NewIter returns a new relative iterator using the provider noder as
+// its unnamed root. When iterating, all returned paths will be
+// relative to node.
+func NewIter(n noder.Noder) (*Iter, error) {
+ return newIter(n, nil)
+}
+
+// NewIterFromPath returns a new absolute iterator from the noder at the
+// end of the path p. When iterating, all returned paths will be
+// absolute, using the root of the path p as their root.
+func NewIterFromPath(p noder.Path) (*Iter, error) {
+ return newIter(p, p) // Path implements Noder
+}
+
+func newIter(root noder.Noder, base noder.Path) (*Iter, error) {
+ ret := &Iter{
+ base: base,
+ }
+
+ if root == nil {
+ return ret, nil
+ }
+
+ frame, err := frame.New(root)
+ if err != nil {
+ return nil, err
+ }
+ ret.push(frame)
+
+ return ret, nil
+}
+
+func (iter *Iter) top() (*frame.Frame, bool) {
+ if len(iter.frameStack) == 0 {
+ return nil, false
+ }
+ top := len(iter.frameStack) - 1
+
+ return iter.frameStack[top], true
+}
+
+func (iter *Iter) push(f *frame.Frame) {
+ iter.frameStack = append(iter.frameStack, f)
+}
+
+const (
+ doDescend = true
+ dontDescend = false
+)
+
+// Next returns the path of the next node without descending deeper into
+// the trie and nil. If there are no more entries in the trie it
+// returns nil and io.EOF. In case of error, it will return nil and the
+// error.
+func (iter *Iter) Next() (noder.Path, error) {
+ return iter.advance(dontDescend)
+}
+
+// Step returns the path to the next node in the trie, descending deeper
+// into it if needed, and nil. If there are no more nodes in the trie,
+// it returns nil and io.EOF. In case of error, it will return nil and
+// the error.
+func (iter *Iter) Step() (noder.Path, error) {
+ return iter.advance(doDescend)
+}
+
+// Advances the iterator in the desired direction: descend or
+// dontDescend.
+//
+// Returns the new current element and a nil error on success. If there
+// are no more elements in the trie below the base, it returns nil, and
+// io.EOF. Returns nil and an error in case of errors.
+func (iter *Iter) advance(wantDescend bool) (noder.Path, error) {
+ current, err := iter.current()
+ if err != nil {
+ return nil, err
+ }
+
+ // The first time we just return the current node.
+ if !iter.hasStarted {
+ iter.hasStarted = true
+ return current, nil
+ }
+
+ // Advances means getting a next current node, either its first child or
+ // its next sibling, depending if we must descend or not.
+ numChildren, err := current.NumChildren()
+ if err != nil {
+ return nil, err
+ }
+
+ mustDescend := numChildren != 0 && wantDescend
+ if mustDescend {
+ // descend: add a new frame with the current's children.
+ frame, err := frame.New(current)
+ if err != nil {
+ return nil, err
+ }
+ iter.push(frame)
+ } else {
+ // don't descend: just drop the current node
+ iter.drop()
+ }
+
+ return iter.current()
+}
+
+// Returns the path to the current node, adding the base if there was
+// one, and a nil error. If there were no noders left, it returns nil
+// and io.EOF. If an error occurred, it returns nil and the error.
+func (iter *Iter) current() (noder.Path, error) {
+ if topFrame, ok := iter.top(); !ok {
+ return nil, io.EOF
+ } else if _, ok := topFrame.First(); !ok {
+ return nil, io.EOF
+ }
+
+ ret := make(noder.Path, 0, len(iter.base)+len(iter.frameStack))
+
+ // concat the base...
+ ret = append(ret, iter.base...)
+ // ... and the current node and all its ancestors
+ for i, f := range iter.frameStack {
+ t, ok := f.First()
+ if !ok {
+ panic(fmt.Sprintf("frame %d is empty", i))
+ }
+ ret = append(ret, t)
+ }
+
+ return ret, nil
+}
+
+// removes the current node if any, and all the frames that become empty as a
+// consequence of this action.
+func (iter *Iter) drop() {
+ frame, ok := iter.top()
+ if !ok {
+ return
+ }
+
+ frame.Drop()
+ // if the frame is empty, remove it and its parent, recursively
+ if frame.Len() == 0 {
+ top := len(iter.frameStack) - 1
+ iter.frameStack[top] = nil
+ iter.frameStack = iter.frameStack[:top]
+ iter.drop()
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/noder.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/noder.go
new file mode 100644
index 00000000..6d22b8c1
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/noder.go
@@ -0,0 +1,60 @@
+// Package noder provide an interface for defining nodes in a
+// merkletrie, their hashes and their paths (a noders and its
+// ancestors).
+//
+// The hasher interface is easy to implement naively by elements that
+// already have a hash, like git blobs and trees. More sophisticated
+// implementations can implement the Equal function in exotic ways
+// though: for instance, comparing the modification time of directories
+// in a filesystem.
+package noder
+
+import "fmt"
+
+// Hasher interface is implemented by types that can tell you
+// their hash.
+type Hasher interface {
+ Hash() []byte
+}
+
+// Equal functions take two hashers and return if they are equal.
+//
+// These functions are expected to be faster than reflect.Equal or
+// reflect.DeepEqual because they can compare just the hash of the
+// objects, instead of their contents, so they are expected to be O(1).
+type Equal func(a, b Hasher) bool
+
+// The Noder interface is implemented by the elements of a Merkle Trie.
+//
+// There are two types of elements in a Merkle Trie:
+//
+// - file-like nodes: they cannot have children.
+//
+// - directory-like nodes: they can have 0 or more children and their
+// hash is calculated by combining their children hashes.
+type Noder interface {
+ Hasher
+ fmt.Stringer // for testing purposes
+ // Name returns the name of an element (relative, not its full
+ // path).
+ Name() string
+ // IsDir returns true if the element is a directory-like node or
+ // false if it is a file-like node.
+ IsDir() bool
+ // Children returns the children of the element. Note that empty
+ // directory-like noders and file-like noders will both return
+ // NoChildren.
+ Children() ([]Noder, error)
+ // NumChildren returns the number of children this element has.
+ //
+ // This method is an optimization: the number of children is easily
+ // calculated as the length of the value returned by the Children
+ // method (above); yet, some implementations will be able to
+ // implement NumChildren in O(1) while Children is usually more
+ // complex.
+ NumChildren() (int, error)
+ Skip() bool
+}
+
+// NoChildren represents the children of a noder without children.
+var NoChildren = []Noder{}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/path.go b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/path.go
new file mode 100644
index 00000000..6c1d3633
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/merkletrie/noder/path.go
@@ -0,0 +1,98 @@
+package noder
+
+import (
+ "bytes"
+ "strings"
+)
+
+// Path values represent a noder and its ancestors. The root goes first
+// and the actual final noder the path is referring to will be the last.
+//
+// A path implements the Noder interface, redirecting all the interface
+// calls to its final noder.
+//
+// Paths build from an empty Noder slice are not valid paths and should
+// not be used.
+type Path []Noder
+
+func (p Path) Skip() bool {
+ if len(p) > 0 {
+ return p.Last().Skip()
+ }
+
+ return false
+}
+
+// String returns the full path of the final noder as a string, using
+// "/" as the separator.
+func (p Path) String() string {
+ var buf bytes.Buffer
+ sep := ""
+ for _, e := range p {
+ _, _ = buf.WriteString(sep)
+ sep = "/"
+ _, _ = buf.WriteString(e.Name())
+ }
+
+ return buf.String()
+}
+
+// Last returns the final noder in the path.
+func (p Path) Last() Noder {
+ return p[len(p)-1]
+}
+
+// Hash returns the hash of the final noder of the path.
+func (p Path) Hash() []byte {
+ return p.Last().Hash()
+}
+
+// Name returns the name of the final noder of the path.
+func (p Path) Name() string {
+ return p.Last().Name()
+}
+
+// IsDir returns if the final noder of the path is a directory-like
+// noder.
+func (p Path) IsDir() bool {
+ return p.Last().IsDir()
+}
+
+// Children returns the children of the final noder in the path.
+func (p Path) Children() ([]Noder, error) {
+ return p.Last().Children()
+}
+
+// NumChildren returns the number of children the final noder of the
+// path has.
+func (p Path) NumChildren() (int, error) {
+ return p.Last().NumChildren()
+}
+
+// Compare returns -1, 0 or 1 if the path p is smaller, equal or bigger
+// than other, in "directory order"; for example:
+//
+// "a" < "b"
+// "a/b/c/d/z" < "b"
+// "a/b/a" > "a/b"
+func (p Path) Compare(other Path) int {
+ i := 0
+ for {
+ switch {
+ case len(other) == len(p) && i == len(p):
+ return 0
+ case i == len(other):
+ return 1
+ case i == len(p):
+ return -1
+ default:
+ // We do *not* normalize Unicode here. CGit doesn't.
+ // https://github.com/src-d/go-git/issues/1057
+ cmp := strings.Compare(p[i].Name(), other[i].Name())
+ if cmp != 0 {
+ return cmp
+ }
+ }
+ i++
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/sync/bufio.go b/vendor/github.com/go-git/go-git/v5/utils/sync/bufio.go
new file mode 100644
index 00000000..5009ea80
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/sync/bufio.go
@@ -0,0 +1,29 @@
+package sync
+
+import (
+ "bufio"
+ "io"
+ "sync"
+)
+
+var bufioReader = sync.Pool{
+ New: func() interface{} {
+ return bufio.NewReader(nil)
+ },
+}
+
+// GetBufioReader returns a *bufio.Reader that is managed by a sync.Pool.
+// Returns a bufio.Reader that is resetted with reader and ready for use.
+//
+// After use, the *bufio.Reader should be put back into the sync.Pool
+// by calling PutBufioReader.
+func GetBufioReader(reader io.Reader) *bufio.Reader {
+ r := bufioReader.Get().(*bufio.Reader)
+ r.Reset(reader)
+ return r
+}
+
+// PutBufioReader puts reader back into its sync.Pool.
+func PutBufioReader(reader *bufio.Reader) {
+ bufioReader.Put(reader)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/sync/bytes.go b/vendor/github.com/go-git/go-git/v5/utils/sync/bytes.go
new file mode 100644
index 00000000..dd06fc0b
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/sync/bytes.go
@@ -0,0 +1,51 @@
+package sync
+
+import (
+ "bytes"
+ "sync"
+)
+
+var (
+ byteSlice = sync.Pool{
+ New: func() interface{} {
+ b := make([]byte, 16*1024)
+ return &b
+ },
+ }
+ bytesBuffer = sync.Pool{
+ New: func() interface{} {
+ return bytes.NewBuffer(nil)
+ },
+ }
+)
+
+// GetByteSlice returns a *[]byte that is managed by a sync.Pool.
+// The initial slice length will be 16384 (16kb).
+//
+// After use, the *[]byte should be put back into the sync.Pool
+// by calling PutByteSlice.
+func GetByteSlice() *[]byte {
+ buf := byteSlice.Get().(*[]byte)
+ return buf
+}
+
+// PutByteSlice puts buf back into its sync.Pool.
+func PutByteSlice(buf *[]byte) {
+ byteSlice.Put(buf)
+}
+
+// GetBytesBuffer returns a *bytes.Buffer that is managed by a sync.Pool.
+// Returns a buffer that is resetted and ready for use.
+//
+// After use, the *bytes.Buffer should be put back into the sync.Pool
+// by calling PutBytesBuffer.
+func GetBytesBuffer() *bytes.Buffer {
+ buf := bytesBuffer.Get().(*bytes.Buffer)
+ buf.Reset()
+ return buf
+}
+
+// PutBytesBuffer puts buf back into its sync.Pool.
+func PutBytesBuffer(buf *bytes.Buffer) {
+ bytesBuffer.Put(buf)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/sync/zlib.go b/vendor/github.com/go-git/go-git/v5/utils/sync/zlib.go
new file mode 100644
index 00000000..c6138859
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/sync/zlib.go
@@ -0,0 +1,74 @@
+package sync
+
+import (
+ "bytes"
+ "compress/zlib"
+ "io"
+ "sync"
+)
+
+var (
+ zlibInitBytes = []byte{0x78, 0x9c, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01}
+ zlibReader = sync.Pool{
+ New: func() interface{} {
+ r, _ := zlib.NewReader(bytes.NewReader(zlibInitBytes))
+ return ZLibReader{
+ Reader: r.(zlibReadCloser),
+ }
+ },
+ }
+ zlibWriter = sync.Pool{
+ New: func() interface{} {
+ return zlib.NewWriter(nil)
+ },
+ }
+)
+
+type zlibReadCloser interface {
+ io.ReadCloser
+ zlib.Resetter
+}
+
+type ZLibReader struct {
+ dict *[]byte
+ Reader zlibReadCloser
+}
+
+// GetZlibReader returns a ZLibReader that is managed by a sync.Pool.
+// Returns a ZLibReader that is resetted using a dictionary that is
+// also managed by a sync.Pool.
+//
+// After use, the ZLibReader should be put back into the sync.Pool
+// by calling PutZlibReader.
+func GetZlibReader(r io.Reader) (ZLibReader, error) {
+ z := zlibReader.Get().(ZLibReader)
+ z.dict = GetByteSlice()
+
+ err := z.Reader.Reset(r, *z.dict)
+
+ return z, err
+}
+
+// PutZlibReader puts z back into its sync.Pool, first closing the reader.
+// The Byte slice dictionary is also put back into its sync.Pool.
+func PutZlibReader(z ZLibReader) {
+ z.Reader.Close()
+ PutByteSlice(z.dict)
+ zlibReader.Put(z)
+}
+
+// GetZlibWriter returns a *zlib.Writer that is managed by a sync.Pool.
+// Returns a writer that is resetted with w and ready for use.
+//
+// After use, the *zlib.Writer should be put back into the sync.Pool
+// by calling PutZlibWriter.
+func GetZlibWriter(w io.Writer) *zlib.Writer {
+ z := zlibWriter.Get().(*zlib.Writer)
+ z.Reset(w)
+ return z
+}
+
+// PutZlibWriter puts w back into its sync.Pool.
+func PutZlibWriter(w *zlib.Writer) {
+ zlibWriter.Put(w)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/utils/trace/trace.go b/vendor/github.com/go-git/go-git/v5/utils/trace/trace.go
new file mode 100644
index 00000000..3e15c5b9
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/utils/trace/trace.go
@@ -0,0 +1,55 @@
+package trace
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "sync/atomic"
+)
+
+var (
+ // logger is the logger to use for tracing.
+ logger = newLogger()
+
+ // current is the targets that are enabled for tracing.
+ current atomic.Int32
+)
+
+func newLogger() *log.Logger {
+ return log.New(os.Stderr, "", log.Ltime|log.Lmicroseconds|log.Lshortfile)
+}
+
+// Target is a tracing target.
+type Target int32
+
+const (
+ // General traces general operations.
+ General Target = 1 << iota
+
+ // Packet traces git packets.
+ Packet
+)
+
+// SetTarget sets the tracing targets.
+func SetTarget(target Target) {
+ current.Store(int32(target))
+}
+
+// SetLogger sets the logger to use for tracing.
+func SetLogger(l *log.Logger) {
+ logger = l
+}
+
+// Print prints the given message only if the target is enabled.
+func (t Target) Print(args ...interface{}) {
+ if int32(t)¤t.Load() != 0 {
+ logger.Output(2, fmt.Sprint(args...)) // nolint: errcheck
+ }
+}
+
+// Printf prints the given message only if the target is enabled.
+func (t Target) Printf(format string, args ...interface{}) {
+ if int32(t)¤t.Load() != 0 {
+ logger.Output(2, fmt.Sprintf(format, args...)) // nolint: errcheck
+ }
+}
diff --git a/vendor/github.com/go-git/go-git/v5/worktree.go b/vendor/github.com/go-git/go-git/v5/worktree.go
new file mode 100644
index 00000000..ab11d42d
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree.go
@@ -0,0 +1,1126 @@
+package git
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/util"
+ "github.com/go-git/go-git/v5/config"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/plumbing/format/gitignore"
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+ "github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/plumbing/storer"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/merkletrie"
+ "github.com/go-git/go-git/v5/utils/sync"
+)
+
+var (
+ ErrWorktreeNotClean = errors.New("worktree is not clean")
+ ErrSubmoduleNotFound = errors.New("submodule not found")
+ ErrUnstagedChanges = errors.New("worktree contains unstaged changes")
+ ErrGitModulesSymlink = errors.New(gitmodulesFile + " is a symlink")
+ ErrNonFastForwardUpdate = errors.New("non-fast-forward update")
+)
+
+// Worktree represents a git worktree.
+type Worktree struct {
+ // Filesystem underlying filesystem.
+ Filesystem billy.Filesystem
+ // External excludes not found in the repository .gitignore
+ Excludes []gitignore.Pattern
+
+ r *Repository
+}
+
+// Pull incorporates changes from a remote repository into the current branch.
+// Returns nil if the operation is successful, NoErrAlreadyUpToDate if there are
+// no changes to be fetched, or an error.
+//
+// Pull only supports merges where the can be resolved as a fast-forward.
+func (w *Worktree) Pull(o *PullOptions) error {
+ return w.PullContext(context.Background(), o)
+}
+
+// PullContext incorporates changes from a remote repository into the current
+// branch. Returns nil if the operation is successful, NoErrAlreadyUpToDate if
+// there are no changes to be fetched, or an error.
+//
+// Pull only supports merges where the can be resolved as a fast-forward.
+//
+// The provided Context must be non-nil. If the context expires before the
+// operation is complete, an error is returned. The context only affects the
+// transport operations.
+func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error {
+ if err := o.Validate(); err != nil {
+ return err
+ }
+
+ remote, err := w.r.Remote(o.RemoteName)
+ if err != nil {
+ return err
+ }
+
+ fetchHead, err := remote.fetch(ctx, &FetchOptions{
+ RemoteName: o.RemoteName,
+ RemoteURL: o.RemoteURL,
+ Depth: o.Depth,
+ Auth: o.Auth,
+ Progress: o.Progress,
+ Force: o.Force,
+ InsecureSkipTLS: o.InsecureSkipTLS,
+ CABundle: o.CABundle,
+ ProxyOptions: o.ProxyOptions,
+ })
+
+ updated := true
+ if err == NoErrAlreadyUpToDate {
+ updated = false
+ } else if err != nil {
+ return err
+ }
+
+ ref, err := storer.ResolveReference(fetchHead, o.ReferenceName)
+ if err != nil {
+ return err
+ }
+
+ head, err := w.r.Head()
+ if err == nil {
+ // if we don't have a shallows list, just ignore it
+ shallowList, _ := w.r.Storer.Shallow()
+
+ var earliestShallow *plumbing.Hash
+ if len(shallowList) > 0 {
+ earliestShallow = &shallowList[0]
+ }
+
+ headAheadOfRef, err := isFastForward(w.r.Storer, ref.Hash(), head.Hash(), earliestShallow)
+ if err != nil {
+ return err
+ }
+
+ if !updated && headAheadOfRef {
+ return NoErrAlreadyUpToDate
+ }
+
+ ff, err := isFastForward(w.r.Storer, head.Hash(), ref.Hash(), earliestShallow)
+ if err != nil {
+ return err
+ }
+
+ if !ff {
+ return ErrNonFastForwardUpdate
+ }
+ }
+
+ if err != nil && err != plumbing.ErrReferenceNotFound {
+ return err
+ }
+
+ if err := w.updateHEAD(ref.Hash()); err != nil {
+ return err
+ }
+
+ if err := w.Reset(&ResetOptions{
+ Mode: MergeReset,
+ Commit: ref.Hash(),
+ }); err != nil {
+ return err
+ }
+
+ if o.RecurseSubmodules != NoRecurseSubmodules {
+ return w.updateSubmodules(&SubmoduleUpdateOptions{
+ RecurseSubmodules: o.RecurseSubmodules,
+ Auth: o.Auth,
+ })
+ }
+
+ return nil
+}
+
+func (w *Worktree) updateSubmodules(o *SubmoduleUpdateOptions) error {
+ s, err := w.Submodules()
+ if err != nil {
+ return err
+ }
+ o.Init = true
+ return s.Update(o)
+}
+
+// Checkout switch branches or restore working tree files.
+func (w *Worktree) Checkout(opts *CheckoutOptions) error {
+ if err := opts.Validate(); err != nil {
+ return err
+ }
+
+ if opts.Create {
+ if err := w.createBranch(opts); err != nil {
+ return err
+ }
+ }
+
+ c, err := w.getCommitFromCheckoutOptions(opts)
+ if err != nil {
+ return err
+ }
+
+ ro := &ResetOptions{Commit: c, Mode: MergeReset}
+ if opts.Force {
+ ro.Mode = HardReset
+ } else if opts.Keep {
+ ro.Mode = SoftReset
+ }
+
+ if !opts.Hash.IsZero() && !opts.Create {
+ err = w.setHEADToCommit(opts.Hash)
+ } else {
+ err = w.setHEADToBranch(opts.Branch, c)
+ }
+
+ if err != nil {
+ return err
+ }
+
+ if len(opts.SparseCheckoutDirectories) > 0 {
+ return w.ResetSparsely(ro, opts.SparseCheckoutDirectories)
+ }
+
+ return w.Reset(ro)
+}
+
+func (w *Worktree) createBranch(opts *CheckoutOptions) error {
+ if err := opts.Branch.Validate(); err != nil {
+ return err
+ }
+
+ _, err := w.r.Storer.Reference(opts.Branch)
+ if err == nil {
+ return fmt.Errorf("a branch named %q already exists", opts.Branch)
+ }
+
+ if err != plumbing.ErrReferenceNotFound {
+ return err
+ }
+
+ if opts.Hash.IsZero() {
+ ref, err := w.r.Head()
+ if err != nil {
+ return err
+ }
+
+ opts.Hash = ref.Hash()
+ }
+
+ return w.r.Storer.SetReference(
+ plumbing.NewHashReference(opts.Branch, opts.Hash),
+ )
+}
+
+func (w *Worktree) getCommitFromCheckoutOptions(opts *CheckoutOptions) (plumbing.Hash, error) {
+ hash := opts.Hash
+ if hash.IsZero() {
+ b, err := w.r.Reference(opts.Branch, true)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ hash = b.Hash()
+ }
+
+ o, err := w.r.Object(plumbing.AnyObject, hash)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ switch o := o.(type) {
+ case *object.Tag:
+ if o.TargetType != plumbing.CommitObject {
+ return plumbing.ZeroHash, fmt.Errorf("%w: tag target %q", object.ErrUnsupportedObject, o.TargetType)
+ }
+
+ return o.Target, nil
+ case *object.Commit:
+ return o.Hash, nil
+ }
+
+ return plumbing.ZeroHash, fmt.Errorf("%w: %q", object.ErrUnsupportedObject, o.Type())
+}
+
+func (w *Worktree) setHEADToCommit(commit plumbing.Hash) error {
+ head := plumbing.NewHashReference(plumbing.HEAD, commit)
+ return w.r.Storer.SetReference(head)
+}
+
+func (w *Worktree) setHEADToBranch(branch plumbing.ReferenceName, commit plumbing.Hash) error {
+ target, err := w.r.Storer.Reference(branch)
+ if err != nil {
+ return err
+ }
+
+ var head *plumbing.Reference
+ if target.Name().IsBranch() {
+ head = plumbing.NewSymbolicReference(plumbing.HEAD, target.Name())
+ } else {
+ head = plumbing.NewHashReference(plumbing.HEAD, commit)
+ }
+
+ return w.r.Storer.SetReference(head)
+}
+
+func (w *Worktree) ResetSparsely(opts *ResetOptions, dirs []string) error {
+ if err := opts.Validate(w.r); err != nil {
+ return err
+ }
+
+ if opts.Mode == MergeReset {
+ unstaged, err := w.containsUnstagedChanges()
+ if err != nil {
+ return err
+ }
+
+ if unstaged {
+ return ErrUnstagedChanges
+ }
+ }
+
+ if err := w.setHEADCommit(opts.Commit); err != nil {
+ return err
+ }
+
+ if opts.Mode == SoftReset {
+ return nil
+ }
+
+ t, err := w.r.getTreeFromCommitHash(opts.Commit)
+ if err != nil {
+ return err
+ }
+
+ if opts.Mode == MixedReset || opts.Mode == MergeReset || opts.Mode == HardReset {
+ if err := w.resetIndex(t, dirs); err != nil {
+ return err
+ }
+ }
+
+ if opts.Mode == MergeReset || opts.Mode == HardReset {
+ if err := w.resetWorktree(t); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Reset the worktree to a specified state.
+func (w *Worktree) Reset(opts *ResetOptions) error {
+ return w.ResetSparsely(opts, nil)
+}
+
+func (w *Worktree) resetIndex(t *object.Tree, dirs []string) error {
+ idx, err := w.r.Storer.Index()
+ if len(dirs) > 0 {
+ idx.SkipUnless(dirs)
+ }
+
+ if err != nil {
+ return err
+ }
+ b := newIndexBuilder(idx)
+
+ changes, err := w.diffTreeWithStaging(t, true)
+ if err != nil {
+ return err
+ }
+
+ for _, ch := range changes {
+ a, err := ch.Action()
+ if err != nil {
+ return err
+ }
+
+ var name string
+ var e *object.TreeEntry
+
+ switch a {
+ case merkletrie.Modify, merkletrie.Insert:
+ name = ch.To.String()
+ e, err = t.FindEntry(name)
+ if err != nil {
+ return err
+ }
+ case merkletrie.Delete:
+ name = ch.From.String()
+ }
+
+ b.Remove(name)
+ if e == nil {
+ continue
+ }
+
+ b.Add(&index.Entry{
+ Name: name,
+ Hash: e.Hash,
+ Mode: e.Mode,
+ })
+
+ }
+
+ b.Write(idx)
+ return w.r.Storer.SetIndex(idx)
+}
+
+func (w *Worktree) resetWorktree(t *object.Tree) error {
+ changes, err := w.diffStagingWithWorktree(true, false)
+ if err != nil {
+ return err
+ }
+
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return err
+ }
+ b := newIndexBuilder(idx)
+
+ for _, ch := range changes {
+ if err := w.validChange(ch); err != nil {
+ return err
+ }
+ if err := w.checkoutChange(ch, t, b); err != nil {
+ return err
+ }
+ }
+
+ b.Write(idx)
+ return w.r.Storer.SetIndex(idx)
+}
+
+// worktreeDeny is a list of paths that are not allowed
+// to be used when resetting the worktree.
+var worktreeDeny = map[string]struct{}{
+ // .git
+ GitDirName: {},
+
+ // For other historical reasons, file names that do not conform to the 8.3
+ // format (up to eight characters for the basename, three for the file
+ // extension, certain characters not allowed such as `+`, etc) are associated
+ // with a so-called "short name", at least on the `C:` drive by default.
+ // Which means that `git~1/` is a valid way to refer to `.git/`.
+ "git~1": {},
+}
+
+// validPath checks whether paths are valid.
+// The rules around invalid paths could differ from upstream based on how
+// filesystems are managed within go-git, but they are largely the same.
+//
+// For upstream rules:
+// https://github.com/git/git/blob/564d0252ca632e0264ed670534a51d18a689ef5d/read-cache.c#L946
+// https://github.com/git/git/blob/564d0252ca632e0264ed670534a51d18a689ef5d/path.c#L1383
+func validPath(paths ...string) error {
+ for _, p := range paths {
+ parts := strings.FieldsFunc(p, func(r rune) bool { return (r == '\\' || r == '/') })
+ if len(parts) == 0 {
+ return fmt.Errorf("invalid path: %q", p)
+ }
+
+ if _, denied := worktreeDeny[strings.ToLower(parts[0])]; denied {
+ return fmt.Errorf("invalid path prefix: %q", p)
+ }
+
+ if runtime.GOOS == "windows" {
+ // Volume names are not supported, in both formats: \\ and :.
+ if vol := filepath.VolumeName(p); vol != "" {
+ return fmt.Errorf("invalid path: %q", p)
+ }
+
+ if !windowsValidPath(parts[0]) {
+ return fmt.Errorf("invalid path: %q", p)
+ }
+ }
+
+ for _, part := range parts {
+ if part == ".." {
+ return fmt.Errorf("invalid path %q: cannot use '..'", p)
+ }
+ }
+ }
+ return nil
+}
+
+// windowsPathReplacer defines the chars that need to be replaced
+// as part of windowsValidPath.
+var windowsPathReplacer *strings.Replacer
+
+func init() {
+ windowsPathReplacer = strings.NewReplacer(" ", "", ".", "")
+}
+
+func windowsValidPath(part string) bool {
+ if len(part) > 3 && strings.EqualFold(part[:4], GitDirName) {
+ // For historical reasons, file names that end in spaces or periods are
+ // automatically trimmed. Therefore, `.git . . ./` is a valid way to refer
+ // to `.git/`.
+ if windowsPathReplacer.Replace(part[4:]) == "" {
+ return false
+ }
+
+ // For yet other historical reasons, NTFS supports so-called "Alternate Data
+ // Streams", i.e. metadata associated with a given file, referred to via
+ // `::`. There exists a default stream
+ // type for directories, allowing `.git/` to be accessed via
+ // `.git::$INDEX_ALLOCATION/`.
+ //
+ // For performance reasons, _all_ Alternate Data Streams of `.git/` are
+ // forbidden, not just `::$INDEX_ALLOCATION`.
+ if len(part) > 4 && part[4:5] == ":" {
+ return false
+ }
+ }
+ return true
+}
+
+func (w *Worktree) validChange(ch merkletrie.Change) error {
+ action, err := ch.Action()
+ if err != nil {
+ return nil
+ }
+
+ switch action {
+ case merkletrie.Delete:
+ return validPath(ch.From.String())
+ case merkletrie.Insert:
+ return validPath(ch.To.String())
+ case merkletrie.Modify:
+ return validPath(ch.From.String(), ch.To.String())
+ }
+
+ return nil
+}
+
+func (w *Worktree) checkoutChange(ch merkletrie.Change, t *object.Tree, idx *indexBuilder) error {
+ a, err := ch.Action()
+ if err != nil {
+ return err
+ }
+
+ var e *object.TreeEntry
+ var name string
+ var isSubmodule bool
+
+ switch a {
+ case merkletrie.Modify, merkletrie.Insert:
+ name = ch.To.String()
+ e, err = t.FindEntry(name)
+ if err != nil {
+ return err
+ }
+
+ isSubmodule = e.Mode == filemode.Submodule
+ case merkletrie.Delete:
+ return rmFileAndDirsIfEmpty(w.Filesystem, ch.From.String())
+ }
+
+ if isSubmodule {
+ return w.checkoutChangeSubmodule(name, a, e, idx)
+ }
+
+ return w.checkoutChangeRegularFile(name, a, t, e, idx)
+}
+
+func (w *Worktree) containsUnstagedChanges() (bool, error) {
+ ch, err := w.diffStagingWithWorktree(false, true)
+ if err != nil {
+ return false, err
+ }
+
+ for _, c := range ch {
+ a, err := c.Action()
+ if err != nil {
+ return false, err
+ }
+
+ if a == merkletrie.Insert {
+ continue
+ }
+
+ return true, nil
+ }
+
+ return false, nil
+}
+
+func (w *Worktree) setHEADCommit(commit plumbing.Hash) error {
+ head, err := w.r.Reference(plumbing.HEAD, false)
+ if err != nil {
+ return err
+ }
+
+ if head.Type() == plumbing.HashReference {
+ head = plumbing.NewHashReference(plumbing.HEAD, commit)
+ return w.r.Storer.SetReference(head)
+ }
+
+ branch, err := w.r.Reference(head.Target(), false)
+ if err != nil {
+ return err
+ }
+
+ if !branch.Name().IsBranch() {
+ return fmt.Errorf("invalid HEAD target should be a branch, found %s", branch.Type())
+ }
+
+ branch = plumbing.NewHashReference(branch.Name(), commit)
+ return w.r.Storer.SetReference(branch)
+}
+
+func (w *Worktree) checkoutChangeSubmodule(name string,
+ a merkletrie.Action,
+ e *object.TreeEntry,
+ idx *indexBuilder,
+) error {
+ switch a {
+ case merkletrie.Modify:
+ sub, err := w.Submodule(name)
+ if err != nil {
+ return err
+ }
+
+ if !sub.initialized {
+ return nil
+ }
+
+ return w.addIndexFromTreeEntry(name, e, idx)
+ case merkletrie.Insert:
+ mode, err := e.Mode.ToOSFileMode()
+ if err != nil {
+ return err
+ }
+
+ if err := w.Filesystem.MkdirAll(name, mode); err != nil {
+ return err
+ }
+
+ return w.addIndexFromTreeEntry(name, e, idx)
+ }
+
+ return nil
+}
+
+func (w *Worktree) checkoutChangeRegularFile(name string,
+ a merkletrie.Action,
+ t *object.Tree,
+ e *object.TreeEntry,
+ idx *indexBuilder,
+) error {
+ switch a {
+ case merkletrie.Modify:
+ idx.Remove(name)
+
+ // to apply perm changes the file is deleted, billy doesn't implement
+ // chmod
+ if err := w.Filesystem.Remove(name); err != nil {
+ return err
+ }
+
+ fallthrough
+ case merkletrie.Insert:
+ f, err := t.File(name)
+ if err != nil {
+ return err
+ }
+
+ if err := w.checkoutFile(f); err != nil {
+ return err
+ }
+
+ return w.addIndexFromFile(name, e.Hash, idx)
+ }
+
+ return nil
+}
+
+func (w *Worktree) checkoutFile(f *object.File) (err error) {
+ mode, err := f.Mode.ToOSFileMode()
+ if err != nil {
+ return
+ }
+
+ if mode&os.ModeSymlink != 0 {
+ return w.checkoutFileSymlink(f)
+ }
+
+ from, err := f.Reader()
+ if err != nil {
+ return
+ }
+
+ defer ioutil.CheckClose(from, &err)
+
+ to, err := w.Filesystem.OpenFile(f.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode.Perm())
+ if err != nil {
+ return
+ }
+
+ defer ioutil.CheckClose(to, &err)
+ buf := sync.GetByteSlice()
+ _, err = io.CopyBuffer(to, from, *buf)
+ sync.PutByteSlice(buf)
+ return
+}
+
+func (w *Worktree) checkoutFileSymlink(f *object.File) (err error) {
+ // https://github.com/git/git/commit/10ecfa76491e4923988337b2e2243b05376b40de
+ if strings.EqualFold(f.Name, gitmodulesFile) {
+ return ErrGitModulesSymlink
+ }
+
+ from, err := f.Reader()
+ if err != nil {
+ return
+ }
+
+ defer ioutil.CheckClose(from, &err)
+
+ bytes, err := io.ReadAll(from)
+ if err != nil {
+ return
+ }
+
+ err = w.Filesystem.Symlink(string(bytes), f.Name)
+
+ // On windows, this might fail.
+ // Follow Git on Windows behavior by writing the link as it is.
+ if err != nil && isSymlinkWindowsNonAdmin(err) {
+ mode, _ := f.Mode.ToOSFileMode()
+
+ to, err := w.Filesystem.OpenFile(f.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode.Perm())
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(to, &err)
+
+ _, err = to.Write(bytes)
+ return err
+ }
+ return
+}
+
+func (w *Worktree) addIndexFromTreeEntry(name string, f *object.TreeEntry, idx *indexBuilder) error {
+ idx.Remove(name)
+ idx.Add(&index.Entry{
+ Hash: f.Hash,
+ Name: name,
+ Mode: filemode.Submodule,
+ })
+ return nil
+}
+
+func (w *Worktree) addIndexFromFile(name string, h plumbing.Hash, idx *indexBuilder) error {
+ idx.Remove(name)
+ fi, err := w.Filesystem.Lstat(name)
+ if err != nil {
+ return err
+ }
+
+ mode, err := filemode.NewFromOSFileMode(fi.Mode())
+ if err != nil {
+ return err
+ }
+
+ e := &index.Entry{
+ Hash: h,
+ Name: name,
+ Mode: mode,
+ ModifiedAt: fi.ModTime(),
+ Size: uint32(fi.Size()),
+ }
+
+ // if the FileInfo.Sys() comes from os the ctime, dev, inode, uid and gid
+ // can be retrieved, otherwise this doesn't apply
+ if fillSystemInfo != nil {
+ fillSystemInfo(e, fi.Sys())
+ }
+ idx.Add(e)
+ return nil
+}
+
+func (r *Repository) getTreeFromCommitHash(commit plumbing.Hash) (*object.Tree, error) {
+ c, err := r.CommitObject(commit)
+ if err != nil {
+ return nil, err
+ }
+
+ return c.Tree()
+}
+
+var fillSystemInfo func(e *index.Entry, sys interface{})
+
+const gitmodulesFile = ".gitmodules"
+
+// Submodule returns the submodule with the given name
+func (w *Worktree) Submodule(name string) (*Submodule, error) {
+ l, err := w.Submodules()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, m := range l {
+ if m.Config().Name == name {
+ return m, nil
+ }
+ }
+
+ return nil, ErrSubmoduleNotFound
+}
+
+// Submodules returns all the available submodules
+func (w *Worktree) Submodules() (Submodules, error) {
+ l := make(Submodules, 0)
+ m, err := w.readGitmodulesFile()
+ if err != nil || m == nil {
+ return l, err
+ }
+
+ c, err := w.r.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, s := range m.Submodules {
+ l = append(l, w.newSubmodule(s, c.Submodules[s.Name]))
+ }
+
+ return l, nil
+}
+
+func (w *Worktree) newSubmodule(fromModules, fromConfig *config.Submodule) *Submodule {
+ m := &Submodule{w: w}
+ m.initialized = fromConfig != nil
+
+ if !m.initialized {
+ m.c = fromModules
+ return m
+ }
+
+ m.c = fromConfig
+ m.c.Path = fromModules.Path
+ return m
+}
+
+func (w *Worktree) isSymlink(path string) bool {
+ if s, err := w.Filesystem.Lstat(path); err == nil {
+ return s.Mode()&os.ModeSymlink != 0
+ }
+ return false
+}
+
+func (w *Worktree) readGitmodulesFile() (*config.Modules, error) {
+ if w.isSymlink(gitmodulesFile) {
+ return nil, ErrGitModulesSymlink
+ }
+
+ f, err := w.Filesystem.Open(gitmodulesFile)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil, nil
+ }
+
+ return nil, err
+ }
+
+ defer f.Close()
+ input, err := io.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+
+ m := config.NewModules()
+ if err := m.Unmarshal(input); err != nil {
+ return m, err
+ }
+
+ return m, nil
+}
+
+// Clean the worktree by removing untracked files.
+// An empty dir could be removed - this is what `git clean -f -d .` does.
+func (w *Worktree) Clean(opts *CleanOptions) error {
+ s, err := w.Status()
+ if err != nil {
+ return err
+ }
+
+ root := ""
+ files, err := w.Filesystem.ReadDir(root)
+ if err != nil {
+ return err
+ }
+ return w.doClean(s, opts, root, files)
+}
+
+func (w *Worktree) doClean(status Status, opts *CleanOptions, dir string, files []os.FileInfo) error {
+ for _, fi := range files {
+ if fi.Name() == GitDirName {
+ continue
+ }
+
+ // relative path under the root
+ path := filepath.Join(dir, fi.Name())
+ if fi.IsDir() {
+ if !opts.Dir {
+ continue
+ }
+
+ subfiles, err := w.Filesystem.ReadDir(path)
+ if err != nil {
+ return err
+ }
+ err = w.doClean(status, opts, path, subfiles)
+ if err != nil {
+ return err
+ }
+ } else {
+ if status.IsUntracked(path) {
+ if err := w.Filesystem.Remove(path); err != nil {
+ return err
+ }
+ }
+ }
+ }
+
+ if opts.Dir && dir != "" {
+ _, err := removeDirIfEmpty(w.Filesystem, dir)
+ return err
+ }
+
+ return nil
+}
+
+// GrepResult is structure of a grep result.
+type GrepResult struct {
+ // FileName is the name of file which contains match.
+ FileName string
+ // LineNumber is the line number of a file at which a match was found.
+ LineNumber int
+ // Content is the content of the file at the matching line.
+ Content string
+ // TreeName is the name of the tree (reference name/commit hash) at
+ // which the match was performed.
+ TreeName string
+}
+
+func (gr GrepResult) String() string {
+ return fmt.Sprintf("%s:%s:%d:%s", gr.TreeName, gr.FileName, gr.LineNumber, gr.Content)
+}
+
+// Grep performs grep on a repository.
+func (r *Repository) Grep(opts *GrepOptions) ([]GrepResult, error) {
+ if err := opts.validate(r); err != nil {
+ return nil, err
+ }
+
+ // Obtain commit hash from options (CommitHash or ReferenceName).
+ var commitHash plumbing.Hash
+ // treeName contains the value of TreeName in GrepResult.
+ var treeName string
+
+ if opts.ReferenceName != "" {
+ ref, err := r.Reference(opts.ReferenceName, true)
+ if err != nil {
+ return nil, err
+ }
+ commitHash = ref.Hash()
+ treeName = opts.ReferenceName.String()
+ } else if !opts.CommitHash.IsZero() {
+ commitHash = opts.CommitHash
+ treeName = opts.CommitHash.String()
+ }
+
+ // Obtain a tree from the commit hash and get a tracked files iterator from
+ // the tree.
+ tree, err := r.getTreeFromCommitHash(commitHash)
+ if err != nil {
+ return nil, err
+ }
+ fileiter := tree.Files()
+
+ return findMatchInFiles(fileiter, treeName, opts)
+}
+
+// Grep performs grep on a worktree.
+func (w *Worktree) Grep(opts *GrepOptions) ([]GrepResult, error) {
+ return w.r.Grep(opts)
+}
+
+// findMatchInFiles takes a FileIter, worktree name and GrepOptions, and
+// returns a slice of GrepResult containing the result of regex pattern matching
+// in content of all the files.
+func findMatchInFiles(fileiter *object.FileIter, treeName string, opts *GrepOptions) ([]GrepResult, error) {
+ var results []GrepResult
+
+ err := fileiter.ForEach(func(file *object.File) error {
+ var fileInPathSpec bool
+
+ // When no pathspecs are provided, search all the files.
+ if len(opts.PathSpecs) == 0 {
+ fileInPathSpec = true
+ }
+
+ // Check if the file name matches with the pathspec. Break out of the
+ // loop once a match is found.
+ for _, pathSpec := range opts.PathSpecs {
+ if pathSpec != nil && pathSpec.MatchString(file.Name) {
+ fileInPathSpec = true
+ break
+ }
+ }
+
+ // If the file does not match with any of the pathspec, skip it.
+ if !fileInPathSpec {
+ return nil
+ }
+
+ grepResults, err := findMatchInFile(file, treeName, opts)
+ if err != nil {
+ return err
+ }
+ results = append(results, grepResults...)
+
+ return nil
+ })
+
+ return results, err
+}
+
+// findMatchInFile takes a single File, worktree name and GrepOptions,
+// and returns a slice of GrepResult containing the result of regex pattern
+// matching in the given file.
+func findMatchInFile(file *object.File, treeName string, opts *GrepOptions) ([]GrepResult, error) {
+ var grepResults []GrepResult
+
+ content, err := file.Contents()
+ if err != nil {
+ return grepResults, err
+ }
+
+ // Split the file content and parse line-by-line.
+ contentByLine := strings.Split(content, "\n")
+ for lineNum, cnt := range contentByLine {
+ addToResult := false
+
+ // Match the patterns and content. Break out of the loop once a
+ // match is found.
+ for _, pattern := range opts.Patterns {
+ if pattern != nil && pattern.MatchString(cnt) {
+ // Add to result only if invert match is not enabled.
+ if !opts.InvertMatch {
+ addToResult = true
+ break
+ }
+ } else if opts.InvertMatch {
+ // If matching fails, and invert match is enabled, add to
+ // results.
+ addToResult = true
+ break
+ }
+ }
+
+ if addToResult {
+ grepResults = append(grepResults, GrepResult{
+ FileName: file.Name,
+ LineNumber: lineNum + 1,
+ Content: cnt,
+ TreeName: treeName,
+ })
+ }
+ }
+
+ return grepResults, nil
+}
+
+// will walk up the directory tree removing all encountered empty
+// directories, not just the one containing this file
+func rmFileAndDirsIfEmpty(fs billy.Filesystem, name string) error {
+ if err := util.RemoveAll(fs, name); err != nil {
+ return err
+ }
+
+ dir := filepath.Dir(name)
+ for {
+ removed, err := removeDirIfEmpty(fs, dir)
+ if err != nil {
+ return err
+ }
+
+ if !removed {
+ // directory was not empty and not removed,
+ // stop checking parents
+ break
+ }
+
+ // move to parent directory
+ dir = filepath.Dir(dir)
+ }
+
+ return nil
+}
+
+// removeDirIfEmpty will remove the supplied directory `dir` if
+// `dir` is empty
+// returns true if the directory was removed
+func removeDirIfEmpty(fs billy.Filesystem, dir string) (bool, error) {
+ files, err := fs.ReadDir(dir)
+ if err != nil {
+ return false, err
+ }
+
+ if len(files) > 0 {
+ return false, nil
+ }
+
+ err = fs.Remove(dir)
+ if err != nil {
+ return false, err
+ }
+
+ return true, nil
+}
+
+type indexBuilder struct {
+ entries map[string]*index.Entry
+}
+
+func newIndexBuilder(idx *index.Index) *indexBuilder {
+ entries := make(map[string]*index.Entry, len(idx.Entries))
+ for _, e := range idx.Entries {
+ entries[e.Name] = e
+ }
+ return &indexBuilder{
+ entries: entries,
+ }
+}
+
+func (b *indexBuilder) Write(idx *index.Index) {
+ idx.Entries = idx.Entries[:0]
+ for _, e := range b.entries {
+ idx.Entries = append(idx.Entries, e)
+ }
+}
+
+func (b *indexBuilder) Add(e *index.Entry) {
+ b.entries[e.Name] = e
+}
+
+func (b *indexBuilder) Remove(name string) {
+ delete(b.entries, filepath.ToSlash(name))
+}
diff --git a/vendor/github.com/go-git/go-git/v5/worktree_bsd.go b/vendor/github.com/go-git/go-git/v5/worktree_bsd.go
new file mode 100644
index 00000000..d4682eb8
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree_bsd.go
@@ -0,0 +1,26 @@
+// +build darwin freebsd netbsd
+
+package git
+
+import (
+ "syscall"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+)
+
+func init() {
+ fillSystemInfo = func(e *index.Entry, sys interface{}) {
+ if os, ok := sys.(*syscall.Stat_t); ok {
+ e.CreatedAt = time.Unix(os.Atimespec.Unix())
+ e.Dev = uint32(os.Dev)
+ e.Inode = uint32(os.Ino)
+ e.GID = os.Gid
+ e.UID = os.Uid
+ }
+ }
+}
+
+func isSymlinkWindowsNonAdmin(err error) bool {
+ return false
+}
diff --git a/vendor/github.com/go-git/go-git/v5/worktree_commit.go b/vendor/github.com/go-git/go-git/v5/worktree_commit.go
new file mode 100644
index 00000000..f62054bc
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree_commit.go
@@ -0,0 +1,271 @@
+package git
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "path"
+ "sort"
+ "strings"
+
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+ "github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/storage"
+
+ "github.com/ProtonMail/go-crypto/openpgp"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+ "github.com/go-git/go-billy/v5"
+)
+
+var (
+ // ErrEmptyCommit occurs when a commit is attempted using a clean
+ // working tree, with no changes to be committed.
+ ErrEmptyCommit = errors.New("cannot create empty commit: clean working tree")
+)
+
+// Commit stores the current contents of the index in a new commit along with
+// a log message from the user describing the changes.
+func (w *Worktree) Commit(msg string, opts *CommitOptions) (plumbing.Hash, error) {
+ if err := opts.Validate(w.r); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ if opts.All {
+ if err := w.autoAddModifiedAndDeleted(); err != nil {
+ return plumbing.ZeroHash, err
+ }
+ }
+
+ var treeHash plumbing.Hash
+
+ if opts.Amend {
+ head, err := w.r.Head()
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+ headCommit, err := w.r.CommitObject(head.Hash())
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ opts.Parents = nil
+ if len(headCommit.ParentHashes) != 0 {
+ opts.Parents = []plumbing.Hash{headCommit.ParentHashes[0]}
+ }
+ }
+
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ h := &buildTreeHelper{
+ fs: w.Filesystem,
+ s: w.r.Storer,
+ }
+
+ treeHash, err = h.BuildTree(idx, opts)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ commit, err := w.buildCommitObject(msg, opts, treeHash)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return commit, w.updateHEAD(commit)
+}
+
+func (w *Worktree) autoAddModifiedAndDeleted() error {
+ s, err := w.Status()
+ if err != nil {
+ return err
+ }
+
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return err
+ }
+
+ for path, fs := range s {
+ if fs.Worktree != Modified && fs.Worktree != Deleted {
+ continue
+ }
+
+ if _, _, err := w.doAddFile(idx, s, path, nil); err != nil {
+ return err
+ }
+
+ }
+
+ return w.r.Storer.SetIndex(idx)
+}
+
+func (w *Worktree) updateHEAD(commit plumbing.Hash) error {
+ head, err := w.r.Storer.Reference(plumbing.HEAD)
+ if err != nil {
+ return err
+ }
+
+ name := plumbing.HEAD
+ if head.Type() != plumbing.HashReference {
+ name = head.Target()
+ }
+
+ ref := plumbing.NewHashReference(name, commit)
+ return w.r.Storer.SetReference(ref)
+}
+
+func (w *Worktree) buildCommitObject(msg string, opts *CommitOptions, tree plumbing.Hash) (plumbing.Hash, error) {
+ commit := &object.Commit{
+ Author: *opts.Author,
+ Committer: *opts.Committer,
+ Message: msg,
+ TreeHash: tree,
+ ParentHashes: opts.Parents,
+ }
+
+ // Convert SignKey into a Signer if set. Existing Signer should take priority.
+ signer := opts.Signer
+ if signer == nil && opts.SignKey != nil {
+ signer = &gpgSigner{key: opts.SignKey}
+ }
+ if signer != nil {
+ sig, err := signObject(signer, commit)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+ commit.PGPSignature = string(sig)
+ }
+
+ obj := w.r.Storer.NewEncodedObject()
+ if err := commit.Encode(obj); err != nil {
+ return plumbing.ZeroHash, err
+ }
+ return w.r.Storer.SetEncodedObject(obj)
+}
+
+type gpgSigner struct {
+ key *openpgp.Entity
+ cfg *packet.Config
+}
+
+func (s *gpgSigner) Sign(message io.Reader) ([]byte, error) {
+ var b bytes.Buffer
+ if err := openpgp.ArmoredDetachSign(&b, s.key, message, s.cfg); err != nil {
+ return nil, err
+ }
+ return b.Bytes(), nil
+}
+
+// buildTreeHelper converts a given index.Index file into multiple git objects
+// reading the blobs from the given filesystem and creating the trees from the
+// index structure. The created objects are pushed to a given Storer.
+type buildTreeHelper struct {
+ fs billy.Filesystem
+ s storage.Storer
+
+ trees map[string]*object.Tree
+ entries map[string]*object.TreeEntry
+}
+
+// BuildTree builds the tree objects and push its to the storer, the hash
+// of the root tree is returned.
+func (h *buildTreeHelper) BuildTree(idx *index.Index, opts *CommitOptions) (plumbing.Hash, error) {
+ if len(idx.Entries) == 0 && (opts == nil || !opts.AllowEmptyCommits) {
+ return plumbing.ZeroHash, ErrEmptyCommit
+ }
+
+ const rootNode = ""
+ h.trees = map[string]*object.Tree{rootNode: {}}
+ h.entries = map[string]*object.TreeEntry{}
+
+ for _, e := range idx.Entries {
+ if err := h.commitIndexEntry(e); err != nil {
+ return plumbing.ZeroHash, err
+ }
+ }
+
+ return h.copyTreeToStorageRecursive(rootNode, h.trees[rootNode])
+}
+
+func (h *buildTreeHelper) commitIndexEntry(e *index.Entry) error {
+ parts := strings.Split(e.Name, "/")
+
+ var fullpath string
+ for _, part := range parts {
+ parent := fullpath
+ fullpath = path.Join(fullpath, part)
+
+ h.doBuildTree(e, parent, fullpath)
+ }
+
+ return nil
+}
+
+func (h *buildTreeHelper) doBuildTree(e *index.Entry, parent, fullpath string) {
+ if _, ok := h.trees[fullpath]; ok {
+ return
+ }
+
+ if _, ok := h.entries[fullpath]; ok {
+ return
+ }
+
+ te := object.TreeEntry{Name: path.Base(fullpath)}
+
+ if fullpath == e.Name {
+ te.Mode = e.Mode
+ te.Hash = e.Hash
+ } else {
+ te.Mode = filemode.Dir
+ h.trees[fullpath] = &object.Tree{}
+ }
+
+ h.trees[parent].Entries = append(h.trees[parent].Entries, te)
+}
+
+type sortableEntries []object.TreeEntry
+
+func (sortableEntries) sortName(te object.TreeEntry) string {
+ if te.Mode == filemode.Dir {
+ return te.Name + "/"
+ }
+ return te.Name
+}
+func (se sortableEntries) Len() int { return len(se) }
+func (se sortableEntries) Less(i int, j int) bool { return se.sortName(se[i]) < se.sortName(se[j]) }
+func (se sortableEntries) Swap(i int, j int) { se[i], se[j] = se[j], se[i] }
+
+func (h *buildTreeHelper) copyTreeToStorageRecursive(parent string, t *object.Tree) (plumbing.Hash, error) {
+ sort.Sort(sortableEntries(t.Entries))
+ for i, e := range t.Entries {
+ if e.Mode != filemode.Dir && !e.Hash.IsZero() {
+ continue
+ }
+
+ path := path.Join(parent, e.Name)
+
+ var err error
+ e.Hash, err = h.copyTreeToStorageRecursive(path, h.trees[path])
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ t.Entries[i] = e
+ }
+
+ o := h.s.NewEncodedObject()
+ if err := t.Encode(o); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ hash := o.Hash()
+ if h.s.HasEncodedObject(hash) == nil {
+ return hash, nil
+ }
+ return h.s.SetEncodedObject(o)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/worktree_js.go b/vendor/github.com/go-git/go-git/v5/worktree_js.go
new file mode 100644
index 00000000..7267d055
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree_js.go
@@ -0,0 +1,26 @@
+// +build js
+
+package git
+
+import (
+ "syscall"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+)
+
+func init() {
+ fillSystemInfo = func(e *index.Entry, sys interface{}) {
+ if os, ok := sys.(*syscall.Stat_t); ok {
+ e.CreatedAt = time.Unix(int64(os.Ctime), int64(os.CtimeNsec))
+ e.Dev = uint32(os.Dev)
+ e.Inode = uint32(os.Ino)
+ e.GID = os.Gid
+ e.UID = os.Uid
+ }
+ }
+}
+
+func isSymlinkWindowsNonAdmin(err error) bool {
+ return false
+}
diff --git a/vendor/github.com/go-git/go-git/v5/worktree_linux.go b/vendor/github.com/go-git/go-git/v5/worktree_linux.go
new file mode 100644
index 00000000..6fcace2f
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree_linux.go
@@ -0,0 +1,26 @@
+// +build linux
+
+package git
+
+import (
+ "syscall"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+)
+
+func init() {
+ fillSystemInfo = func(e *index.Entry, sys interface{}) {
+ if os, ok := sys.(*syscall.Stat_t); ok {
+ e.CreatedAt = time.Unix(os.Ctim.Unix())
+ e.Dev = uint32(os.Dev)
+ e.Inode = uint32(os.Ino)
+ e.GID = os.Gid
+ e.UID = os.Uid
+ }
+ }
+}
+
+func isSymlinkWindowsNonAdmin(err error) bool {
+ return false
+}
diff --git a/vendor/github.com/go-git/go-git/v5/worktree_plan9.go b/vendor/github.com/go-git/go-git/v5/worktree_plan9.go
new file mode 100644
index 00000000..8cedf71a
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree_plan9.go
@@ -0,0 +1,31 @@
+package git
+
+import (
+ "syscall"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+)
+
+func init() {
+ fillSystemInfo = func(e *index.Entry, sys interface{}) {
+ if os, ok := sys.(*syscall.Dir); ok {
+ // Plan 9 doesn't have a CreatedAt field.
+ e.CreatedAt = time.Unix(int64(os.Mtime), 0)
+
+ e.Dev = uint32(os.Dev)
+
+ // Plan 9 has no Inode.
+ // ext2srv(4) appears to store Inode in Qid.Path.
+ e.Inode = uint32(os.Qid.Path)
+
+ // Plan 9 has string UID/GID
+ e.GID = 0
+ e.UID = 0
+ }
+ }
+}
+
+func isSymlinkWindowsNonAdmin(err error) bool {
+ return true
+}
diff --git a/vendor/github.com/go-git/go-git/v5/worktree_status.go b/vendor/github.com/go-git/go-git/v5/worktree_status.go
new file mode 100644
index 00000000..dd9b2439
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree_status.go
@@ -0,0 +1,713 @@
+package git
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+
+ "github.com/go-git/go-billy/v5/util"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/filemode"
+ "github.com/go-git/go-git/v5/plumbing/format/gitignore"
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+ "github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/go-git/go-git/v5/utils/merkletrie"
+ "github.com/go-git/go-git/v5/utils/merkletrie/filesystem"
+ mindex "github.com/go-git/go-git/v5/utils/merkletrie/index"
+ "github.com/go-git/go-git/v5/utils/merkletrie/noder"
+)
+
+var (
+ // ErrDestinationExists in an Move operation means that the target exists on
+ // the worktree.
+ ErrDestinationExists = errors.New("destination exists")
+ // ErrGlobNoMatches in an AddGlob if the glob pattern does not match any
+ // files in the worktree.
+ ErrGlobNoMatches = errors.New("glob pattern did not match any files")
+)
+
+// Status returns the working tree status.
+func (w *Worktree) Status() (Status, error) {
+ var hash plumbing.Hash
+
+ ref, err := w.r.Head()
+ if err != nil && err != plumbing.ErrReferenceNotFound {
+ return nil, err
+ }
+
+ if err == nil {
+ hash = ref.Hash()
+ }
+
+ return w.status(hash)
+}
+
+func (w *Worktree) status(commit plumbing.Hash) (Status, error) {
+ s := make(Status)
+
+ left, err := w.diffCommitWithStaging(commit, false)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, ch := range left {
+ a, err := ch.Action()
+ if err != nil {
+ return nil, err
+ }
+
+ fs := s.File(nameFromAction(&ch))
+ fs.Worktree = Unmodified
+
+ switch a {
+ case merkletrie.Delete:
+ s.File(ch.From.String()).Staging = Deleted
+ case merkletrie.Insert:
+ s.File(ch.To.String()).Staging = Added
+ case merkletrie.Modify:
+ s.File(ch.To.String()).Staging = Modified
+ }
+ }
+
+ right, err := w.diffStagingWithWorktree(false, true)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, ch := range right {
+ a, err := ch.Action()
+ if err != nil {
+ return nil, err
+ }
+
+ fs := s.File(nameFromAction(&ch))
+ if fs.Staging == Untracked {
+ fs.Staging = Unmodified
+ }
+
+ switch a {
+ case merkletrie.Delete:
+ fs.Worktree = Deleted
+ case merkletrie.Insert:
+ fs.Worktree = Untracked
+ fs.Staging = Untracked
+ case merkletrie.Modify:
+ fs.Worktree = Modified
+ }
+ }
+
+ return s, nil
+}
+
+func nameFromAction(ch *merkletrie.Change) string {
+ name := ch.To.String()
+ if name == "" {
+ return ch.From.String()
+ }
+
+ return name
+}
+
+func (w *Worktree) diffStagingWithWorktree(reverse, excludeIgnoredChanges bool) (merkletrie.Changes, error) {
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return nil, err
+ }
+
+ from := mindex.NewRootNode(idx)
+ submodules, err := w.getSubmodulesStatus()
+ if err != nil {
+ return nil, err
+ }
+
+ to := filesystem.NewRootNode(w.Filesystem, submodules)
+
+ var c merkletrie.Changes
+ if reverse {
+ c, err = merkletrie.DiffTree(to, from, diffTreeIsEquals)
+ } else {
+ c, err = merkletrie.DiffTree(from, to, diffTreeIsEquals)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if excludeIgnoredChanges {
+ return w.excludeIgnoredChanges(c), nil
+ }
+ return c, nil
+}
+
+func (w *Worktree) excludeIgnoredChanges(changes merkletrie.Changes) merkletrie.Changes {
+ patterns, err := gitignore.ReadPatterns(w.Filesystem, nil)
+ if err != nil {
+ return changes
+ }
+
+ patterns = append(patterns, w.Excludes...)
+
+ if len(patterns) == 0 {
+ return changes
+ }
+
+ m := gitignore.NewMatcher(patterns)
+
+ var res merkletrie.Changes
+ for _, ch := range changes {
+ var path []string
+ for _, n := range ch.To {
+ path = append(path, n.Name())
+ }
+ if len(path) == 0 {
+ for _, n := range ch.From {
+ path = append(path, n.Name())
+ }
+ }
+ if len(path) != 0 {
+ isDir := (len(ch.To) > 0 && ch.To.IsDir()) || (len(ch.From) > 0 && ch.From.IsDir())
+ if m.Match(path, isDir) {
+ if len(ch.From) == 0 {
+ continue
+ }
+ }
+ }
+ res = append(res, ch)
+ }
+ return res
+}
+
+func (w *Worktree) getSubmodulesStatus() (map[string]plumbing.Hash, error) {
+ o := map[string]plumbing.Hash{}
+
+ sub, err := w.Submodules()
+ if err != nil {
+ return nil, err
+ }
+
+ status, err := sub.Status()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, s := range status {
+ if s.Current.IsZero() {
+ o[s.Path] = s.Expected
+ continue
+ }
+
+ o[s.Path] = s.Current
+ }
+
+ return o, nil
+}
+
+func (w *Worktree) diffCommitWithStaging(commit plumbing.Hash, reverse bool) (merkletrie.Changes, error) {
+ var t *object.Tree
+ if !commit.IsZero() {
+ c, err := w.r.CommitObject(commit)
+ if err != nil {
+ return nil, err
+ }
+
+ t, err = c.Tree()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return w.diffTreeWithStaging(t, reverse)
+}
+
+func (w *Worktree) diffTreeWithStaging(t *object.Tree, reverse bool) (merkletrie.Changes, error) {
+ var from noder.Noder
+ if t != nil {
+ from = object.NewTreeRootNode(t)
+ }
+
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return nil, err
+ }
+
+ to := mindex.NewRootNode(idx)
+
+ if reverse {
+ return merkletrie.DiffTree(to, from, diffTreeIsEquals)
+ }
+
+ return merkletrie.DiffTree(from, to, diffTreeIsEquals)
+}
+
+var emptyNoderHash = make([]byte, 24)
+
+// diffTreeIsEquals is a implementation of noder.Equals, used to compare
+// noder.Noder, it compare the content and the length of the hashes.
+//
+// Since some of the noder.Noder implementations doesn't compute a hash for
+// some directories, if any of the hashes is a 24-byte slice of zero values
+// the comparison is not done and the hashes are take as different.
+func diffTreeIsEquals(a, b noder.Hasher) bool {
+ hashA := a.Hash()
+ hashB := b.Hash()
+
+ if bytes.Equal(hashA, emptyNoderHash) || bytes.Equal(hashB, emptyNoderHash) {
+ return false
+ }
+
+ return bytes.Equal(hashA, hashB)
+}
+
+// Add adds the file contents of a file in the worktree to the index. if the
+// file is already staged in the index no error is returned. If a file deleted
+// from the Workspace is given, the file is removed from the index. If a
+// directory given, adds the files and all his sub-directories recursively in
+// the worktree to the index. If any of the files is already staged in the index
+// no error is returned. When path is a file, the blob.Hash is returned.
+func (w *Worktree) Add(path string) (plumbing.Hash, error) {
+ // TODO(mcuadros): deprecate in favor of AddWithOption in v6.
+ return w.doAdd(path, make([]gitignore.Pattern, 0), false)
+}
+
+func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string, ignorePattern []gitignore.Pattern) (added bool, err error) {
+ if len(ignorePattern) > 0 {
+ m := gitignore.NewMatcher(ignorePattern)
+ matchPath := strings.Split(directory, string(os.PathSeparator))
+ if m.Match(matchPath, true) {
+ // ignore
+ return false, nil
+ }
+ }
+
+ directory = filepath.ToSlash(filepath.Clean(directory))
+
+ for name := range s {
+ if !isPathInDirectory(name, directory) {
+ continue
+ }
+
+ var a bool
+ a, _, err = w.doAddFile(idx, s, name, ignorePattern)
+ if err != nil {
+ return
+ }
+
+ added = added || a
+ }
+
+ return
+}
+
+func isPathInDirectory(path, directory string) bool {
+ return directory == "." || strings.HasPrefix(path, directory+"/")
+}
+
+// AddWithOptions file contents to the index, updates the index using the
+// current content found in the working tree, to prepare the content staged for
+// the next commit.
+//
+// It typically adds the current content of existing paths as a whole, but with
+// some options it can also be used to add content with only part of the changes
+// made to the working tree files applied, or remove paths that do not exist in
+// the working tree anymore.
+func (w *Worktree) AddWithOptions(opts *AddOptions) error {
+ if err := opts.Validate(w.r); err != nil {
+ return err
+ }
+
+ if opts.All {
+ _, err := w.doAdd(".", w.Excludes, false)
+ return err
+ }
+
+ if opts.Glob != "" {
+ return w.AddGlob(opts.Glob)
+ }
+
+ _, err := w.doAdd(opts.Path, make([]gitignore.Pattern, 0), opts.SkipStatus)
+ return err
+}
+
+func (w *Worktree) doAdd(path string, ignorePattern []gitignore.Pattern, skipStatus bool) (plumbing.Hash, error) {
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ var h plumbing.Hash
+ var added bool
+
+ fi, err := w.Filesystem.Lstat(path)
+
+ // status is required for doAddDirectory
+ var s Status
+ var err2 error
+ if !skipStatus || fi == nil || fi.IsDir() {
+ s, err2 = w.Status()
+ if err2 != nil {
+ return plumbing.ZeroHash, err2
+ }
+ }
+
+ if err != nil || !fi.IsDir() {
+ added, h, err = w.doAddFile(idx, s, path, ignorePattern)
+ } else {
+ added, err = w.doAddDirectory(idx, s, path, ignorePattern)
+ }
+
+ if err != nil {
+ return h, err
+ }
+
+ if !added {
+ return h, nil
+ }
+
+ return h, w.r.Storer.SetIndex(idx)
+}
+
+// AddGlob adds all paths, matching pattern, to the index. If pattern matches a
+// directory path, all directory contents are added to the index recursively. No
+// error is returned if all matching paths are already staged in index.
+func (w *Worktree) AddGlob(pattern string) error {
+ // TODO(mcuadros): deprecate in favor of AddWithOption in v6.
+ files, err := util.Glob(w.Filesystem, pattern)
+ if err != nil {
+ return err
+ }
+
+ if len(files) == 0 {
+ return ErrGlobNoMatches
+ }
+
+ s, err := w.Status()
+ if err != nil {
+ return err
+ }
+
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return err
+ }
+
+ var saveIndex bool
+ for _, file := range files {
+ fi, err := w.Filesystem.Lstat(file)
+ if err != nil {
+ return err
+ }
+
+ var added bool
+ if fi.IsDir() {
+ added, err = w.doAddDirectory(idx, s, file, make([]gitignore.Pattern, 0))
+ } else {
+ added, _, err = w.doAddFile(idx, s, file, make([]gitignore.Pattern, 0))
+ }
+
+ if err != nil {
+ return err
+ }
+
+ if !saveIndex && added {
+ saveIndex = true
+ }
+ }
+
+ if saveIndex {
+ return w.r.Storer.SetIndex(idx)
+ }
+
+ return nil
+}
+
+// doAddFile create a new blob from path and update the index, added is true if
+// the file added is different from the index.
+// if s status is nil will skip the status check and update the index anyway
+func (w *Worktree) doAddFile(idx *index.Index, s Status, path string, ignorePattern []gitignore.Pattern) (added bool, h plumbing.Hash, err error) {
+ if s != nil && s.File(path).Worktree == Unmodified {
+ return false, h, nil
+ }
+ if len(ignorePattern) > 0 {
+ m := gitignore.NewMatcher(ignorePattern)
+ matchPath := strings.Split(path, string(os.PathSeparator))
+ if m.Match(matchPath, true) {
+ // ignore
+ return false, h, nil
+ }
+ }
+
+ h, err = w.copyFileToStorage(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ added = true
+ h, err = w.deleteFromIndex(idx, path)
+ }
+
+ return
+ }
+
+ if err := w.addOrUpdateFileToIndex(idx, path, h); err != nil {
+ return false, h, err
+ }
+
+ return true, h, err
+}
+
+func (w *Worktree) copyFileToStorage(path string) (hash plumbing.Hash, err error) {
+ fi, err := w.Filesystem.Lstat(path)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ obj := w.r.Storer.NewEncodedObject()
+ obj.SetType(plumbing.BlobObject)
+ obj.SetSize(fi.Size())
+
+ writer, err := obj.Writer()
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ defer ioutil.CheckClose(writer, &err)
+
+ if fi.Mode()&os.ModeSymlink != 0 {
+ err = w.fillEncodedObjectFromSymlink(writer, path, fi)
+ } else {
+ err = w.fillEncodedObjectFromFile(writer, path, fi)
+ }
+
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return w.r.Storer.SetEncodedObject(obj)
+}
+
+func (w *Worktree) fillEncodedObjectFromFile(dst io.Writer, path string, fi os.FileInfo) (err error) {
+ src, err := w.Filesystem.Open(path)
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(src, &err)
+
+ if _, err := io.Copy(dst, src); err != nil {
+ return err
+ }
+
+ return err
+}
+
+func (w *Worktree) fillEncodedObjectFromSymlink(dst io.Writer, path string, fi os.FileInfo) error {
+ target, err := w.Filesystem.Readlink(path)
+ if err != nil {
+ return err
+ }
+
+ _, err = dst.Write([]byte(target))
+ return err
+}
+
+func (w *Worktree) addOrUpdateFileToIndex(idx *index.Index, filename string, h plumbing.Hash) error {
+ e, err := idx.Entry(filename)
+ if err != nil && err != index.ErrEntryNotFound {
+ return err
+ }
+
+ if err == index.ErrEntryNotFound {
+ return w.doAddFileToIndex(idx, filename, h)
+ }
+
+ return w.doUpdateFileToIndex(e, filename, h)
+}
+
+func (w *Worktree) doAddFileToIndex(idx *index.Index, filename string, h plumbing.Hash) error {
+ return w.doUpdateFileToIndex(idx.Add(filename), filename, h)
+}
+
+func (w *Worktree) doUpdateFileToIndex(e *index.Entry, filename string, h plumbing.Hash) error {
+ info, err := w.Filesystem.Lstat(filename)
+ if err != nil {
+ return err
+ }
+
+ e.Hash = h
+ e.ModifiedAt = info.ModTime()
+ e.Mode, err = filemode.NewFromOSFileMode(info.Mode())
+ if err != nil {
+ return err
+ }
+
+ if e.Mode.IsRegular() {
+ e.Size = uint32(info.Size())
+ }
+
+ fillSystemInfo(e, info.Sys())
+ return nil
+}
+
+// Remove removes files from the working tree and from the index.
+func (w *Worktree) Remove(path string) (plumbing.Hash, error) {
+ // TODO(mcuadros): remove plumbing.Hash from signature at v5.
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ var h plumbing.Hash
+
+ fi, err := w.Filesystem.Lstat(path)
+ if err != nil || !fi.IsDir() {
+ h, err = w.doRemoveFile(idx, path)
+ } else {
+ _, err = w.doRemoveDirectory(idx, path)
+ }
+ if err != nil {
+ return h, err
+ }
+
+ return h, w.r.Storer.SetIndex(idx)
+}
+
+func (w *Worktree) doRemoveDirectory(idx *index.Index, directory string) (removed bool, err error) {
+ files, err := w.Filesystem.ReadDir(directory)
+ if err != nil {
+ return false, err
+ }
+
+ for _, file := range files {
+ name := path.Join(directory, file.Name())
+
+ var r bool
+ if file.IsDir() {
+ r, err = w.doRemoveDirectory(idx, name)
+ } else {
+ _, err = w.doRemoveFile(idx, name)
+ if err == index.ErrEntryNotFound {
+ err = nil
+ }
+ }
+
+ if err != nil {
+ return
+ }
+
+ if !removed && r {
+ removed = true
+ }
+ }
+
+ err = w.removeEmptyDirectory(directory)
+ return
+}
+
+func (w *Worktree) removeEmptyDirectory(path string) error {
+ files, err := w.Filesystem.ReadDir(path)
+ if err != nil {
+ return err
+ }
+
+ if len(files) != 0 {
+ return nil
+ }
+
+ return w.Filesystem.Remove(path)
+}
+
+func (w *Worktree) doRemoveFile(idx *index.Index, path string) (plumbing.Hash, error) {
+ hash, err := w.deleteFromIndex(idx, path)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return hash, w.deleteFromFilesystem(path)
+}
+
+func (w *Worktree) deleteFromIndex(idx *index.Index, path string) (plumbing.Hash, error) {
+ e, err := idx.Remove(path)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ return e.Hash, nil
+}
+
+func (w *Worktree) deleteFromFilesystem(path string) error {
+ err := w.Filesystem.Remove(path)
+ if os.IsNotExist(err) {
+ return nil
+ }
+
+ return err
+}
+
+// RemoveGlob removes all paths, matching pattern, from the index. If pattern
+// matches a directory path, all directory contents are removed from the index
+// recursively.
+func (w *Worktree) RemoveGlob(pattern string) error {
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return err
+ }
+
+ entries, err := idx.Glob(pattern)
+ if err != nil {
+ return err
+ }
+
+ for _, e := range entries {
+ file := filepath.FromSlash(e.Name)
+ if _, err := w.Filesystem.Lstat(file); err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
+ if _, err := w.doRemoveFile(idx, file); err != nil {
+ return err
+ }
+
+ dir, _ := filepath.Split(file)
+ if err := w.removeEmptyDirectory(dir); err != nil {
+ return err
+ }
+ }
+
+ return w.r.Storer.SetIndex(idx)
+}
+
+// Move moves or rename a file in the worktree and the index, directories are
+// not supported.
+func (w *Worktree) Move(from, to string) (plumbing.Hash, error) {
+ // TODO(mcuadros): support directories and/or implement support for glob
+ if _, err := w.Filesystem.Lstat(from); err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ if _, err := w.Filesystem.Lstat(to); err == nil {
+ return plumbing.ZeroHash, ErrDestinationExists
+ }
+
+ idx, err := w.r.Storer.Index()
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ hash, err := w.deleteFromIndex(idx, from)
+ if err != nil {
+ return plumbing.ZeroHash, err
+ }
+
+ if err := w.Filesystem.Rename(from, to); err != nil {
+ return hash, err
+ }
+
+ if err := w.addOrUpdateFileToIndex(idx, to, hash); err != nil {
+ return hash, err
+ }
+
+ return hash, w.r.Storer.SetIndex(idx)
+}
diff --git a/vendor/github.com/go-git/go-git/v5/worktree_unix_other.go b/vendor/github.com/go-git/go-git/v5/worktree_unix_other.go
new file mode 100644
index 00000000..5b16e70b
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree_unix_other.go
@@ -0,0 +1,26 @@
+// +build openbsd dragonfly solaris
+
+package git
+
+import (
+ "syscall"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+)
+
+func init() {
+ fillSystemInfo = func(e *index.Entry, sys interface{}) {
+ if os, ok := sys.(*syscall.Stat_t); ok {
+ e.CreatedAt = time.Unix(os.Atim.Unix())
+ e.Dev = uint32(os.Dev)
+ e.Inode = uint32(os.Ino)
+ e.GID = os.Gid
+ e.UID = os.Uid
+ }
+ }
+}
+
+func isSymlinkWindowsNonAdmin(err error) bool {
+ return false
+}
diff --git a/vendor/github.com/go-git/go-git/v5/worktree_windows.go b/vendor/github.com/go-git/go-git/v5/worktree_windows.go
new file mode 100644
index 00000000..1928f971
--- /dev/null
+++ b/vendor/github.com/go-git/go-git/v5/worktree_windows.go
@@ -0,0 +1,35 @@
+// +build windows
+
+package git
+
+import (
+ "os"
+ "syscall"
+ "time"
+
+ "github.com/go-git/go-git/v5/plumbing/format/index"
+)
+
+func init() {
+ fillSystemInfo = func(e *index.Entry, sys interface{}) {
+ if os, ok := sys.(*syscall.Win32FileAttributeData); ok {
+ seconds := os.CreationTime.Nanoseconds() / 1000000000
+ nanoseconds := os.CreationTime.Nanoseconds() - seconds*1000000000
+ e.CreatedAt = time.Unix(seconds, nanoseconds)
+ }
+ }
+}
+
+func isSymlinkWindowsNonAdmin(err error) bool {
+ const ERROR_PRIVILEGE_NOT_HELD syscall.Errno = 1314
+
+ if err != nil {
+ if errLink, ok := err.(*os.LinkError); ok {
+ if errNo, ok := errLink.Err.(syscall.Errno); ok {
+ return errNo == ERROR_PRIVILEGE_NOT_HELD
+ }
+ }
+ }
+
+ return false
+}
diff --git a/vendor/github.com/jbenet/go-context/LICENSE b/vendor/github.com/jbenet/go-context/LICENSE
new file mode 100644
index 00000000..c7386b3c
--- /dev/null
+++ b/vendor/github.com/jbenet/go-context/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Juan Batiz-Benet
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/jbenet/go-context/io/ctxio.go b/vendor/github.com/jbenet/go-context/io/ctxio.go
new file mode 100644
index 00000000..b4f24542
--- /dev/null
+++ b/vendor/github.com/jbenet/go-context/io/ctxio.go
@@ -0,0 +1,120 @@
+// Package ctxio provides io.Reader and io.Writer wrappers that
+// respect context.Contexts. Use these at the interface between
+// your context code and your io.
+//
+// WARNING: read the code. see how writes and reads will continue
+// until you cancel the io. Maybe this package should provide
+// versions of io.ReadCloser and io.WriteCloser that automatically
+// call .Close when the context expires. But for now -- since in my
+// use cases I have long-lived connections with ephemeral io wrappers
+// -- this has yet to be a need.
+package ctxio
+
+import (
+ "io"
+
+ context "golang.org/x/net/context"
+)
+
+type ioret struct {
+ n int
+ err error
+}
+
+type Writer interface {
+ io.Writer
+}
+
+type ctxWriter struct {
+ w io.Writer
+ ctx context.Context
+}
+
+// NewWriter wraps a writer to make it respect given Context.
+// If there is a blocking write, the returned Writer will return
+// whenever the context is cancelled (the return values are n=0
+// and err=ctx.Err().)
+//
+// Note well: this wrapper DOES NOT ACTUALLY cancel the underlying
+// write-- there is no way to do that with the standard go io
+// interface. So the read and write _will_ happen or hang. So, use
+// this sparingly, make sure to cancel the read or write as necesary
+// (e.g. closing a connection whose context is up, etc.)
+//
+// Furthermore, in order to protect your memory from being read
+// _after_ you've cancelled the context, this io.Writer will
+// first make a **copy** of the buffer.
+func NewWriter(ctx context.Context, w io.Writer) *ctxWriter {
+ if ctx == nil {
+ ctx = context.Background()
+ }
+ return &ctxWriter{ctx: ctx, w: w}
+}
+
+func (w *ctxWriter) Write(buf []byte) (int, error) {
+ buf2 := make([]byte, len(buf))
+ copy(buf2, buf)
+
+ c := make(chan ioret, 1)
+
+ go func() {
+ n, err := w.w.Write(buf2)
+ c <- ioret{n, err}
+ close(c)
+ }()
+
+ select {
+ case r := <-c:
+ return r.n, r.err
+ case <-w.ctx.Done():
+ return 0, w.ctx.Err()
+ }
+}
+
+type Reader interface {
+ io.Reader
+}
+
+type ctxReader struct {
+ r io.Reader
+ ctx context.Context
+}
+
+// NewReader wraps a reader to make it respect given Context.
+// If there is a blocking read, the returned Reader will return
+// whenever the context is cancelled (the return values are n=0
+// and err=ctx.Err().)
+//
+// Note well: this wrapper DOES NOT ACTUALLY cancel the underlying
+// write-- there is no way to do that with the standard go io
+// interface. So the read and write _will_ happen or hang. So, use
+// this sparingly, make sure to cancel the read or write as necesary
+// (e.g. closing a connection whose context is up, etc.)
+//
+// Furthermore, in order to protect your memory from being read
+// _before_ you've cancelled the context, this io.Reader will
+// allocate a buffer of the same size, and **copy** into the client's
+// if the read succeeds in time.
+func NewReader(ctx context.Context, r io.Reader) *ctxReader {
+ return &ctxReader{ctx: ctx, r: r}
+}
+
+func (r *ctxReader) Read(buf []byte) (int, error) {
+ buf2 := make([]byte, len(buf))
+
+ c := make(chan ioret, 1)
+
+ go func() {
+ n, err := r.r.Read(buf2)
+ c <- ioret{n, err}
+ close(c)
+ }()
+
+ select {
+ case ret := <-c:
+ copy(buf, buf2)
+ return ret.n, ret.err
+ case <-r.ctx.Done():
+ return 0, r.ctx.Err()
+ }
+}
diff --git a/vendor/github.com/kevinburke/ssh_config/.gitattributes b/vendor/github.com/kevinburke/ssh_config/.gitattributes
new file mode 100644
index 00000000..44db5818
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/.gitattributes
@@ -0,0 +1 @@
+testdata/dos-lines eol=crlf
diff --git a/vendor/github.com/kevinburke/ssh_config/.gitignore b/vendor/github.com/kevinburke/ssh_config/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/vendor/github.com/kevinburke/ssh_config/.mailmap b/vendor/github.com/kevinburke/ssh_config/.mailmap
new file mode 100644
index 00000000..253406b1
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/.mailmap
@@ -0,0 +1 @@
+Kevin Burke Kevin Burke
diff --git a/vendor/github.com/kevinburke/ssh_config/AUTHORS.txt b/vendor/github.com/kevinburke/ssh_config/AUTHORS.txt
new file mode 100644
index 00000000..311aeb1b
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/AUTHORS.txt
@@ -0,0 +1,9 @@
+Carlos A Becker
+Dustin Spicuzza
+Eugene Terentev
+Kevin Burke
+Mark Nevill
+Scott Lessans
+Sergey Lukjanov
+Wayne Ashley Berry
+santosh653 <70637961+santosh653@users.noreply.github.com>
diff --git a/vendor/github.com/kevinburke/ssh_config/CHANGELOG.md b/vendor/github.com/kevinburke/ssh_config/CHANGELOG.md
new file mode 100644
index 00000000..d32a3f51
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/CHANGELOG.md
@@ -0,0 +1,19 @@
+# Changes
+
+## Version 1.2
+
+Previously, if a Host declaration or a value had trailing whitespace, that
+whitespace would have been included as part of the value. This led to unexpected
+consequences. For example:
+
+```
+Host example # A comment
+ HostName example.com # Another comment
+```
+
+Prior to version 1.2, the value for Host would have been "example " and the
+value for HostName would have been "example.com ". Both of these are
+unintuitive.
+
+Instead, we strip the trailing whitespace in the configuration, which leads to
+more intuitive behavior.
diff --git a/vendor/github.com/kevinburke/ssh_config/LICENSE b/vendor/github.com/kevinburke/ssh_config/LICENSE
new file mode 100644
index 00000000..b9a770ac
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/LICENSE
@@ -0,0 +1,49 @@
+Copyright (c) 2017 Kevin Burke.
+
+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.
+
+===================
+
+The lexer and parser borrow heavily from github.com/pelletier/go-toml. The
+license for that project is copied below.
+
+The MIT License (MIT)
+
+Copyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/kevinburke/ssh_config/Makefile b/vendor/github.com/kevinburke/ssh_config/Makefile
new file mode 100644
index 00000000..df7ee728
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/Makefile
@@ -0,0 +1,33 @@
+BUMP_VERSION := $(GOPATH)/bin/bump_version
+STATICCHECK := $(GOPATH)/bin/staticcheck
+WRITE_MAILMAP := $(GOPATH)/bin/write_mailmap
+
+$(STATICCHECK):
+ go get honnef.co/go/tools/cmd/staticcheck
+
+lint: $(STATICCHECK)
+ go vet ./...
+ $(STATICCHECK)
+
+test: lint
+ @# the timeout helps guard against infinite recursion
+ go test -timeout=250ms ./...
+
+race-test: lint
+ go test -timeout=500ms -race ./...
+
+$(BUMP_VERSION):
+ go get -u github.com/kevinburke/bump_version
+
+$(WRITE_MAILMAP):
+ go get -u github.com/kevinburke/write_mailmap
+
+release: test | $(BUMP_VERSION)
+ $(BUMP_VERSION) --tag-prefix=v minor config.go
+
+force: ;
+
+AUTHORS.txt: force | $(WRITE_MAILMAP)
+ $(WRITE_MAILMAP) > AUTHORS.txt
+
+authors: AUTHORS.txt
diff --git a/vendor/github.com/kevinburke/ssh_config/README.md b/vendor/github.com/kevinburke/ssh_config/README.md
new file mode 100644
index 00000000..f14b2168
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/README.md
@@ -0,0 +1,92 @@
+# ssh_config
+
+This is a Go parser for `ssh_config` files. Importantly, this parser attempts
+to preserve comments in a given file, so you can manipulate a `ssh_config` file
+from a program, if your heart desires.
+
+It's designed to be used with the excellent
+[x/crypto/ssh](https://golang.org/x/crypto/ssh) package, which handles SSH
+negotiation but isn't very easy to configure.
+
+The `ssh_config` `Get()` and `GetStrict()` functions will attempt to read values
+from `$HOME/.ssh/config` and fall back to `/etc/ssh/ssh_config`. The first
+argument is the host name to match on, and the second argument is the key you
+want to retrieve.
+
+```go
+port := ssh_config.Get("myhost", "Port")
+```
+
+Certain directives can occur multiple times for a host (such as `IdentityFile`),
+so you should use the `GetAll` or `GetAllStrict` directive to retrieve those
+instead.
+
+```go
+files := ssh_config.GetAll("myhost", "IdentityFile")
+```
+
+You can also load a config file and read values from it.
+
+```go
+var config = `
+Host *.test
+ Compression yes
+`
+
+cfg, err := ssh_config.Decode(strings.NewReader(config))
+fmt.Println(cfg.Get("example.test", "Port"))
+```
+
+Some SSH arguments have default values - for example, the default value for
+`KeyboardAuthentication` is `"yes"`. If you call Get(), and no value for the
+given Host/keyword pair exists in the config, we'll return a default for the
+keyword if one exists.
+
+### Manipulating SSH config files
+
+Here's how you can manipulate an SSH config file, and then write it back to
+disk.
+
+```go
+f, _ := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "config"))
+cfg, _ := ssh_config.Decode(f)
+for _, host := range cfg.Hosts {
+ fmt.Println("patterns:", host.Patterns)
+ for _, node := range host.Nodes {
+ // Manipulate the nodes as you see fit, or use a type switch to
+ // distinguish between Empty, KV, and Include nodes.
+ fmt.Println(node.String())
+ }
+}
+
+// Print the config to stdout:
+fmt.Println(cfg.String())
+```
+
+## Spec compliance
+
+Wherever possible we try to implement the specification as documented in
+the `ssh_config` manpage. Unimplemented features should be present in the
+[issues][issues] list.
+
+Notably, the `Match` directive is currently unsupported.
+
+[issues]: https://github.com/kevinburke/ssh_config/issues
+
+## Errata
+
+This is the second [comment-preserving configuration parser][blog] I've written, after
+[an /etc/hosts parser][hostsfile]. Eventually, I will write one for every Linux
+file format.
+
+[blog]: https://kev.inburke.com/kevin/more-comment-preserving-configuration-parsers/
+[hostsfile]: https://github.com/kevinburke/hostsfile
+
+## Donating
+
+I don't get paid to maintain this project. Donations free up time to make
+improvements to the library, and respond to bug reports. You can send donations
+via Paypal's "Send Money" feature to kev@inburke.com. Donations are not tax
+deductible in the USA.
+
+You can also reach out about a consulting engagement: https://burke.services
diff --git a/vendor/github.com/kevinburke/ssh_config/config.go b/vendor/github.com/kevinburke/ssh_config/config.go
new file mode 100644
index 00000000..00d815c1
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/config.go
@@ -0,0 +1,803 @@
+// Package ssh_config provides tools for manipulating SSH config files.
+//
+// Importantly, this parser attempts to preserve comments in a given file, so
+// you can manipulate a `ssh_config` file from a program, if your heart desires.
+//
+// The Get() and GetStrict() functions will attempt to read values from
+// $HOME/.ssh/config, falling back to /etc/ssh/ssh_config. The first argument is
+// the host name to match on ("example.com"), and the second argument is the key
+// you want to retrieve ("Port"). The keywords are case insensitive.
+//
+// port := ssh_config.Get("myhost", "Port")
+//
+// You can also manipulate an SSH config file and then print it or write it back
+// to disk.
+//
+// f, _ := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "config"))
+// cfg, _ := ssh_config.Decode(f)
+// for _, host := range cfg.Hosts {
+// fmt.Println("patterns:", host.Patterns)
+// for _, node := range host.Nodes {
+// fmt.Println(node.String())
+// }
+// }
+//
+// // Write the cfg back to disk:
+// fmt.Println(cfg.String())
+//
+// BUG: the Match directive is currently unsupported; parsing a config with
+// a Match directive will trigger an error.
+package ssh_config
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ osuser "os/user"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "strings"
+ "sync"
+)
+
+const version = "1.2"
+
+var _ = version
+
+type configFinder func() string
+
+// UserSettings checks ~/.ssh and /etc/ssh for configuration files. The config
+// files are parsed and cached the first time Get() or GetStrict() is called.
+type UserSettings struct {
+ IgnoreErrors bool
+ systemConfig *Config
+ systemConfigFinder configFinder
+ userConfig *Config
+ userConfigFinder configFinder
+ loadConfigs sync.Once
+ onceErr error
+}
+
+func homedir() string {
+ user, err := osuser.Current()
+ if err == nil {
+ return user.HomeDir
+ } else {
+ return os.Getenv("HOME")
+ }
+}
+
+func userConfigFinder() string {
+ return filepath.Join(homedir(), ".ssh", "config")
+}
+
+// DefaultUserSettings is the default UserSettings and is used by Get and
+// GetStrict. It checks both $HOME/.ssh/config and /etc/ssh/ssh_config for keys,
+// and it will return parse errors (if any) instead of swallowing them.
+var DefaultUserSettings = &UserSettings{
+ IgnoreErrors: false,
+ systemConfigFinder: systemConfigFinder,
+ userConfigFinder: userConfigFinder,
+}
+
+func systemConfigFinder() string {
+ return filepath.Join("/", "etc", "ssh", "ssh_config")
+}
+
+func findVal(c *Config, alias, key string) (string, error) {
+ if c == nil {
+ return "", nil
+ }
+ val, err := c.Get(alias, key)
+ if err != nil || val == "" {
+ return "", err
+ }
+ if err := validate(key, val); err != nil {
+ return "", err
+ }
+ return val, nil
+}
+
+func findAll(c *Config, alias, key string) ([]string, error) {
+ if c == nil {
+ return nil, nil
+ }
+ return c.GetAll(alias, key)
+}
+
+// Get finds the first value for key within a declaration that matches the
+// alias. Get returns the empty string if no value was found, or if IgnoreErrors
+// is false and we could not parse the configuration file. Use GetStrict to
+// disambiguate the latter cases.
+//
+// The match for key is case insensitive.
+//
+// Get is a wrapper around DefaultUserSettings.Get.
+func Get(alias, key string) string {
+ return DefaultUserSettings.Get(alias, key)
+}
+
+// GetAll retrieves zero or more directives for key for the given alias. GetAll
+// returns nil if no value was found, or if IgnoreErrors is false and we could
+// not parse the configuration file. Use GetAllStrict to disambiguate the
+// latter cases.
+//
+// In most cases you want to use Get or GetStrict, which returns a single value.
+// However, a subset of ssh configuration values (IdentityFile, for example)
+// allow you to specify multiple directives.
+//
+// The match for key is case insensitive.
+//
+// GetAll is a wrapper around DefaultUserSettings.GetAll.
+func GetAll(alias, key string) []string {
+ return DefaultUserSettings.GetAll(alias, key)
+}
+
+// GetStrict finds the first value for key within a declaration that matches the
+// alias. If key has a default value and no matching configuration is found, the
+// default will be returned. For more information on default values and the way
+// patterns are matched, see the manpage for ssh_config.
+//
+// The returned error will be non-nil if and only if a user's configuration file
+// or the system configuration file could not be parsed, and u.IgnoreErrors is
+// false.
+//
+// GetStrict is a wrapper around DefaultUserSettings.GetStrict.
+func GetStrict(alias, key string) (string, error) {
+ return DefaultUserSettings.GetStrict(alias, key)
+}
+
+// GetAllStrict retrieves zero or more directives for key for the given alias.
+//
+// In most cases you want to use Get or GetStrict, which returns a single value.
+// However, a subset of ssh configuration values (IdentityFile, for example)
+// allow you to specify multiple directives.
+//
+// The returned error will be non-nil if and only if a user's configuration file
+// or the system configuration file could not be parsed, and u.IgnoreErrors is
+// false.
+//
+// GetAllStrict is a wrapper around DefaultUserSettings.GetAllStrict.
+func GetAllStrict(alias, key string) ([]string, error) {
+ return DefaultUserSettings.GetAllStrict(alias, key)
+}
+
+// Get finds the first value for key within a declaration that matches the
+// alias. Get returns the empty string if no value was found, or if IgnoreErrors
+// is false and we could not parse the configuration file. Use GetStrict to
+// disambiguate the latter cases.
+//
+// The match for key is case insensitive.
+func (u *UserSettings) Get(alias, key string) string {
+ val, err := u.GetStrict(alias, key)
+ if err != nil {
+ return ""
+ }
+ return val
+}
+
+// GetAll retrieves zero or more directives for key for the given alias. GetAll
+// returns nil if no value was found, or if IgnoreErrors is false and we could
+// not parse the configuration file. Use GetStrict to disambiguate the latter
+// cases.
+//
+// The match for key is case insensitive.
+func (u *UserSettings) GetAll(alias, key string) []string {
+ val, _ := u.GetAllStrict(alias, key)
+ return val
+}
+
+// GetStrict finds the first value for key within a declaration that matches the
+// alias. If key has a default value and no matching configuration is found, the
+// default will be returned. For more information on default values and the way
+// patterns are matched, see the manpage for ssh_config.
+//
+// error will be non-nil if and only if a user's configuration file or the
+// system configuration file could not be parsed, and u.IgnoreErrors is false.
+func (u *UserSettings) GetStrict(alias, key string) (string, error) {
+ u.doLoadConfigs()
+ //lint:ignore S1002 I prefer it this way
+ if u.onceErr != nil && u.IgnoreErrors == false {
+ return "", u.onceErr
+ }
+ val, err := findVal(u.userConfig, alias, key)
+ if err != nil || val != "" {
+ return val, err
+ }
+ val2, err2 := findVal(u.systemConfig, alias, key)
+ if err2 != nil || val2 != "" {
+ return val2, err2
+ }
+ return Default(key), nil
+}
+
+// GetAllStrict retrieves zero or more directives for key for the given alias.
+// If key has a default value and no matching configuration is found, the
+// default will be returned. For more information on default values and the way
+// patterns are matched, see the manpage for ssh_config.
+//
+// The returned error will be non-nil if and only if a user's configuration file
+// or the system configuration file could not be parsed, and u.IgnoreErrors is
+// false.
+func (u *UserSettings) GetAllStrict(alias, key string) ([]string, error) {
+ u.doLoadConfigs()
+ //lint:ignore S1002 I prefer it this way
+ if u.onceErr != nil && u.IgnoreErrors == false {
+ return nil, u.onceErr
+ }
+ val, err := findAll(u.userConfig, alias, key)
+ if err != nil || val != nil {
+ return val, err
+ }
+ val2, err2 := findAll(u.systemConfig, alias, key)
+ if err2 != nil || val2 != nil {
+ return val2, err2
+ }
+ // TODO: IdentityFile has multiple default values that we should return.
+ if def := Default(key); def != "" {
+ return []string{def}, nil
+ }
+ return []string{}, nil
+}
+
+func (u *UserSettings) doLoadConfigs() {
+ u.loadConfigs.Do(func() {
+ // can't parse user file, that's ok.
+ var filename string
+ if u.userConfigFinder == nil {
+ filename = userConfigFinder()
+ } else {
+ filename = u.userConfigFinder()
+ }
+ var err error
+ u.userConfig, err = parseFile(filename)
+ //lint:ignore S1002 I prefer it this way
+ if err != nil && os.IsNotExist(err) == false {
+ u.onceErr = err
+ return
+ }
+ if u.systemConfigFinder == nil {
+ filename = systemConfigFinder()
+ } else {
+ filename = u.systemConfigFinder()
+ }
+ u.systemConfig, err = parseFile(filename)
+ //lint:ignore S1002 I prefer it this way
+ if err != nil && os.IsNotExist(err) == false {
+ u.onceErr = err
+ return
+ }
+ })
+}
+
+func parseFile(filename string) (*Config, error) {
+ return parseWithDepth(filename, 0)
+}
+
+func parseWithDepth(filename string, depth uint8) (*Config, error) {
+ b, err := os.ReadFile(filename)
+ if err != nil {
+ return nil, err
+ }
+ return decodeBytes(b, isSystem(filename), depth)
+}
+
+func isSystem(filename string) bool {
+ // TODO: not sure this is the best way to detect a system repo
+ return strings.HasPrefix(filepath.Clean(filename), "/etc/ssh")
+}
+
+// Decode reads r into a Config, or returns an error if r could not be parsed as
+// an SSH config file.
+func Decode(r io.Reader) (*Config, error) {
+ b, err := io.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+ return decodeBytes(b, false, 0)
+}
+
+// DecodeBytes reads b into a Config, or returns an error if r could not be
+// parsed as an SSH config file.
+func DecodeBytes(b []byte) (*Config, error) {
+ return decodeBytes(b, false, 0)
+}
+
+func decodeBytes(b []byte, system bool, depth uint8) (c *Config, err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ if _, ok := r.(runtime.Error); ok {
+ panic(r)
+ }
+ if e, ok := r.(error); ok && e == ErrDepthExceeded {
+ err = e
+ return
+ }
+ err = errors.New(r.(string))
+ }
+ }()
+
+ c = parseSSH(lexSSH(b), system, depth)
+ return c, err
+}
+
+// Config represents an SSH config file.
+type Config struct {
+ // A list of hosts to match against. The file begins with an implicit
+ // "Host *" declaration matching all hosts.
+ Hosts []*Host
+ depth uint8
+ position Position
+}
+
+// Get finds the first value in the configuration that matches the alias and
+// contains key. Get returns the empty string if no value was found, or if the
+// Config contains an invalid conditional Include value.
+//
+// The match for key is case insensitive.
+func (c *Config) Get(alias, key string) (string, error) {
+ lowerKey := strings.ToLower(key)
+ for _, host := range c.Hosts {
+ if !host.Matches(alias) {
+ continue
+ }
+ for _, node := range host.Nodes {
+ switch t := node.(type) {
+ case *Empty:
+ continue
+ case *KV:
+ // "keys are case insensitive" per the spec
+ lkey := strings.ToLower(t.Key)
+ if lkey == "match" {
+ panic("can't handle Match directives")
+ }
+ if lkey == lowerKey {
+ return t.Value, nil
+ }
+ case *Include:
+ val := t.Get(alias, key)
+ if val != "" {
+ return val, nil
+ }
+ default:
+ return "", fmt.Errorf("unknown Node type %v", t)
+ }
+ }
+ }
+ return "", nil
+}
+
+// GetAll returns all values in the configuration that match the alias and
+// contains key, or nil if none are present.
+func (c *Config) GetAll(alias, key string) ([]string, error) {
+ lowerKey := strings.ToLower(key)
+ all := []string(nil)
+ for _, host := range c.Hosts {
+ if !host.Matches(alias) {
+ continue
+ }
+ for _, node := range host.Nodes {
+ switch t := node.(type) {
+ case *Empty:
+ continue
+ case *KV:
+ // "keys are case insensitive" per the spec
+ lkey := strings.ToLower(t.Key)
+ if lkey == "match" {
+ panic("can't handle Match directives")
+ }
+ if lkey == lowerKey {
+ all = append(all, t.Value)
+ }
+ case *Include:
+ val, _ := t.GetAll(alias, key)
+ if len(val) > 0 {
+ all = append(all, val...)
+ }
+ default:
+ return nil, fmt.Errorf("unknown Node type %v", t)
+ }
+ }
+ }
+
+ return all, nil
+}
+
+// String returns a string representation of the Config file.
+func (c Config) String() string {
+ return marshal(c).String()
+}
+
+func (c Config) MarshalText() ([]byte, error) {
+ return marshal(c).Bytes(), nil
+}
+
+func marshal(c Config) *bytes.Buffer {
+ var buf bytes.Buffer
+ for i := range c.Hosts {
+ buf.WriteString(c.Hosts[i].String())
+ }
+ return &buf
+}
+
+// Pattern is a pattern in a Host declaration. Patterns are read-only values;
+// create a new one with NewPattern().
+type Pattern struct {
+ str string // Its appearance in the file, not the value that gets compiled.
+ regex *regexp.Regexp
+ not bool // True if this is a negated match
+}
+
+// String prints the string representation of the pattern.
+func (p Pattern) String() string {
+ return p.str
+}
+
+// Copied from regexp.go with * and ? removed.
+var specialBytes = []byte(`\.+()|[]{}^$`)
+
+func special(b byte) bool {
+ return bytes.IndexByte(specialBytes, b) >= 0
+}
+
+// NewPattern creates a new Pattern for matching hosts. NewPattern("*") creates
+// a Pattern that matches all hosts.
+//
+// From the manpage, a pattern consists of zero or more non-whitespace
+// characters, `*' (a wildcard that matches zero or more characters), or `?' (a
+// wildcard that matches exactly one character). For example, to specify a set
+// of declarations for any host in the ".co.uk" set of domains, the following
+// pattern could be used:
+//
+// Host *.co.uk
+//
+// The following pattern would match any host in the 192.168.0.[0-9] network range:
+//
+// Host 192.168.0.?
+func NewPattern(s string) (*Pattern, error) {
+ if s == "" {
+ return nil, errors.New("ssh_config: empty pattern")
+ }
+ negated := false
+ if s[0] == '!' {
+ negated = true
+ s = s[1:]
+ }
+ var buf bytes.Buffer
+ buf.WriteByte('^')
+ for i := 0; i < len(s); i++ {
+ // A byte loop is correct because all metacharacters are ASCII.
+ switch b := s[i]; b {
+ case '*':
+ buf.WriteString(".*")
+ case '?':
+ buf.WriteString(".?")
+ default:
+ // borrowing from QuoteMeta here.
+ if special(b) {
+ buf.WriteByte('\\')
+ }
+ buf.WriteByte(b)
+ }
+ }
+ buf.WriteByte('$')
+ r, err := regexp.Compile(buf.String())
+ if err != nil {
+ return nil, err
+ }
+ return &Pattern{str: s, regex: r, not: negated}, nil
+}
+
+// Host describes a Host directive and the keywords that follow it.
+type Host struct {
+ // A list of host patterns that should match this host.
+ Patterns []*Pattern
+ // A Node is either a key/value pair or a comment line.
+ Nodes []Node
+ // EOLComment is the comment (if any) terminating the Host line.
+ EOLComment string
+ // Whitespace if any between the Host declaration and a trailing comment.
+ spaceBeforeComment string
+
+ hasEquals bool
+ leadingSpace int // TODO: handle spaces vs tabs here.
+ // The file starts with an implicit "Host *" declaration.
+ implicit bool
+}
+
+// Matches returns true if the Host matches for the given alias. For
+// a description of the rules that provide a match, see the manpage for
+// ssh_config.
+func (h *Host) Matches(alias string) bool {
+ found := false
+ for i := range h.Patterns {
+ if h.Patterns[i].regex.MatchString(alias) {
+ if h.Patterns[i].not {
+ // Negated match. "A pattern entry may be negated by prefixing
+ // it with an exclamation mark (`!'). If a negated entry is
+ // matched, then the Host entry is ignored, regardless of
+ // whether any other patterns on the line match. Negated matches
+ // are therefore useful to provide exceptions for wildcard
+ // matches."
+ return false
+ }
+ found = true
+ }
+ }
+ return found
+}
+
+// String prints h as it would appear in a config file. Minor tweaks may be
+// present in the whitespace in the printed file.
+func (h *Host) String() string {
+ var buf strings.Builder
+ //lint:ignore S1002 I prefer to write it this way
+ if h.implicit == false {
+ buf.WriteString(strings.Repeat(" ", int(h.leadingSpace)))
+ buf.WriteString("Host")
+ if h.hasEquals {
+ buf.WriteString(" = ")
+ } else {
+ buf.WriteString(" ")
+ }
+ for i, pat := range h.Patterns {
+ buf.WriteString(pat.String())
+ if i < len(h.Patterns)-1 {
+ buf.WriteString(" ")
+ }
+ }
+ buf.WriteString(h.spaceBeforeComment)
+ if h.EOLComment != "" {
+ buf.WriteByte('#')
+ buf.WriteString(h.EOLComment)
+ }
+ buf.WriteByte('\n')
+ }
+ for i := range h.Nodes {
+ buf.WriteString(h.Nodes[i].String())
+ buf.WriteByte('\n')
+ }
+ return buf.String()
+}
+
+// Node represents a line in a Config.
+type Node interface {
+ Pos() Position
+ String() string
+}
+
+// KV is a line in the config file that contains a key, a value, and possibly
+// a comment.
+type KV struct {
+ Key string
+ Value string
+ // Whitespace after the value but before any comment
+ spaceAfterValue string
+ Comment string
+ hasEquals bool
+ leadingSpace int // Space before the key. TODO handle spaces vs tabs.
+ position Position
+}
+
+// Pos returns k's Position.
+func (k *KV) Pos() Position {
+ return k.position
+}
+
+// String prints k as it was parsed in the config file.
+func (k *KV) String() string {
+ if k == nil {
+ return ""
+ }
+ equals := " "
+ if k.hasEquals {
+ equals = " = "
+ }
+ line := strings.Repeat(" ", int(k.leadingSpace)) + k.Key + equals + k.Value + k.spaceAfterValue
+ if k.Comment != "" {
+ line += "#" + k.Comment
+ }
+ return line
+}
+
+// Empty is a line in the config file that contains only whitespace or comments.
+type Empty struct {
+ Comment string
+ leadingSpace int // TODO handle spaces vs tabs.
+ position Position
+}
+
+// Pos returns e's Position.
+func (e *Empty) Pos() Position {
+ return e.position
+}
+
+// String prints e as it was parsed in the config file.
+func (e *Empty) String() string {
+ if e == nil {
+ return ""
+ }
+ if e.Comment == "" {
+ return ""
+ }
+ return fmt.Sprintf("%s#%s", strings.Repeat(" ", int(e.leadingSpace)), e.Comment)
+}
+
+// Include holds the result of an Include directive, including the config files
+// that have been parsed as part of that directive. At most 5 levels of Include
+// statements will be parsed.
+type Include struct {
+ // Comment is the contents of any comment at the end of the Include
+ // statement.
+ Comment string
+ // an include directive can include several different files, and wildcards
+ directives []string
+
+ mu sync.Mutex
+ // 1:1 mapping between matches and keys in files array; matches preserves
+ // ordering
+ matches []string
+ // actual filenames are listed here
+ files map[string]*Config
+ leadingSpace int
+ position Position
+ depth uint8
+ hasEquals bool
+}
+
+const maxRecurseDepth = 5
+
+// ErrDepthExceeded is returned if too many Include directives are parsed.
+// Usually this indicates a recursive loop (an Include directive pointing to the
+// file it contains).
+var ErrDepthExceeded = errors.New("ssh_config: max recurse depth exceeded")
+
+func removeDups(arr []string) []string {
+ // Use map to record duplicates as we find them.
+ encountered := make(map[string]bool, len(arr))
+ result := make([]string, 0)
+
+ for v := range arr {
+ //lint:ignore S1002 I prefer it this way
+ if encountered[arr[v]] == false {
+ encountered[arr[v]] = true
+ result = append(result, arr[v])
+ }
+ }
+ return result
+}
+
+// NewInclude creates a new Include with a list of file globs to include.
+// Configuration files are parsed greedily (e.g. as soon as this function runs).
+// Any error encountered while parsing nested configuration files will be
+// returned.
+func NewInclude(directives []string, hasEquals bool, pos Position, comment string, system bool, depth uint8) (*Include, error) {
+ if depth > maxRecurseDepth {
+ return nil, ErrDepthExceeded
+ }
+ inc := &Include{
+ Comment: comment,
+ directives: directives,
+ files: make(map[string]*Config),
+ position: pos,
+ leadingSpace: pos.Col - 1,
+ depth: depth,
+ hasEquals: hasEquals,
+ }
+ // no need for inc.mu.Lock() since nothing else can access this inc
+ matches := make([]string, 0)
+ for i := range directives {
+ var path string
+ if filepath.IsAbs(directives[i]) {
+ path = directives[i]
+ } else if system {
+ path = filepath.Join("/etc/ssh", directives[i])
+ } else {
+ path = filepath.Join(homedir(), ".ssh", directives[i])
+ }
+ theseMatches, err := filepath.Glob(path)
+ if err != nil {
+ return nil, err
+ }
+ matches = append(matches, theseMatches...)
+ }
+ matches = removeDups(matches)
+ inc.matches = matches
+ for i := range matches {
+ config, err := parseWithDepth(matches[i], depth)
+ if err != nil {
+ return nil, err
+ }
+ inc.files[matches[i]] = config
+ }
+ return inc, nil
+}
+
+// Pos returns the position of the Include directive in the larger file.
+func (i *Include) Pos() Position {
+ return i.position
+}
+
+// Get finds the first value in the Include statement matching the alias and the
+// given key.
+func (inc *Include) Get(alias, key string) string {
+ inc.mu.Lock()
+ defer inc.mu.Unlock()
+ // TODO: we search files in any order which is not correct
+ for i := range inc.matches {
+ cfg := inc.files[inc.matches[i]]
+ if cfg == nil {
+ panic("nil cfg")
+ }
+ val, err := cfg.Get(alias, key)
+ if err == nil && val != "" {
+ return val
+ }
+ }
+ return ""
+}
+
+// GetAll finds all values in the Include statement matching the alias and the
+// given key.
+func (inc *Include) GetAll(alias, key string) ([]string, error) {
+ inc.mu.Lock()
+ defer inc.mu.Unlock()
+ var vals []string
+
+ // TODO: we search files in any order which is not correct
+ for i := range inc.matches {
+ cfg := inc.files[inc.matches[i]]
+ if cfg == nil {
+ panic("nil cfg")
+ }
+ val, err := cfg.GetAll(alias, key)
+ if err == nil && len(val) != 0 {
+ // In theory if SupportsMultiple was false for this key we could
+ // stop looking here. But the caller has asked us to find all
+ // instances of the keyword (and could use Get() if they wanted) so
+ // let's keep looking.
+ vals = append(vals, val...)
+ }
+ }
+ return vals, nil
+}
+
+// String prints out a string representation of this Include directive. Note
+// included Config files are not printed as part of this representation.
+func (inc *Include) String() string {
+ equals := " "
+ if inc.hasEquals {
+ equals = " = "
+ }
+ line := fmt.Sprintf("%sInclude%s%s", strings.Repeat(" ", int(inc.leadingSpace)), equals, strings.Join(inc.directives, " "))
+ if inc.Comment != "" {
+ line += " #" + inc.Comment
+ }
+ return line
+}
+
+var matchAll *Pattern
+
+func init() {
+ var err error
+ matchAll, err = NewPattern("*")
+ if err != nil {
+ panic(err)
+ }
+}
+
+func newConfig() *Config {
+ return &Config{
+ Hosts: []*Host{
+ &Host{
+ implicit: true,
+ Patterns: []*Pattern{matchAll},
+ Nodes: make([]Node, 0),
+ },
+ },
+ depth: 0,
+ }
+}
diff --git a/vendor/github.com/kevinburke/ssh_config/lexer.go b/vendor/github.com/kevinburke/ssh_config/lexer.go
new file mode 100644
index 00000000..11680b4c
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/lexer.go
@@ -0,0 +1,240 @@
+package ssh_config
+
+import (
+ "bytes"
+)
+
+// Define state functions
+type sshLexStateFn func() sshLexStateFn
+
+type sshLexer struct {
+ inputIdx int
+ input []rune // Textual source
+
+ buffer []rune // Runes composing the current token
+ tokens chan token
+ line int
+ col int
+ endbufferLine int
+ endbufferCol int
+}
+
+func (s *sshLexer) lexComment(previousState sshLexStateFn) sshLexStateFn {
+ return func() sshLexStateFn {
+ growingString := ""
+ for next := s.peek(); next != '\n' && next != eof; next = s.peek() {
+ if next == '\r' && s.follow("\r\n") {
+ break
+ }
+ growingString += string(next)
+ s.next()
+ }
+ s.emitWithValue(tokenComment, growingString)
+ s.skip()
+ return previousState
+ }
+}
+
+// lex the space after an equals sign in a function
+func (s *sshLexer) lexRspace() sshLexStateFn {
+ for {
+ next := s.peek()
+ if !isSpace(next) {
+ break
+ }
+ s.skip()
+ }
+ return s.lexRvalue
+}
+
+func (s *sshLexer) lexEquals() sshLexStateFn {
+ for {
+ next := s.peek()
+ if next == '=' {
+ s.emit(tokenEquals)
+ s.skip()
+ return s.lexRspace
+ }
+ // TODO error handling here; newline eof etc.
+ if !isSpace(next) {
+ break
+ }
+ s.skip()
+ }
+ return s.lexRvalue
+}
+
+func (s *sshLexer) lexKey() sshLexStateFn {
+ growingString := ""
+
+ for r := s.peek(); isKeyChar(r); r = s.peek() {
+ // simplified a lot here
+ if isSpace(r) || r == '=' {
+ s.emitWithValue(tokenKey, growingString)
+ s.skip()
+ return s.lexEquals
+ }
+ growingString += string(r)
+ s.next()
+ }
+ s.emitWithValue(tokenKey, growingString)
+ return s.lexEquals
+}
+
+func (s *sshLexer) lexRvalue() sshLexStateFn {
+ growingString := ""
+ for {
+ next := s.peek()
+ switch next {
+ case '\r':
+ if s.follow("\r\n") {
+ s.emitWithValue(tokenString, growingString)
+ s.skip()
+ return s.lexVoid
+ }
+ case '\n':
+ s.emitWithValue(tokenString, growingString)
+ s.skip()
+ return s.lexVoid
+ case '#':
+ s.emitWithValue(tokenString, growingString)
+ s.skip()
+ return s.lexComment(s.lexVoid)
+ case eof:
+ s.next()
+ }
+ if next == eof {
+ break
+ }
+ growingString += string(next)
+ s.next()
+ }
+ s.emit(tokenEOF)
+ return nil
+}
+
+func (s *sshLexer) read() rune {
+ r := s.peek()
+ if r == '\n' {
+ s.endbufferLine++
+ s.endbufferCol = 1
+ } else {
+ s.endbufferCol++
+ }
+ s.inputIdx++
+ return r
+}
+
+func (s *sshLexer) next() rune {
+ r := s.read()
+
+ if r != eof {
+ s.buffer = append(s.buffer, r)
+ }
+ return r
+}
+
+func (s *sshLexer) lexVoid() sshLexStateFn {
+ for {
+ next := s.peek()
+ switch next {
+ case '#':
+ s.skip()
+ return s.lexComment(s.lexVoid)
+ case '\r':
+ fallthrough
+ case '\n':
+ s.emit(tokenEmptyLine)
+ s.skip()
+ continue
+ }
+
+ if isSpace(next) {
+ s.skip()
+ }
+
+ if isKeyStartChar(next) {
+ return s.lexKey
+ }
+
+ // removed IsKeyStartChar and lexKey. probably will need to readd
+
+ if next == eof {
+ s.next()
+ break
+ }
+ }
+
+ s.emit(tokenEOF)
+ return nil
+}
+
+func (s *sshLexer) ignore() {
+ s.buffer = make([]rune, 0)
+ s.line = s.endbufferLine
+ s.col = s.endbufferCol
+}
+
+func (s *sshLexer) skip() {
+ s.next()
+ s.ignore()
+}
+
+func (s *sshLexer) emit(t tokenType) {
+ s.emitWithValue(t, string(s.buffer))
+}
+
+func (s *sshLexer) emitWithValue(t tokenType, value string) {
+ tok := token{
+ Position: Position{s.line, s.col},
+ typ: t,
+ val: value,
+ }
+ s.tokens <- tok
+ s.ignore()
+}
+
+func (s *sshLexer) peek() rune {
+ if s.inputIdx >= len(s.input) {
+ return eof
+ }
+
+ r := s.input[s.inputIdx]
+ return r
+}
+
+func (s *sshLexer) follow(next string) bool {
+ inputIdx := s.inputIdx
+ for _, expectedRune := range next {
+ if inputIdx >= len(s.input) {
+ return false
+ }
+ r := s.input[inputIdx]
+ inputIdx++
+ if expectedRune != r {
+ return false
+ }
+ }
+ return true
+}
+
+func (s *sshLexer) run() {
+ for state := s.lexVoid; state != nil; {
+ state = state()
+ }
+ close(s.tokens)
+}
+
+func lexSSH(input []byte) chan token {
+ runes := bytes.Runes(input)
+ l := &sshLexer{
+ input: runes,
+ tokens: make(chan token),
+ line: 1,
+ col: 1,
+ endbufferLine: 1,
+ endbufferCol: 1,
+ }
+ go l.run()
+ return l.tokens
+}
diff --git a/vendor/github.com/kevinburke/ssh_config/parser.go b/vendor/github.com/kevinburke/ssh_config/parser.go
new file mode 100644
index 00000000..2b1e718c
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/parser.go
@@ -0,0 +1,200 @@
+package ssh_config
+
+import (
+ "fmt"
+ "strings"
+ "unicode"
+)
+
+type sshParser struct {
+ flow chan token
+ config *Config
+ tokensBuffer []token
+ currentTable []string
+ seenTableKeys []string
+ // /etc/ssh parser or local parser - used to find the default for relative
+ // filepaths in the Include directive
+ system bool
+ depth uint8
+}
+
+type sshParserStateFn func() sshParserStateFn
+
+// Formats and panics an error message based on a token
+func (p *sshParser) raiseErrorf(tok *token, msg string, args ...interface{}) {
+ // TODO this format is ugly
+ panic(tok.Position.String() + ": " + fmt.Sprintf(msg, args...))
+}
+
+func (p *sshParser) raiseError(tok *token, err error) {
+ if err == ErrDepthExceeded {
+ panic(err)
+ }
+ // TODO this format is ugly
+ panic(tok.Position.String() + ": " + err.Error())
+}
+
+func (p *sshParser) run() {
+ for state := p.parseStart; state != nil; {
+ state = state()
+ }
+}
+
+func (p *sshParser) peek() *token {
+ if len(p.tokensBuffer) != 0 {
+ return &(p.tokensBuffer[0])
+ }
+
+ tok, ok := <-p.flow
+ if !ok {
+ return nil
+ }
+ p.tokensBuffer = append(p.tokensBuffer, tok)
+ return &tok
+}
+
+func (p *sshParser) getToken() *token {
+ if len(p.tokensBuffer) != 0 {
+ tok := p.tokensBuffer[0]
+ p.tokensBuffer = p.tokensBuffer[1:]
+ return &tok
+ }
+ tok, ok := <-p.flow
+ if !ok {
+ return nil
+ }
+ return &tok
+}
+
+func (p *sshParser) parseStart() sshParserStateFn {
+ tok := p.peek()
+
+ // end of stream, parsing is finished
+ if tok == nil {
+ return nil
+ }
+
+ switch tok.typ {
+ case tokenComment, tokenEmptyLine:
+ return p.parseComment
+ case tokenKey:
+ return p.parseKV
+ case tokenEOF:
+ return nil
+ default:
+ p.raiseErrorf(tok, fmt.Sprintf("unexpected token %q\n", tok))
+ }
+ return nil
+}
+
+func (p *sshParser) parseKV() sshParserStateFn {
+ key := p.getToken()
+ hasEquals := false
+ val := p.getToken()
+ if val.typ == tokenEquals {
+ hasEquals = true
+ val = p.getToken()
+ }
+ comment := ""
+ tok := p.peek()
+ if tok == nil {
+ tok = &token{typ: tokenEOF}
+ }
+ if tok.typ == tokenComment && tok.Position.Line == val.Position.Line {
+ tok = p.getToken()
+ comment = tok.val
+ }
+ if strings.ToLower(key.val) == "match" {
+ // https://github.com/kevinburke/ssh_config/issues/6
+ p.raiseErrorf(val, "ssh_config: Match directive parsing is unsupported")
+ return nil
+ }
+ if strings.ToLower(key.val) == "host" {
+ strPatterns := strings.Split(val.val, " ")
+ patterns := make([]*Pattern, 0)
+ for i := range strPatterns {
+ if strPatterns[i] == "" {
+ continue
+ }
+ pat, err := NewPattern(strPatterns[i])
+ if err != nil {
+ p.raiseErrorf(val, "Invalid host pattern: %v", err)
+ return nil
+ }
+ patterns = append(patterns, pat)
+ }
+ // val.val at this point could be e.g. "example.com "
+ hostval := strings.TrimRightFunc(val.val, unicode.IsSpace)
+ spaceBeforeComment := val.val[len(hostval):]
+ val.val = hostval
+ p.config.Hosts = append(p.config.Hosts, &Host{
+ Patterns: patterns,
+ Nodes: make([]Node, 0),
+ EOLComment: comment,
+ spaceBeforeComment: spaceBeforeComment,
+ hasEquals: hasEquals,
+ })
+ return p.parseStart
+ }
+ lastHost := p.config.Hosts[len(p.config.Hosts)-1]
+ if strings.ToLower(key.val) == "include" {
+ inc, err := NewInclude(strings.Split(val.val, " "), hasEquals, key.Position, comment, p.system, p.depth+1)
+ if err == ErrDepthExceeded {
+ p.raiseError(val, err)
+ return nil
+ }
+ if err != nil {
+ p.raiseErrorf(val, "Error parsing Include directive: %v", err)
+ return nil
+ }
+ lastHost.Nodes = append(lastHost.Nodes, inc)
+ return p.parseStart
+ }
+ shortval := strings.TrimRightFunc(val.val, unicode.IsSpace)
+ spaceAfterValue := val.val[len(shortval):]
+ kv := &KV{
+ Key: key.val,
+ Value: shortval,
+ spaceAfterValue: spaceAfterValue,
+ Comment: comment,
+ hasEquals: hasEquals,
+ leadingSpace: key.Position.Col - 1,
+ position: key.Position,
+ }
+ lastHost.Nodes = append(lastHost.Nodes, kv)
+ return p.parseStart
+}
+
+func (p *sshParser) parseComment() sshParserStateFn {
+ comment := p.getToken()
+ lastHost := p.config.Hosts[len(p.config.Hosts)-1]
+ lastHost.Nodes = append(lastHost.Nodes, &Empty{
+ Comment: comment.val,
+ // account for the "#" as well
+ leadingSpace: comment.Position.Col - 2,
+ position: comment.Position,
+ })
+ return p.parseStart
+}
+
+func parseSSH(flow chan token, system bool, depth uint8) *Config {
+ // Ensure we consume tokens to completion even if parser exits early
+ defer func() {
+ for range flow {
+ }
+ }()
+
+ result := newConfig()
+ result.position = Position{1, 1}
+ parser := &sshParser{
+ flow: flow,
+ config: result,
+ tokensBuffer: make([]token, 0),
+ currentTable: make([]string, 0),
+ seenTableKeys: make([]string, 0),
+ system: system,
+ depth: depth,
+ }
+ parser.run()
+ return result
+}
diff --git a/vendor/github.com/kevinburke/ssh_config/position.go b/vendor/github.com/kevinburke/ssh_config/position.go
new file mode 100644
index 00000000..e0b5e3fb
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/position.go
@@ -0,0 +1,25 @@
+package ssh_config
+
+import "fmt"
+
+// Position of a document element within a SSH document.
+//
+// Line and Col are both 1-indexed positions for the element's line number and
+// column number, respectively. Values of zero or less will cause Invalid(),
+// to return true.
+type Position struct {
+ Line int // line within the document
+ Col int // column within the line
+}
+
+// String representation of the position.
+// Displays 1-indexed line and column numbers.
+func (p Position) String() string {
+ return fmt.Sprintf("(%d, %d)", p.Line, p.Col)
+}
+
+// Invalid returns whether or not the position is valid (i.e. with negative or
+// null values)
+func (p Position) Invalid() bool {
+ return p.Line <= 0 || p.Col <= 0
+}
diff --git a/vendor/github.com/kevinburke/ssh_config/token.go b/vendor/github.com/kevinburke/ssh_config/token.go
new file mode 100644
index 00000000..a0ecbb2b
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/token.go
@@ -0,0 +1,49 @@
+package ssh_config
+
+import "fmt"
+
+type token struct {
+ Position
+ typ tokenType
+ val string
+}
+
+func (t token) String() string {
+ switch t.typ {
+ case tokenEOF:
+ return "EOF"
+ }
+ return fmt.Sprintf("%q", t.val)
+}
+
+type tokenType int
+
+const (
+ eof = -(iota + 1)
+)
+
+const (
+ tokenError tokenType = iota
+ tokenEOF
+ tokenEmptyLine
+ tokenComment
+ tokenKey
+ tokenEquals
+ tokenString
+)
+
+func isSpace(r rune) bool {
+ return r == ' ' || r == '\t'
+}
+
+func isKeyStartChar(r rune) bool {
+ return !(isSpace(r) || r == '\r' || r == '\n' || r == eof)
+}
+
+// I'm not sure that this is correct
+func isKeyChar(r rune) bool {
+ // Keys start with the first character that isn't whitespace or [ and end
+ // with the last non-whitespace character before the equals sign. Keys
+ // cannot contain a # character."
+ return !(r == '\r' || r == '\n' || r == eof || r == '=')
+}
diff --git a/vendor/github.com/kevinburke/ssh_config/validators.go b/vendor/github.com/kevinburke/ssh_config/validators.go
new file mode 100644
index 00000000..5977f909
--- /dev/null
+++ b/vendor/github.com/kevinburke/ssh_config/validators.go
@@ -0,0 +1,186 @@
+package ssh_config
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// Default returns the default value for the given keyword, for example "22" if
+// the keyword is "Port". Default returns the empty string if the keyword has no
+// default, or if the keyword is unknown. Keyword matching is case-insensitive.
+//
+// Default values are provided by OpenSSH_7.4p1 on a Mac.
+func Default(keyword string) string {
+ return defaults[strings.ToLower(keyword)]
+}
+
+// Arguments where the value must be "yes" or "no" and *only* yes or no.
+var yesnos = map[string]bool{
+ strings.ToLower("BatchMode"): true,
+ strings.ToLower("CanonicalizeFallbackLocal"): true,
+ strings.ToLower("ChallengeResponseAuthentication"): true,
+ strings.ToLower("CheckHostIP"): true,
+ strings.ToLower("ClearAllForwardings"): true,
+ strings.ToLower("Compression"): true,
+ strings.ToLower("EnableSSHKeysign"): true,
+ strings.ToLower("ExitOnForwardFailure"): true,
+ strings.ToLower("ForwardAgent"): true,
+ strings.ToLower("ForwardX11"): true,
+ strings.ToLower("ForwardX11Trusted"): true,
+ strings.ToLower("GatewayPorts"): true,
+ strings.ToLower("GSSAPIAuthentication"): true,
+ strings.ToLower("GSSAPIDelegateCredentials"): true,
+ strings.ToLower("HostbasedAuthentication"): true,
+ strings.ToLower("IdentitiesOnly"): true,
+ strings.ToLower("KbdInteractiveAuthentication"): true,
+ strings.ToLower("NoHostAuthenticationForLocalhost"): true,
+ strings.ToLower("PasswordAuthentication"): true,
+ strings.ToLower("PermitLocalCommand"): true,
+ strings.ToLower("PubkeyAuthentication"): true,
+ strings.ToLower("RhostsRSAAuthentication"): true,
+ strings.ToLower("RSAAuthentication"): true,
+ strings.ToLower("StreamLocalBindUnlink"): true,
+ strings.ToLower("TCPKeepAlive"): true,
+ strings.ToLower("UseKeychain"): true,
+ strings.ToLower("UsePrivilegedPort"): true,
+ strings.ToLower("VisualHostKey"): true,
+}
+
+var uints = map[string]bool{
+ strings.ToLower("CanonicalizeMaxDots"): true,
+ strings.ToLower("CompressionLevel"): true, // 1 to 9
+ strings.ToLower("ConnectionAttempts"): true,
+ strings.ToLower("ConnectTimeout"): true,
+ strings.ToLower("NumberOfPasswordPrompts"): true,
+ strings.ToLower("Port"): true,
+ strings.ToLower("ServerAliveCountMax"): true,
+ strings.ToLower("ServerAliveInterval"): true,
+}
+
+func mustBeYesOrNo(lkey string) bool {
+ return yesnos[lkey]
+}
+
+func mustBeUint(lkey string) bool {
+ return uints[lkey]
+}
+
+func validate(key, val string) error {
+ lkey := strings.ToLower(key)
+ if mustBeYesOrNo(lkey) && (val != "yes" && val != "no") {
+ return fmt.Errorf("ssh_config: value for key %q must be 'yes' or 'no', got %q", key, val)
+ }
+ if mustBeUint(lkey) {
+ _, err := strconv.ParseUint(val, 10, 64)
+ if err != nil {
+ return fmt.Errorf("ssh_config: %v", err)
+ }
+ }
+ return nil
+}
+
+var defaults = map[string]string{
+ strings.ToLower("AddKeysToAgent"): "no",
+ strings.ToLower("AddressFamily"): "any",
+ strings.ToLower("BatchMode"): "no",
+ strings.ToLower("CanonicalizeFallbackLocal"): "yes",
+ strings.ToLower("CanonicalizeHostname"): "no",
+ strings.ToLower("CanonicalizeMaxDots"): "1",
+ strings.ToLower("ChallengeResponseAuthentication"): "yes",
+ strings.ToLower("CheckHostIP"): "yes",
+ // TODO is this still the correct cipher
+ strings.ToLower("Cipher"): "3des",
+ strings.ToLower("Ciphers"): "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc",
+ strings.ToLower("ClearAllForwardings"): "no",
+ strings.ToLower("Compression"): "no",
+ strings.ToLower("CompressionLevel"): "6",
+ strings.ToLower("ConnectionAttempts"): "1",
+ strings.ToLower("ControlMaster"): "no",
+ strings.ToLower("EnableSSHKeysign"): "no",
+ strings.ToLower("EscapeChar"): "~",
+ strings.ToLower("ExitOnForwardFailure"): "no",
+ strings.ToLower("FingerprintHash"): "sha256",
+ strings.ToLower("ForwardAgent"): "no",
+ strings.ToLower("ForwardX11"): "no",
+ strings.ToLower("ForwardX11Timeout"): "20m",
+ strings.ToLower("ForwardX11Trusted"): "no",
+ strings.ToLower("GatewayPorts"): "no",
+ strings.ToLower("GlobalKnownHostsFile"): "/etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2",
+ strings.ToLower("GSSAPIAuthentication"): "no",
+ strings.ToLower("GSSAPIDelegateCredentials"): "no",
+ strings.ToLower("HashKnownHosts"): "no",
+ strings.ToLower("HostbasedAuthentication"): "no",
+
+ strings.ToLower("HostbasedKeyTypes"): "ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,ssh-rsa",
+ strings.ToLower("HostKeyAlgorithms"): "ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,ssh-rsa",
+ // HostName has a dynamic default (the value passed at the command line).
+
+ strings.ToLower("IdentitiesOnly"): "no",
+ strings.ToLower("IdentityFile"): "~/.ssh/identity",
+
+ // IPQoS has a dynamic default based on interactive or non-interactive
+ // sessions.
+
+ strings.ToLower("KbdInteractiveAuthentication"): "yes",
+
+ strings.ToLower("KexAlgorithms"): "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1",
+ strings.ToLower("LogLevel"): "INFO",
+ strings.ToLower("MACs"): "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
+
+ strings.ToLower("NoHostAuthenticationForLocalhost"): "no",
+ strings.ToLower("NumberOfPasswordPrompts"): "3",
+ strings.ToLower("PasswordAuthentication"): "yes",
+ strings.ToLower("PermitLocalCommand"): "no",
+ strings.ToLower("Port"): "22",
+
+ strings.ToLower("PreferredAuthentications"): "gssapi-with-mic,hostbased,publickey,keyboard-interactive,password",
+ strings.ToLower("Protocol"): "2",
+ strings.ToLower("ProxyUseFdpass"): "no",
+ strings.ToLower("PubkeyAcceptedKeyTypes"): "ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,ssh-rsa",
+ strings.ToLower("PubkeyAuthentication"): "yes",
+ strings.ToLower("RekeyLimit"): "default none",
+ strings.ToLower("RhostsRSAAuthentication"): "no",
+ strings.ToLower("RSAAuthentication"): "yes",
+
+ strings.ToLower("ServerAliveCountMax"): "3",
+ strings.ToLower("ServerAliveInterval"): "0",
+ strings.ToLower("StreamLocalBindMask"): "0177",
+ strings.ToLower("StreamLocalBindUnlink"): "no",
+ strings.ToLower("StrictHostKeyChecking"): "ask",
+ strings.ToLower("TCPKeepAlive"): "yes",
+ strings.ToLower("Tunnel"): "no",
+ strings.ToLower("TunnelDevice"): "any:any",
+ strings.ToLower("UpdateHostKeys"): "no",
+ strings.ToLower("UseKeychain"): "no",
+ strings.ToLower("UsePrivilegedPort"): "no",
+
+ strings.ToLower("UserKnownHostsFile"): "~/.ssh/known_hosts ~/.ssh/known_hosts2",
+ strings.ToLower("VerifyHostKeyDNS"): "no",
+ strings.ToLower("VisualHostKey"): "no",
+ strings.ToLower("XAuthLocation"): "/usr/X11R6/bin/xauth",
+}
+
+// these identities are used for SSH protocol 2
+var defaultProtocol2Identities = []string{
+ "~/.ssh/id_dsa",
+ "~/.ssh/id_ecdsa",
+ "~/.ssh/id_ed25519",
+ "~/.ssh/id_rsa",
+}
+
+// these directives support multiple items that can be collected
+// across multiple files
+var pluralDirectives = map[string]bool{
+ "CertificateFile": true,
+ "IdentityFile": true,
+ "DynamicForward": true,
+ "RemoteForward": true,
+ "SendEnv": true,
+ "SetEnv": true,
+}
+
+// SupportsMultiple reports whether a directive can be specified multiple times.
+func SupportsMultiple(key string) bool {
+ return pluralDirectives[strings.ToLower(key)]
+}
diff --git a/vendor/github.com/pjbgf/sha1cd/Dockerfile.arm b/vendor/github.com/pjbgf/sha1cd/Dockerfile.arm
new file mode 100644
index 00000000..99761296
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/Dockerfile.arm
@@ -0,0 +1,23 @@
+FROM golang:1.20@sha256:2edf6aab2d57644f3fe7407132a0d1770846867465a39c2083770cf62734b05d
+
+ENV GOOS=linux
+ENV GOARCH=arm
+ENV CGO_ENABLED=1
+ENV CC=arm-linux-gnueabihf-gcc
+ENV PATH="/go/bin/${GOOS}_${GOARCH}:${PATH}"
+ENV PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig
+
+RUN dpkg --add-architecture armhf \
+ && apt update \
+ && apt install -y --no-install-recommends \
+ upx \
+ gcc-arm-linux-gnueabihf \
+ libc6-dev-armhf-cross \
+ pkg-config \
+ && rm -rf /var/lib/apt/lists/*
+
+COPY . /src/workdir
+
+WORKDIR /src/workdir
+
+RUN go build ./...
diff --git a/vendor/github.com/pjbgf/sha1cd/Dockerfile.arm64 b/vendor/github.com/pjbgf/sha1cd/Dockerfile.arm64
new file mode 100644
index 00000000..66bd0947
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/Dockerfile.arm64
@@ -0,0 +1,23 @@
+FROM golang:1.20@sha256:2edf6aab2d57644f3fe7407132a0d1770846867465a39c2083770cf62734b05d
+
+ENV GOOS=linux
+ENV GOARCH=arm64
+ENV CGO_ENABLED=1
+ENV CC=aarch64-linux-gnu-gcc
+ENV PATH="/go/bin/${GOOS}_${GOARCH}:${PATH}"
+ENV PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig
+
+# install build & runtime dependencies
+RUN dpkg --add-architecture arm64 \
+ && apt update \
+ && apt install -y --no-install-recommends \
+ gcc-aarch64-linux-gnu \
+ libc6-dev-arm64-cross \
+ pkg-config \
+ && rm -rf /var/lib/apt/lists/*
+
+COPY . /src/workdir
+
+WORKDIR /src/workdir
+
+RUN go build ./...
diff --git a/vendor/github.com/pjbgf/sha1cd/LICENSE b/vendor/github.com/pjbgf/sha1cd/LICENSE
new file mode 100644
index 00000000..261eeb9e
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ 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 "[]"
+ 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
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ 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.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/pjbgf/sha1cd/Makefile b/vendor/github.com/pjbgf/sha1cd/Makefile
new file mode 100644
index 00000000..b24f2cba
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/Makefile
@@ -0,0 +1,40 @@
+FUZZ_TIME ?= 1m
+
+export CGO_ENABLED := 1
+
+.PHONY: test
+test:
+ go test ./...
+
+.PHONY: bench
+bench:
+ go test -benchmem -run=^$$ -bench ^Benchmark ./...
+
+.PHONY: fuzz
+fuzz:
+ go test -tags gofuzz -fuzz=. -fuzztime=$(FUZZ_TIME) ./test/
+
+# Cross build project in arm/v7.
+build-arm:
+ docker build -t sha1cd-arm -f Dockerfile.arm .
+ docker run --rm sha1cd-arm
+
+# Cross build project in arm64.
+build-arm64:
+ docker build -t sha1cd-arm64 -f Dockerfile.arm64 .
+ docker run --rm sha1cd-arm64
+
+# Build with cgo disabled.
+build-nocgo:
+ CGO_ENABLED=0 go build ./cgo
+
+# Run cross-compilation to assure supported architectures.
+cross-build: build-arm build-arm64 build-nocgo
+
+generate:
+ go run sha1cdblock_amd64_asm.go -out sha1cdblock_amd64.s
+ sed -i 's;&\samd64;&\n// +build !noasm,gc,amd64;g' sha1cdblock_amd64.s
+
+verify: generate
+ git diff --exit-code
+ go vet ./...
diff --git a/vendor/github.com/pjbgf/sha1cd/README.md b/vendor/github.com/pjbgf/sha1cd/README.md
new file mode 100644
index 00000000..378cf78c
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/README.md
@@ -0,0 +1,58 @@
+# sha1cd
+
+A Go implementation of SHA1 with counter-cryptanalysis, which detects
+collision attacks.
+
+The `cgo/lib` code is a carbon copy of the [original code], based on
+the award winning [white paper] by Marc Stevens.
+
+The Go implementation is largely based off Go's generic sha1.
+At present no SIMD optimisations have been implemented.
+
+## Usage
+
+`sha1cd` can be used as a drop-in replacement for `crypto/sha1`:
+
+```golang
+import "github.com/pjbgf/sha1cd"
+
+func test(){
+ data := []byte("data to be sha1 hashed")
+ h := sha1cd.Sum(data)
+ fmt.Printf("hash: %q\n", hex.EncodeToString(h))
+}
+```
+
+To obtain information as to whether a collision was found, use the
+func `CollisionResistantSum`.
+
+```golang
+import "github.com/pjbgf/sha1cd"
+
+func test(){
+ data := []byte("data to be sha1 hashed")
+ h, col := sha1cd.CollisionResistantSum(data)
+ if col {
+ fmt.Println("collision found!")
+ }
+ fmt.Printf("hash: %q", hex.EncodeToString(h))
+}
+```
+
+Note that the algorithm will automatically avoid collision, by
+extending the SHA1 to 240-steps, instead of 80 when a collision
+attempt is detected. Therefore, inputs that contains the unavoidable
+bit conditions will yield a different hash from `sha1cd`, when compared
+with results using `crypto/sha1`. Valid inputs will have matching the outputs.
+
+## References
+- https://shattered.io/
+- https://github.com/cr-marcstevens/sha1collisiondetection
+- https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Secure-Hashing#shavs
+
+## Use of the Original Implementation
+- https://github.com/git/git/commit/28dc98e343ca4eb370a29ceec4c19beac9b5c01e
+- https://github.com/libgit2/libgit2/pull/4136
+
+[original code]: https://github.com/cr-marcstevens/sha1collisiondetection
+[white paper]: https://marc-stevens.nl/research/papers/C13-S.pdf
diff --git a/vendor/github.com/pjbgf/sha1cd/detection.go b/vendor/github.com/pjbgf/sha1cd/detection.go
new file mode 100644
index 00000000..a1458748
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/detection.go
@@ -0,0 +1,11 @@
+package sha1cd
+
+import "hash"
+
+type CollisionResistantHash interface {
+ // CollisionResistantSum extends on Sum by returning an additional boolean
+ // which indicates whether a collision was found during the hashing process.
+ CollisionResistantSum(b []byte) ([]byte, bool)
+
+ hash.Hash
+}
diff --git a/vendor/github.com/pjbgf/sha1cd/internal/const.go b/vendor/github.com/pjbgf/sha1cd/internal/const.go
new file mode 100644
index 00000000..944a131d
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/internal/const.go
@@ -0,0 +1,42 @@
+package shared
+
+const (
+ // Constants for the SHA-1 hash function.
+ K0 = 0x5A827999
+ K1 = 0x6ED9EBA1
+ K2 = 0x8F1BBCDC
+ K3 = 0xCA62C1D6
+
+ // Initial values for the buffer variables: h0, h1, h2, h3, h4.
+ Init0 = 0x67452301
+ Init1 = 0xEFCDAB89
+ Init2 = 0x98BADCFE
+ Init3 = 0x10325476
+ Init4 = 0xC3D2E1F0
+
+ // Initial values for the temporary variables (ihvtmp0, ihvtmp1, ihvtmp2, ihvtmp3, ihvtmp4) during the SHA recompression step.
+ InitTmp0 = 0xD5
+ InitTmp1 = 0x394
+ InitTmp2 = 0x8152A8
+ InitTmp3 = 0x0
+ InitTmp4 = 0xA7ECE0
+
+ // SHA1 contains 2 buffers, each based off 5 32-bit words.
+ WordBuffers = 5
+
+ // The output of SHA1 is 20 bytes (160 bits).
+ Size = 20
+
+ // Rounds represents the number of steps required to process each chunk.
+ Rounds = 80
+
+ // SHA1 processes the input data in chunks. Each chunk contains 64 bytes.
+ Chunk = 64
+
+ // The number of pre-step compression state to store.
+ // Currently there are 3 pre-step compression states required: 0, 58, 65.
+ PreStepState = 3
+
+ Magic = "shacd\x01"
+ MarshaledSize = len(Magic) + 5*4 + Chunk + 8
+)
diff --git a/vendor/github.com/pjbgf/sha1cd/sha1cd.go b/vendor/github.com/pjbgf/sha1cd/sha1cd.go
new file mode 100644
index 00000000..a69e480e
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/sha1cd.go
@@ -0,0 +1,227 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sha1cd implements collision detection based on the whitepaper
+// Counter-cryptanalysis from Marc Stevens. The original ubc implementation
+// was done by Marc Stevens and Dan Shumow, and can be found at:
+// https://github.com/cr-marcstevens/sha1collisiondetection
+package sha1cd
+
+// This SHA1 implementation is based on Go's generic SHA1.
+// Original: https://github.com/golang/go/blob/master/src/crypto/sha1/sha1.go
+
+import (
+ "crypto"
+ "encoding/binary"
+ "errors"
+ "hash"
+
+ shared "github.com/pjbgf/sha1cd/internal"
+)
+
+func init() {
+ crypto.RegisterHash(crypto.SHA1, New)
+}
+
+// The size of a SHA-1 checksum in bytes.
+const Size = shared.Size
+
+// The blocksize of SHA-1 in bytes.
+const BlockSize = shared.Chunk
+
+// digest represents the partial evaluation of a checksum.
+type digest struct {
+ h [shared.WordBuffers]uint32
+ x [shared.Chunk]byte
+ nx int
+ len uint64
+
+ // col defines whether a collision has been found.
+ col bool
+ blockFunc func(dig *digest, p []byte)
+}
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+ b := make([]byte, 0, shared.MarshaledSize)
+ b = append(b, shared.Magic...)
+ b = appendUint32(b, d.h[0])
+ b = appendUint32(b, d.h[1])
+ b = appendUint32(b, d.h[2])
+ b = appendUint32(b, d.h[3])
+ b = appendUint32(b, d.h[4])
+ b = append(b, d.x[:d.nx]...)
+ b = b[:len(b)+len(d.x)-d.nx] // already zero
+ b = appendUint64(b, d.len)
+ return b, nil
+}
+
+func appendUint32(b []byte, v uint32) []byte {
+ return append(b,
+ byte(v>>24),
+ byte(v>>16),
+ byte(v>>8),
+ byte(v),
+ )
+}
+
+func appendUint64(b []byte, v uint64) []byte {
+ return append(b,
+ byte(v>>56),
+ byte(v>>48),
+ byte(v>>40),
+ byte(v>>32),
+ byte(v>>24),
+ byte(v>>16),
+ byte(v>>8),
+ byte(v),
+ )
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+ if len(b) < len(shared.Magic) || string(b[:len(shared.Magic)]) != shared.Magic {
+ return errors.New("crypto/sha1: invalid hash state identifier")
+ }
+ if len(b) != shared.MarshaledSize {
+ return errors.New("crypto/sha1: invalid hash state size")
+ }
+ b = b[len(shared.Magic):]
+ b, d.h[0] = consumeUint32(b)
+ b, d.h[1] = consumeUint32(b)
+ b, d.h[2] = consumeUint32(b)
+ b, d.h[3] = consumeUint32(b)
+ b, d.h[4] = consumeUint32(b)
+ b = b[copy(d.x[:], b):]
+ b, d.len = consumeUint64(b)
+ d.nx = int(d.len % shared.Chunk)
+ return nil
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+ _ = b[7]
+ x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[shared.WordBuffers])<<16 | uint64(b[4])<<24 |
+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+ return b[8:], x
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+ _ = b[3]
+ x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+ return b[4:], x
+}
+
+func (d *digest) Reset() {
+ d.h[0] = shared.Init0
+ d.h[1] = shared.Init1
+ d.h[2] = shared.Init2
+ d.h[3] = shared.Init3
+ d.h[4] = shared.Init4
+ d.nx = 0
+ d.len = 0
+
+ d.col = false
+}
+
+// New returns a new hash.Hash computing the SHA1 checksum. The Hash also
+// implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
+// marshal and unmarshal the internal state of the hash.
+func New() hash.Hash {
+ d := new(digest)
+
+ d.blockFunc = block
+ d.Reset()
+ return d
+}
+
+// NewGeneric is equivalent to New but uses the Go generic implementation,
+// avoiding any processor-specific optimizations.
+func NewGeneric() hash.Hash {
+ d := new(digest)
+
+ d.blockFunc = blockGeneric
+ d.Reset()
+ return d
+}
+
+func (d *digest) Size() int { return Size }
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Write(p []byte) (nn int, err error) {
+ if len(p) == 0 {
+ return
+ }
+
+ nn = len(p)
+ d.len += uint64(nn)
+ if d.nx > 0 {
+ n := copy(d.x[d.nx:], p)
+ d.nx += n
+ if d.nx == shared.Chunk {
+ d.blockFunc(d, d.x[:])
+ d.nx = 0
+ }
+ p = p[n:]
+ }
+ if len(p) >= shared.Chunk {
+ n := len(p) &^ (shared.Chunk - 1)
+ d.blockFunc(d, p[:n])
+ p = p[n:]
+ }
+ if len(p) > 0 {
+ d.nx = copy(d.x[:], p)
+ }
+ return
+}
+
+func (d *digest) Sum(in []byte) []byte {
+ // Make a copy of d so that caller can keep writing and summing.
+ d0 := *d
+ hash := d0.checkSum()
+ return append(in, hash[:]...)
+}
+
+func (d *digest) checkSum() [Size]byte {
+ len := d.len
+ // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
+ var tmp [64]byte
+ tmp[0] = 0x80
+ if len%64 < 56 {
+ d.Write(tmp[0 : 56-len%64])
+ } else {
+ d.Write(tmp[0 : 64+56-len%64])
+ }
+
+ // Length in bits.
+ len <<= 3
+ binary.BigEndian.PutUint64(tmp[:], len)
+ d.Write(tmp[0:8])
+
+ if d.nx != 0 {
+ panic("d.nx != 0")
+ }
+
+ var digest [Size]byte
+
+ binary.BigEndian.PutUint32(digest[0:], d.h[0])
+ binary.BigEndian.PutUint32(digest[4:], d.h[1])
+ binary.BigEndian.PutUint32(digest[8:], d.h[2])
+ binary.BigEndian.PutUint32(digest[12:], d.h[3])
+ binary.BigEndian.PutUint32(digest[16:], d.h[4])
+
+ return digest
+}
+
+// Sum returns the SHA-1 checksum of the data.
+func Sum(data []byte) ([Size]byte, bool) {
+ d := New().(*digest)
+ d.Write(data)
+ return d.checkSum(), d.col
+}
+
+func (d *digest) CollisionResistantSum(in []byte) ([]byte, bool) {
+ // Make a copy of d so that caller can keep writing and summing.
+ d0 := *d
+ hash := d0.checkSum()
+ return append(in, hash[:]...), d0.col
+}
diff --git a/vendor/github.com/pjbgf/sha1cd/sha1cdblock_amd64.go b/vendor/github.com/pjbgf/sha1cd/sha1cdblock_amd64.go
new file mode 100644
index 00000000..95e08308
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/sha1cdblock_amd64.go
@@ -0,0 +1,50 @@
+//go:build !noasm && gc && amd64
+// +build !noasm,gc,amd64
+
+package sha1cd
+
+import (
+ "math"
+ "unsafe"
+
+ shared "github.com/pjbgf/sha1cd/internal"
+)
+
+type sliceHeader struct {
+ base uintptr
+ len int
+ cap int
+}
+
+// blockAMD64 hashes the message p into the current state in dig.
+// Both m1 and cs are used to store intermediate results which are used by the collision detection logic.
+//
+//go:noescape
+func blockAMD64(dig *digest, p sliceHeader, m1 []uint32, cs [][5]uint32)
+
+func block(dig *digest, p []byte) {
+ m1 := [shared.Rounds]uint32{}
+ cs := [shared.PreStepState][shared.WordBuffers]uint32{}
+
+ for len(p) >= shared.Chunk {
+ // Only send a block to be processed, as the collission detection
+ // works on a block by block basis.
+ ips := sliceHeader{
+ base: uintptr(unsafe.Pointer(&p[0])),
+ len: int(math.Min(float64(len(p)), float64(shared.Chunk))),
+ cap: shared.Chunk,
+ }
+
+ blockAMD64(dig, ips, m1[:], cs[:])
+
+ col := checkCollision(m1, cs, dig.h)
+ if col {
+ dig.col = true
+
+ blockAMD64(dig, ips, m1[:], cs[:])
+ blockAMD64(dig, ips, m1[:], cs[:])
+ }
+
+ p = p[shared.Chunk:]
+ }
+}
diff --git a/vendor/github.com/pjbgf/sha1cd/sha1cdblock_amd64.s b/vendor/github.com/pjbgf/sha1cd/sha1cdblock_amd64.s
new file mode 100644
index 00000000..86f9821c
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/sha1cdblock_amd64.s
@@ -0,0 +1,2274 @@
+// Code generated by command: go run sha1cdblock_amd64_asm.go -out sha1cdblock_amd64.s. DO NOT EDIT.
+
+//go:build !noasm && gc && amd64
+// +build !noasm,gc,amd64
+
+#include "textflag.h"
+
+// func blockAMD64(dig *digest, p []byte, m1 []uint32, cs [][5]uint32)
+TEXT ·blockAMD64(SB), NOSPLIT, $64-80
+ MOVQ dig+0(FP), R8
+ MOVQ p_base+8(FP), DI
+ MOVQ p_len+16(FP), DX
+ SHRQ $+6, DX
+ SHLQ $+6, DX
+ LEAQ (DI)(DX*1), SI
+
+ // Load h0, h1, h2, h3, h4.
+ MOVL (R8), AX
+ MOVL 4(R8), BX
+ MOVL 8(R8), CX
+ MOVL 12(R8), DX
+ MOVL 16(R8), BP
+
+ // len(p) >= chunk
+ CMPQ DI, SI
+ JEQ end
+
+loop:
+ // Initialize registers a, b, c, d, e.
+ MOVL AX, R10
+ MOVL BX, R11
+ MOVL CX, R12
+ MOVL DX, R13
+ MOVL BP, R14
+
+ // ROUND1 (steps 0-15)
+ // Load cs
+ MOVQ cs_base+56(FP), R8
+ MOVL R10, (R8)
+ MOVL R11, 4(R8)
+ MOVL R12, 8(R8)
+ MOVL R13, 12(R8)
+ MOVL R14, 16(R8)
+
+ // ROUND1(0)
+ // LOAD
+ MOVL (DI), R9
+ BSWAPL R9
+ MOVL R9, (SP)
+
+ // FUNC1
+ MOVL R13, R15
+ XORL R12, R15
+ ANDL R11, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL (SP), R9
+ MOVL R9, (R8)
+
+ // ROUND1(1)
+ // LOAD
+ MOVL 4(DI), R9
+ BSWAPL R9
+ MOVL R9, 4(SP)
+
+ // FUNC1
+ MOVL R12, R15
+ XORL R11, R15
+ ANDL R10, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 4(SP), R9
+ MOVL R9, 4(R8)
+
+ // ROUND1(2)
+ // LOAD
+ MOVL 8(DI), R9
+ BSWAPL R9
+ MOVL R9, 8(SP)
+
+ // FUNC1
+ MOVL R11, R15
+ XORL R10, R15
+ ANDL R14, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 8(SP), R9
+ MOVL R9, 8(R8)
+
+ // ROUND1(3)
+ // LOAD
+ MOVL 12(DI), R9
+ BSWAPL R9
+ MOVL R9, 12(SP)
+
+ // FUNC1
+ MOVL R10, R15
+ XORL R14, R15
+ ANDL R13, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 12(SP), R9
+ MOVL R9, 12(R8)
+
+ // ROUND1(4)
+ // LOAD
+ MOVL 16(DI), R9
+ BSWAPL R9
+ MOVL R9, 16(SP)
+
+ // FUNC1
+ MOVL R14, R15
+ XORL R13, R15
+ ANDL R12, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 16(SP), R9
+ MOVL R9, 16(R8)
+
+ // ROUND1(5)
+ // LOAD
+ MOVL 20(DI), R9
+ BSWAPL R9
+ MOVL R9, 20(SP)
+
+ // FUNC1
+ MOVL R13, R15
+ XORL R12, R15
+ ANDL R11, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 20(SP), R9
+ MOVL R9, 20(R8)
+
+ // ROUND1(6)
+ // LOAD
+ MOVL 24(DI), R9
+ BSWAPL R9
+ MOVL R9, 24(SP)
+
+ // FUNC1
+ MOVL R12, R15
+ XORL R11, R15
+ ANDL R10, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 24(SP), R9
+ MOVL R9, 24(R8)
+
+ // ROUND1(7)
+ // LOAD
+ MOVL 28(DI), R9
+ BSWAPL R9
+ MOVL R9, 28(SP)
+
+ // FUNC1
+ MOVL R11, R15
+ XORL R10, R15
+ ANDL R14, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 28(SP), R9
+ MOVL R9, 28(R8)
+
+ // ROUND1(8)
+ // LOAD
+ MOVL 32(DI), R9
+ BSWAPL R9
+ MOVL R9, 32(SP)
+
+ // FUNC1
+ MOVL R10, R15
+ XORL R14, R15
+ ANDL R13, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 32(SP), R9
+ MOVL R9, 32(R8)
+
+ // ROUND1(9)
+ // LOAD
+ MOVL 36(DI), R9
+ BSWAPL R9
+ MOVL R9, 36(SP)
+
+ // FUNC1
+ MOVL R14, R15
+ XORL R13, R15
+ ANDL R12, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 36(SP), R9
+ MOVL R9, 36(R8)
+
+ // ROUND1(10)
+ // LOAD
+ MOVL 40(DI), R9
+ BSWAPL R9
+ MOVL R9, 40(SP)
+
+ // FUNC1
+ MOVL R13, R15
+ XORL R12, R15
+ ANDL R11, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 40(SP), R9
+ MOVL R9, 40(R8)
+
+ // ROUND1(11)
+ // LOAD
+ MOVL 44(DI), R9
+ BSWAPL R9
+ MOVL R9, 44(SP)
+
+ // FUNC1
+ MOVL R12, R15
+ XORL R11, R15
+ ANDL R10, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 44(SP), R9
+ MOVL R9, 44(R8)
+
+ // ROUND1(12)
+ // LOAD
+ MOVL 48(DI), R9
+ BSWAPL R9
+ MOVL R9, 48(SP)
+
+ // FUNC1
+ MOVL R11, R15
+ XORL R10, R15
+ ANDL R14, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 48(SP), R9
+ MOVL R9, 48(R8)
+
+ // ROUND1(13)
+ // LOAD
+ MOVL 52(DI), R9
+ BSWAPL R9
+ MOVL R9, 52(SP)
+
+ // FUNC1
+ MOVL R10, R15
+ XORL R14, R15
+ ANDL R13, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 52(SP), R9
+ MOVL R9, 52(R8)
+
+ // ROUND1(14)
+ // LOAD
+ MOVL 56(DI), R9
+ BSWAPL R9
+ MOVL R9, 56(SP)
+
+ // FUNC1
+ MOVL R14, R15
+ XORL R13, R15
+ ANDL R12, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 56(SP), R9
+ MOVL R9, 56(R8)
+
+ // ROUND1(15)
+ // LOAD
+ MOVL 60(DI), R9
+ BSWAPL R9
+ MOVL R9, 60(SP)
+
+ // FUNC1
+ MOVL R13, R15
+ XORL R12, R15
+ ANDL R11, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 60(SP), R9
+ MOVL R9, 60(R8)
+
+ // ROUND1x (steps 16-19) - same as ROUND1 but with no data load.
+ // ROUND1x(16)
+ // SHUFFLE
+ MOVL (SP), R9
+ XORL 52(SP), R9
+ XORL 32(SP), R9
+ XORL 8(SP), R9
+ ROLL $+1, R9
+ MOVL R9, (SP)
+
+ // FUNC1
+ MOVL R12, R15
+ XORL R11, R15
+ ANDL R10, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL (SP), R9
+ MOVL R9, 64(R8)
+
+ // ROUND1x(17)
+ // SHUFFLE
+ MOVL 4(SP), R9
+ XORL 56(SP), R9
+ XORL 36(SP), R9
+ XORL 12(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 4(SP)
+
+ // FUNC1
+ MOVL R11, R15
+ XORL R10, R15
+ ANDL R14, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 4(SP), R9
+ MOVL R9, 68(R8)
+
+ // ROUND1x(18)
+ // SHUFFLE
+ MOVL 8(SP), R9
+ XORL 60(SP), R9
+ XORL 40(SP), R9
+ XORL 16(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 8(SP)
+
+ // FUNC1
+ MOVL R10, R15
+ XORL R14, R15
+ ANDL R13, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 8(SP), R9
+ MOVL R9, 72(R8)
+
+ // ROUND1x(19)
+ // SHUFFLE
+ MOVL 12(SP), R9
+ XORL (SP), R9
+ XORL 44(SP), R9
+ XORL 20(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 12(SP)
+
+ // FUNC1
+ MOVL R14, R15
+ XORL R13, R15
+ ANDL R12, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 1518500249(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 12(SP), R9
+ MOVL R9, 76(R8)
+
+ // ROUND2 (steps 20-39)
+ // ROUND2(20)
+ // SHUFFLE
+ MOVL 16(SP), R9
+ XORL 4(SP), R9
+ XORL 48(SP), R9
+ XORL 24(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 16(SP)
+
+ // FUNC2
+ MOVL R11, R15
+ XORL R12, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 16(SP), R9
+ MOVL R9, 80(R8)
+
+ // ROUND2(21)
+ // SHUFFLE
+ MOVL 20(SP), R9
+ XORL 8(SP), R9
+ XORL 52(SP), R9
+ XORL 28(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 20(SP)
+
+ // FUNC2
+ MOVL R10, R15
+ XORL R11, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 20(SP), R9
+ MOVL R9, 84(R8)
+
+ // ROUND2(22)
+ // SHUFFLE
+ MOVL 24(SP), R9
+ XORL 12(SP), R9
+ XORL 56(SP), R9
+ XORL 32(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 24(SP)
+
+ // FUNC2
+ MOVL R14, R15
+ XORL R10, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 24(SP), R9
+ MOVL R9, 88(R8)
+
+ // ROUND2(23)
+ // SHUFFLE
+ MOVL 28(SP), R9
+ XORL 16(SP), R9
+ XORL 60(SP), R9
+ XORL 36(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 28(SP)
+
+ // FUNC2
+ MOVL R13, R15
+ XORL R14, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 28(SP), R9
+ MOVL R9, 92(R8)
+
+ // ROUND2(24)
+ // SHUFFLE
+ MOVL 32(SP), R9
+ XORL 20(SP), R9
+ XORL (SP), R9
+ XORL 40(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 32(SP)
+
+ // FUNC2
+ MOVL R12, R15
+ XORL R13, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 32(SP), R9
+ MOVL R9, 96(R8)
+
+ // ROUND2(25)
+ // SHUFFLE
+ MOVL 36(SP), R9
+ XORL 24(SP), R9
+ XORL 4(SP), R9
+ XORL 44(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 36(SP)
+
+ // FUNC2
+ MOVL R11, R15
+ XORL R12, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 36(SP), R9
+ MOVL R9, 100(R8)
+
+ // ROUND2(26)
+ // SHUFFLE
+ MOVL 40(SP), R9
+ XORL 28(SP), R9
+ XORL 8(SP), R9
+ XORL 48(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 40(SP)
+
+ // FUNC2
+ MOVL R10, R15
+ XORL R11, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 40(SP), R9
+ MOVL R9, 104(R8)
+
+ // ROUND2(27)
+ // SHUFFLE
+ MOVL 44(SP), R9
+ XORL 32(SP), R9
+ XORL 12(SP), R9
+ XORL 52(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 44(SP)
+
+ // FUNC2
+ MOVL R14, R15
+ XORL R10, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 44(SP), R9
+ MOVL R9, 108(R8)
+
+ // ROUND2(28)
+ // SHUFFLE
+ MOVL 48(SP), R9
+ XORL 36(SP), R9
+ XORL 16(SP), R9
+ XORL 56(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 48(SP)
+
+ // FUNC2
+ MOVL R13, R15
+ XORL R14, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 48(SP), R9
+ MOVL R9, 112(R8)
+
+ // ROUND2(29)
+ // SHUFFLE
+ MOVL 52(SP), R9
+ XORL 40(SP), R9
+ XORL 20(SP), R9
+ XORL 60(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 52(SP)
+
+ // FUNC2
+ MOVL R12, R15
+ XORL R13, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 52(SP), R9
+ MOVL R9, 116(R8)
+
+ // ROUND2(30)
+ // SHUFFLE
+ MOVL 56(SP), R9
+ XORL 44(SP), R9
+ XORL 24(SP), R9
+ XORL (SP), R9
+ ROLL $+1, R9
+ MOVL R9, 56(SP)
+
+ // FUNC2
+ MOVL R11, R15
+ XORL R12, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 56(SP), R9
+ MOVL R9, 120(R8)
+
+ // ROUND2(31)
+ // SHUFFLE
+ MOVL 60(SP), R9
+ XORL 48(SP), R9
+ XORL 28(SP), R9
+ XORL 4(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 60(SP)
+
+ // FUNC2
+ MOVL R10, R15
+ XORL R11, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 60(SP), R9
+ MOVL R9, 124(R8)
+
+ // ROUND2(32)
+ // SHUFFLE
+ MOVL (SP), R9
+ XORL 52(SP), R9
+ XORL 32(SP), R9
+ XORL 8(SP), R9
+ ROLL $+1, R9
+ MOVL R9, (SP)
+
+ // FUNC2
+ MOVL R14, R15
+ XORL R10, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL (SP), R9
+ MOVL R9, 128(R8)
+
+ // ROUND2(33)
+ // SHUFFLE
+ MOVL 4(SP), R9
+ XORL 56(SP), R9
+ XORL 36(SP), R9
+ XORL 12(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 4(SP)
+
+ // FUNC2
+ MOVL R13, R15
+ XORL R14, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 4(SP), R9
+ MOVL R9, 132(R8)
+
+ // ROUND2(34)
+ // SHUFFLE
+ MOVL 8(SP), R9
+ XORL 60(SP), R9
+ XORL 40(SP), R9
+ XORL 16(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 8(SP)
+
+ // FUNC2
+ MOVL R12, R15
+ XORL R13, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 8(SP), R9
+ MOVL R9, 136(R8)
+
+ // ROUND2(35)
+ // SHUFFLE
+ MOVL 12(SP), R9
+ XORL (SP), R9
+ XORL 44(SP), R9
+ XORL 20(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 12(SP)
+
+ // FUNC2
+ MOVL R11, R15
+ XORL R12, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 12(SP), R9
+ MOVL R9, 140(R8)
+
+ // ROUND2(36)
+ // SHUFFLE
+ MOVL 16(SP), R9
+ XORL 4(SP), R9
+ XORL 48(SP), R9
+ XORL 24(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 16(SP)
+
+ // FUNC2
+ MOVL R10, R15
+ XORL R11, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 16(SP), R9
+ MOVL R9, 144(R8)
+
+ // ROUND2(37)
+ // SHUFFLE
+ MOVL 20(SP), R9
+ XORL 8(SP), R9
+ XORL 52(SP), R9
+ XORL 28(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 20(SP)
+
+ // FUNC2
+ MOVL R14, R15
+ XORL R10, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 20(SP), R9
+ MOVL R9, 148(R8)
+
+ // ROUND2(38)
+ // SHUFFLE
+ MOVL 24(SP), R9
+ XORL 12(SP), R9
+ XORL 56(SP), R9
+ XORL 32(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 24(SP)
+
+ // FUNC2
+ MOVL R13, R15
+ XORL R14, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 24(SP), R9
+ MOVL R9, 152(R8)
+
+ // ROUND2(39)
+ // SHUFFLE
+ MOVL 28(SP), R9
+ XORL 16(SP), R9
+ XORL 60(SP), R9
+ XORL 36(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 28(SP)
+
+ // FUNC2
+ MOVL R12, R15
+ XORL R13, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 1859775393(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 28(SP), R9
+ MOVL R9, 156(R8)
+
+ // ROUND3 (steps 40-59)
+ // ROUND3(40)
+ // SHUFFLE
+ MOVL 32(SP), R9
+ XORL 20(SP), R9
+ XORL (SP), R9
+ XORL 40(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 32(SP)
+
+ // FUNC3
+ MOVL R11, R8
+ ORL R12, R8
+ ANDL R13, R8
+ MOVL R11, R15
+ ANDL R12, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 32(SP), R9
+ MOVL R9, 160(R8)
+
+ // ROUND3(41)
+ // SHUFFLE
+ MOVL 36(SP), R9
+ XORL 24(SP), R9
+ XORL 4(SP), R9
+ XORL 44(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 36(SP)
+
+ // FUNC3
+ MOVL R10, R8
+ ORL R11, R8
+ ANDL R12, R8
+ MOVL R10, R15
+ ANDL R11, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 36(SP), R9
+ MOVL R9, 164(R8)
+
+ // ROUND3(42)
+ // SHUFFLE
+ MOVL 40(SP), R9
+ XORL 28(SP), R9
+ XORL 8(SP), R9
+ XORL 48(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 40(SP)
+
+ // FUNC3
+ MOVL R14, R8
+ ORL R10, R8
+ ANDL R11, R8
+ MOVL R14, R15
+ ANDL R10, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 40(SP), R9
+ MOVL R9, 168(R8)
+
+ // ROUND3(43)
+ // SHUFFLE
+ MOVL 44(SP), R9
+ XORL 32(SP), R9
+ XORL 12(SP), R9
+ XORL 52(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 44(SP)
+
+ // FUNC3
+ MOVL R13, R8
+ ORL R14, R8
+ ANDL R10, R8
+ MOVL R13, R15
+ ANDL R14, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 44(SP), R9
+ MOVL R9, 172(R8)
+
+ // ROUND3(44)
+ // SHUFFLE
+ MOVL 48(SP), R9
+ XORL 36(SP), R9
+ XORL 16(SP), R9
+ XORL 56(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 48(SP)
+
+ // FUNC3
+ MOVL R12, R8
+ ORL R13, R8
+ ANDL R14, R8
+ MOVL R12, R15
+ ANDL R13, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 48(SP), R9
+ MOVL R9, 176(R8)
+
+ // ROUND3(45)
+ // SHUFFLE
+ MOVL 52(SP), R9
+ XORL 40(SP), R9
+ XORL 20(SP), R9
+ XORL 60(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 52(SP)
+
+ // FUNC3
+ MOVL R11, R8
+ ORL R12, R8
+ ANDL R13, R8
+ MOVL R11, R15
+ ANDL R12, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 52(SP), R9
+ MOVL R9, 180(R8)
+
+ // ROUND3(46)
+ // SHUFFLE
+ MOVL 56(SP), R9
+ XORL 44(SP), R9
+ XORL 24(SP), R9
+ XORL (SP), R9
+ ROLL $+1, R9
+ MOVL R9, 56(SP)
+
+ // FUNC3
+ MOVL R10, R8
+ ORL R11, R8
+ ANDL R12, R8
+ MOVL R10, R15
+ ANDL R11, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 56(SP), R9
+ MOVL R9, 184(R8)
+
+ // ROUND3(47)
+ // SHUFFLE
+ MOVL 60(SP), R9
+ XORL 48(SP), R9
+ XORL 28(SP), R9
+ XORL 4(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 60(SP)
+
+ // FUNC3
+ MOVL R14, R8
+ ORL R10, R8
+ ANDL R11, R8
+ MOVL R14, R15
+ ANDL R10, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 60(SP), R9
+ MOVL R9, 188(R8)
+
+ // ROUND3(48)
+ // SHUFFLE
+ MOVL (SP), R9
+ XORL 52(SP), R9
+ XORL 32(SP), R9
+ XORL 8(SP), R9
+ ROLL $+1, R9
+ MOVL R9, (SP)
+
+ // FUNC3
+ MOVL R13, R8
+ ORL R14, R8
+ ANDL R10, R8
+ MOVL R13, R15
+ ANDL R14, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL (SP), R9
+ MOVL R9, 192(R8)
+
+ // ROUND3(49)
+ // SHUFFLE
+ MOVL 4(SP), R9
+ XORL 56(SP), R9
+ XORL 36(SP), R9
+ XORL 12(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 4(SP)
+
+ // FUNC3
+ MOVL R12, R8
+ ORL R13, R8
+ ANDL R14, R8
+ MOVL R12, R15
+ ANDL R13, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 4(SP), R9
+ MOVL R9, 196(R8)
+
+ // ROUND3(50)
+ // SHUFFLE
+ MOVL 8(SP), R9
+ XORL 60(SP), R9
+ XORL 40(SP), R9
+ XORL 16(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 8(SP)
+
+ // FUNC3
+ MOVL R11, R8
+ ORL R12, R8
+ ANDL R13, R8
+ MOVL R11, R15
+ ANDL R12, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 8(SP), R9
+ MOVL R9, 200(R8)
+
+ // ROUND3(51)
+ // SHUFFLE
+ MOVL 12(SP), R9
+ XORL (SP), R9
+ XORL 44(SP), R9
+ XORL 20(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 12(SP)
+
+ // FUNC3
+ MOVL R10, R8
+ ORL R11, R8
+ ANDL R12, R8
+ MOVL R10, R15
+ ANDL R11, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 12(SP), R9
+ MOVL R9, 204(R8)
+
+ // ROUND3(52)
+ // SHUFFLE
+ MOVL 16(SP), R9
+ XORL 4(SP), R9
+ XORL 48(SP), R9
+ XORL 24(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 16(SP)
+
+ // FUNC3
+ MOVL R14, R8
+ ORL R10, R8
+ ANDL R11, R8
+ MOVL R14, R15
+ ANDL R10, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 16(SP), R9
+ MOVL R9, 208(R8)
+
+ // ROUND3(53)
+ // SHUFFLE
+ MOVL 20(SP), R9
+ XORL 8(SP), R9
+ XORL 52(SP), R9
+ XORL 28(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 20(SP)
+
+ // FUNC3
+ MOVL R13, R8
+ ORL R14, R8
+ ANDL R10, R8
+ MOVL R13, R15
+ ANDL R14, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 20(SP), R9
+ MOVL R9, 212(R8)
+
+ // ROUND3(54)
+ // SHUFFLE
+ MOVL 24(SP), R9
+ XORL 12(SP), R9
+ XORL 56(SP), R9
+ XORL 32(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 24(SP)
+
+ // FUNC3
+ MOVL R12, R8
+ ORL R13, R8
+ ANDL R14, R8
+ MOVL R12, R15
+ ANDL R13, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 24(SP), R9
+ MOVL R9, 216(R8)
+
+ // ROUND3(55)
+ // SHUFFLE
+ MOVL 28(SP), R9
+ XORL 16(SP), R9
+ XORL 60(SP), R9
+ XORL 36(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 28(SP)
+
+ // FUNC3
+ MOVL R11, R8
+ ORL R12, R8
+ ANDL R13, R8
+ MOVL R11, R15
+ ANDL R12, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 28(SP), R9
+ MOVL R9, 220(R8)
+
+ // ROUND3(56)
+ // SHUFFLE
+ MOVL 32(SP), R9
+ XORL 20(SP), R9
+ XORL (SP), R9
+ XORL 40(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 32(SP)
+
+ // FUNC3
+ MOVL R10, R8
+ ORL R11, R8
+ ANDL R12, R8
+ MOVL R10, R15
+ ANDL R11, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 32(SP), R9
+ MOVL R9, 224(R8)
+
+ // ROUND3(57)
+ // SHUFFLE
+ MOVL 36(SP), R9
+ XORL 24(SP), R9
+ XORL 4(SP), R9
+ XORL 44(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 36(SP)
+
+ // FUNC3
+ MOVL R14, R8
+ ORL R10, R8
+ ANDL R11, R8
+ MOVL R14, R15
+ ANDL R10, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 36(SP), R9
+ MOVL R9, 228(R8)
+
+ // Load cs
+ MOVQ cs_base+56(FP), R8
+ MOVL R12, 20(R8)
+ MOVL R13, 24(R8)
+ MOVL R14, 28(R8)
+ MOVL R10, 32(R8)
+ MOVL R11, 36(R8)
+
+ // ROUND3(58)
+ // SHUFFLE
+ MOVL 40(SP), R9
+ XORL 28(SP), R9
+ XORL 8(SP), R9
+ XORL 48(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 40(SP)
+
+ // FUNC3
+ MOVL R13, R8
+ ORL R14, R8
+ ANDL R10, R8
+ MOVL R13, R15
+ ANDL R14, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 40(SP), R9
+ MOVL R9, 232(R8)
+
+ // ROUND3(59)
+ // SHUFFLE
+ MOVL 44(SP), R9
+ XORL 32(SP), R9
+ XORL 12(SP), R9
+ XORL 52(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 44(SP)
+
+ // FUNC3
+ MOVL R12, R8
+ ORL R13, R8
+ ANDL R14, R8
+ MOVL R12, R15
+ ANDL R13, R15
+ ORL R8, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 2400959708(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 44(SP), R9
+ MOVL R9, 236(R8)
+
+ // ROUND4 (steps 60-79)
+ // ROUND4(60)
+ // SHUFFLE
+ MOVL 48(SP), R9
+ XORL 36(SP), R9
+ XORL 16(SP), R9
+ XORL 56(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 48(SP)
+
+ // FUNC2
+ MOVL R11, R15
+ XORL R12, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 48(SP), R9
+ MOVL R9, 240(R8)
+
+ // ROUND4(61)
+ // SHUFFLE
+ MOVL 52(SP), R9
+ XORL 40(SP), R9
+ XORL 20(SP), R9
+ XORL 60(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 52(SP)
+
+ // FUNC2
+ MOVL R10, R15
+ XORL R11, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 52(SP), R9
+ MOVL R9, 244(R8)
+
+ // ROUND4(62)
+ // SHUFFLE
+ MOVL 56(SP), R9
+ XORL 44(SP), R9
+ XORL 24(SP), R9
+ XORL (SP), R9
+ ROLL $+1, R9
+ MOVL R9, 56(SP)
+
+ // FUNC2
+ MOVL R14, R15
+ XORL R10, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 56(SP), R9
+ MOVL R9, 248(R8)
+
+ // ROUND4(63)
+ // SHUFFLE
+ MOVL 60(SP), R9
+ XORL 48(SP), R9
+ XORL 28(SP), R9
+ XORL 4(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 60(SP)
+
+ // FUNC2
+ MOVL R13, R15
+ XORL R14, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 60(SP), R9
+ MOVL R9, 252(R8)
+
+ // ROUND4(64)
+ // SHUFFLE
+ MOVL (SP), R9
+ XORL 52(SP), R9
+ XORL 32(SP), R9
+ XORL 8(SP), R9
+ ROLL $+1, R9
+ MOVL R9, (SP)
+
+ // FUNC2
+ MOVL R12, R15
+ XORL R13, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL (SP), R9
+ MOVL R9, 256(R8)
+
+ // Load cs
+ MOVQ cs_base+56(FP), R8
+ MOVL R10, 40(R8)
+ MOVL R11, 44(R8)
+ MOVL R12, 48(R8)
+ MOVL R13, 52(R8)
+ MOVL R14, 56(R8)
+
+ // ROUND4(65)
+ // SHUFFLE
+ MOVL 4(SP), R9
+ XORL 56(SP), R9
+ XORL 36(SP), R9
+ XORL 12(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 4(SP)
+
+ // FUNC2
+ MOVL R11, R15
+ XORL R12, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 4(SP), R9
+ MOVL R9, 260(R8)
+
+ // ROUND4(66)
+ // SHUFFLE
+ MOVL 8(SP), R9
+ XORL 60(SP), R9
+ XORL 40(SP), R9
+ XORL 16(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 8(SP)
+
+ // FUNC2
+ MOVL R10, R15
+ XORL R11, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 8(SP), R9
+ MOVL R9, 264(R8)
+
+ // ROUND4(67)
+ // SHUFFLE
+ MOVL 12(SP), R9
+ XORL (SP), R9
+ XORL 44(SP), R9
+ XORL 20(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 12(SP)
+
+ // FUNC2
+ MOVL R14, R15
+ XORL R10, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 12(SP), R9
+ MOVL R9, 268(R8)
+
+ // ROUND4(68)
+ // SHUFFLE
+ MOVL 16(SP), R9
+ XORL 4(SP), R9
+ XORL 48(SP), R9
+ XORL 24(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 16(SP)
+
+ // FUNC2
+ MOVL R13, R15
+ XORL R14, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 16(SP), R9
+ MOVL R9, 272(R8)
+
+ // ROUND4(69)
+ // SHUFFLE
+ MOVL 20(SP), R9
+ XORL 8(SP), R9
+ XORL 52(SP), R9
+ XORL 28(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 20(SP)
+
+ // FUNC2
+ MOVL R12, R15
+ XORL R13, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 20(SP), R9
+ MOVL R9, 276(R8)
+
+ // ROUND4(70)
+ // SHUFFLE
+ MOVL 24(SP), R9
+ XORL 12(SP), R9
+ XORL 56(SP), R9
+ XORL 32(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 24(SP)
+
+ // FUNC2
+ MOVL R11, R15
+ XORL R12, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 24(SP), R9
+ MOVL R9, 280(R8)
+
+ // ROUND4(71)
+ // SHUFFLE
+ MOVL 28(SP), R9
+ XORL 16(SP), R9
+ XORL 60(SP), R9
+ XORL 36(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 28(SP)
+
+ // FUNC2
+ MOVL R10, R15
+ XORL R11, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 28(SP), R9
+ MOVL R9, 284(R8)
+
+ // ROUND4(72)
+ // SHUFFLE
+ MOVL 32(SP), R9
+ XORL 20(SP), R9
+ XORL (SP), R9
+ XORL 40(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 32(SP)
+
+ // FUNC2
+ MOVL R14, R15
+ XORL R10, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 32(SP), R9
+ MOVL R9, 288(R8)
+
+ // ROUND4(73)
+ // SHUFFLE
+ MOVL 36(SP), R9
+ XORL 24(SP), R9
+ XORL 4(SP), R9
+ XORL 44(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 36(SP)
+
+ // FUNC2
+ MOVL R13, R15
+ XORL R14, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 36(SP), R9
+ MOVL R9, 292(R8)
+
+ // ROUND4(74)
+ // SHUFFLE
+ MOVL 40(SP), R9
+ XORL 28(SP), R9
+ XORL 8(SP), R9
+ XORL 48(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 40(SP)
+
+ // FUNC2
+ MOVL R12, R15
+ XORL R13, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 40(SP), R9
+ MOVL R9, 296(R8)
+
+ // ROUND4(75)
+ // SHUFFLE
+ MOVL 44(SP), R9
+ XORL 32(SP), R9
+ XORL 12(SP), R9
+ XORL 52(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 44(SP)
+
+ // FUNC2
+ MOVL R11, R15
+ XORL R12, R15
+ XORL R13, R15
+
+ // MIX
+ ROLL $+30, R11
+ ADDL R15, R14
+ MOVL R10, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R14)(R9*1), R14
+ ADDL R8, R14
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 44(SP), R9
+ MOVL R9, 300(R8)
+
+ // ROUND4(76)
+ // SHUFFLE
+ MOVL 48(SP), R9
+ XORL 36(SP), R9
+ XORL 16(SP), R9
+ XORL 56(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 48(SP)
+
+ // FUNC2
+ MOVL R10, R15
+ XORL R11, R15
+ XORL R12, R15
+
+ // MIX
+ ROLL $+30, R10
+ ADDL R15, R13
+ MOVL R14, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R13)(R9*1), R13
+ ADDL R8, R13
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 48(SP), R9
+ MOVL R9, 304(R8)
+
+ // ROUND4(77)
+ // SHUFFLE
+ MOVL 52(SP), R9
+ XORL 40(SP), R9
+ XORL 20(SP), R9
+ XORL 60(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 52(SP)
+
+ // FUNC2
+ MOVL R14, R15
+ XORL R10, R15
+ XORL R11, R15
+
+ // MIX
+ ROLL $+30, R14
+ ADDL R15, R12
+ MOVL R13, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R12)(R9*1), R12
+ ADDL R8, R12
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 52(SP), R9
+ MOVL R9, 308(R8)
+
+ // ROUND4(78)
+ // SHUFFLE
+ MOVL 56(SP), R9
+ XORL 44(SP), R9
+ XORL 24(SP), R9
+ XORL (SP), R9
+ ROLL $+1, R9
+ MOVL R9, 56(SP)
+
+ // FUNC2
+ MOVL R13, R15
+ XORL R14, R15
+ XORL R10, R15
+
+ // MIX
+ ROLL $+30, R13
+ ADDL R15, R11
+ MOVL R12, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R11)(R9*1), R11
+ ADDL R8, R11
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 56(SP), R9
+ MOVL R9, 312(R8)
+
+ // ROUND4(79)
+ // SHUFFLE
+ MOVL 60(SP), R9
+ XORL 48(SP), R9
+ XORL 28(SP), R9
+ XORL 4(SP), R9
+ ROLL $+1, R9
+ MOVL R9, 60(SP)
+
+ // FUNC2
+ MOVL R12, R15
+ XORL R13, R15
+ XORL R14, R15
+
+ // MIX
+ ROLL $+30, R12
+ ADDL R15, R10
+ MOVL R11, R8
+ ROLL $+5, R8
+ LEAL 3395469782(R10)(R9*1), R10
+ ADDL R8, R10
+
+ // Load m1
+ MOVQ m1_base+32(FP), R8
+ MOVL 60(SP), R9
+ MOVL R9, 316(R8)
+
+ // Add registers to temp hash.
+ ADDL R10, AX
+ ADDL R11, BX
+ ADDL R12, CX
+ ADDL R13, DX
+ ADDL R14, BP
+ ADDQ $+64, DI
+ CMPQ DI, SI
+ JB loop
+
+end:
+ MOVQ dig+0(FP), SI
+ MOVL AX, (SI)
+ MOVL BX, 4(SI)
+ MOVL CX, 8(SI)
+ MOVL DX, 12(SI)
+ MOVL BP, 16(SI)
+ RET
diff --git a/vendor/github.com/pjbgf/sha1cd/sha1cdblock_generic.go b/vendor/github.com/pjbgf/sha1cd/sha1cdblock_generic.go
new file mode 100644
index 00000000..ba8b96e8
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/sha1cdblock_generic.go
@@ -0,0 +1,268 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Originally from: https://github.com/go/blob/master/src/crypto/sha1/sha1block.go
+// It has been modified to support collision detection.
+
+package sha1cd
+
+import (
+ "fmt"
+ "math/bits"
+
+ shared "github.com/pjbgf/sha1cd/internal"
+ "github.com/pjbgf/sha1cd/ubc"
+)
+
+// blockGeneric is a portable, pure Go version of the SHA-1 block step.
+// It's used by sha1block_generic.go and tests.
+func blockGeneric(dig *digest, p []byte) {
+ var w [16]uint32
+
+ // cs stores the pre-step compression state for only the steps required for the
+ // collision detection, which are 0, 58 and 65.
+ // Refer to ubc/const.go for more details.
+ cs := [shared.PreStepState][shared.WordBuffers]uint32{}
+
+ h0, h1, h2, h3, h4 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4]
+ for len(p) >= shared.Chunk {
+ m1 := [shared.Rounds]uint32{}
+ hi := 1
+
+ // Collision attacks are thwarted by hashing a detected near-collision block 3 times.
+ // Think of it as extending SHA-1 from 80-steps to 240-steps for such blocks:
+ // The best collision attacks against SHA-1 have complexity about 2^60,
+ // thus for 240-steps an immediate lower-bound for the best cryptanalytic attacks would be 2^180.
+ // An attacker would be better off using a generic birthday search of complexity 2^80.
+ rehash:
+ a, b, c, d, e := h0, h1, h2, h3, h4
+
+ // Each of the four 20-iteration rounds
+ // differs only in the computation of f and
+ // the choice of K (K0, K1, etc).
+ i := 0
+
+ // Store pre-step compression state for the collision detection.
+ cs[0] = [shared.WordBuffers]uint32{a, b, c, d, e}
+
+ for ; i < 16; i++ {
+ // load step
+ j := i * 4
+ w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3])
+
+ f := b&c | (^b)&d
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + shared.K0
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+
+ // Store compression state for the collision detection.
+ m1[i] = w[i&0xf]
+ }
+ for ; i < 20; i++ {
+ tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
+ w[i&0xf] = tmp<<1 | tmp>>(32-1)
+
+ f := b&c | (^b)&d
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + shared.K0
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+
+ // Store compression state for the collision detection.
+ m1[i] = w[i&0xf]
+ }
+ for ; i < 40; i++ {
+ tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
+ w[i&0xf] = tmp<<1 | tmp>>(32-1)
+
+ f := b ^ c ^ d
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + shared.K1
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+
+ // Store compression state for the collision detection.
+ m1[i] = w[i&0xf]
+ }
+ for ; i < 60; i++ {
+ if i == 58 {
+ // Store pre-step compression state for the collision detection.
+ cs[1] = [shared.WordBuffers]uint32{a, b, c, d, e}
+ }
+
+ tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
+ w[i&0xf] = tmp<<1 | tmp>>(32-1)
+
+ f := ((b | c) & d) | (b & c)
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + shared.K2
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+
+ // Store compression state for the collision detection.
+ m1[i] = w[i&0xf]
+ }
+ for ; i < 80; i++ {
+ if i == 65 {
+ // Store pre-step compression state for the collision detection.
+ cs[2] = [shared.WordBuffers]uint32{a, b, c, d, e}
+ }
+
+ tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
+ w[i&0xf] = tmp<<1 | tmp>>(32-1)
+
+ f := b ^ c ^ d
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + shared.K3
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+
+ // Store compression state for the collision detection.
+ m1[i] = w[i&0xf]
+ }
+
+ h0 += a
+ h1 += b
+ h2 += c
+ h3 += d
+ h4 += e
+
+ if hi == 2 {
+ hi++
+ goto rehash
+ }
+
+ if hi == 1 {
+ col := checkCollision(m1, cs, [shared.WordBuffers]uint32{h0, h1, h2, h3, h4})
+ if col {
+ dig.col = true
+ hi++
+ goto rehash
+ }
+ }
+
+ p = p[shared.Chunk:]
+ }
+
+ dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4
+}
+
+func checkCollision(
+ m1 [shared.Rounds]uint32,
+ cs [shared.PreStepState][shared.WordBuffers]uint32,
+ state [shared.WordBuffers]uint32) bool {
+
+ if mask := ubc.CalculateDvMask(m1); mask != 0 {
+ dvs := ubc.SHA1_dvs()
+
+ for i := 0; dvs[i].DvType != 0; i++ {
+ if (mask & ((uint32)(1) << uint32(dvs[i].MaskB))) != 0 {
+ var csState [shared.WordBuffers]uint32
+ switch dvs[i].TestT {
+ case 58:
+ csState = cs[1]
+ case 65:
+ csState = cs[2]
+ case 0:
+ csState = cs[0]
+ default:
+ panic(fmt.Sprintf("dvs data is trying to use a testT that isn't available: %d", dvs[i].TestT))
+ }
+
+ col := hasCollided(
+ dvs[i].TestT, // testT is the step number
+ // m2 is a secondary message created XORing with
+ // ubc's DM prior to the SHA recompression step.
+ m1, dvs[i].Dm,
+ csState,
+ state)
+
+ if col {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+func hasCollided(step uint32, m1, dm [shared.Rounds]uint32,
+ state [shared.WordBuffers]uint32, h [shared.WordBuffers]uint32) bool {
+ // Intermediary Hash Value.
+ ihv := [shared.WordBuffers]uint32{}
+
+ a, b, c, d, e := state[0], state[1], state[2], state[3], state[4]
+
+ // Walk backwards from current step to undo previous compression.
+ // The existing collision detection does not have dvs higher than 65,
+ // start value of i accordingly.
+ for i := uint32(64); i >= 60; i-- {
+ a, b, c, d, e = b, c, d, e, a
+ if step > i {
+ b = bits.RotateLeft32(b, -30)
+ f := b ^ c ^ d
+ e -= bits.RotateLeft32(a, 5) + f + shared.K3 + (m1[i] ^ dm[i]) // m2 = m1 ^ dm.
+ }
+ }
+ for i := uint32(59); i >= 40; i-- {
+ a, b, c, d, e = b, c, d, e, a
+ if step > i {
+ b = bits.RotateLeft32(b, -30)
+ f := ((b | c) & d) | (b & c)
+ e -= bits.RotateLeft32(a, 5) + f + shared.K2 + (m1[i] ^ dm[i])
+ }
+ }
+ for i := uint32(39); i >= 20; i-- {
+ a, b, c, d, e = b, c, d, e, a
+ if step > i {
+ b = bits.RotateLeft32(b, -30)
+ f := b ^ c ^ d
+ e -= bits.RotateLeft32(a, 5) + f + shared.K1 + (m1[i] ^ dm[i])
+ }
+ }
+ for i := uint32(20); i > 0; i-- {
+ j := i - 1
+ a, b, c, d, e = b, c, d, e, a
+ if step > j {
+ b = bits.RotateLeft32(b, -30) // undo the rotate left
+ f := b&c | (^b)&d
+ // subtract from e
+ e -= bits.RotateLeft32(a, 5) + f + shared.K0 + (m1[j] ^ dm[j])
+ }
+ }
+
+ ihv[0] = a
+ ihv[1] = b
+ ihv[2] = c
+ ihv[3] = d
+ ihv[4] = e
+ a = state[0]
+ b = state[1]
+ c = state[2]
+ d = state[3]
+ e = state[4]
+
+ // Recompress blocks based on the current step.
+ // The existing collision detection does not have dvs below 58, so they have been removed
+ // from the source code. If new dvs are added which target rounds below 40, that logic
+ // will need to be readded here.
+ for i := uint32(40); i < 60; i++ {
+ if step <= i {
+ f := ((b | c) & d) | (b & c)
+ t := bits.RotateLeft32(a, 5) + f + e + shared.K2 + (m1[i] ^ dm[i])
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+ }
+ }
+ for i := uint32(60); i < 80; i++ {
+ if step <= i {
+ f := b ^ c ^ d
+ t := bits.RotateLeft32(a, 5) + f + e + shared.K3 + (m1[i] ^ dm[i])
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+ }
+ }
+
+ ihv[0] += a
+ ihv[1] += b
+ ihv[2] += c
+ ihv[3] += d
+ ihv[4] += e
+
+ if ((ihv[0] ^ h[0]) | (ihv[1] ^ h[1]) |
+ (ihv[2] ^ h[2]) | (ihv[3] ^ h[3]) | (ihv[4] ^ h[4])) == 0 {
+ return true
+ }
+
+ return false
+}
diff --git a/vendor/github.com/pjbgf/sha1cd/sha1cdblock_noasm.go b/vendor/github.com/pjbgf/sha1cd/sha1cdblock_noasm.go
new file mode 100644
index 00000000..15bae5a7
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/sha1cdblock_noasm.go
@@ -0,0 +1,8 @@
+//go:build !amd64 || noasm || !gc
+// +build !amd64 noasm !gc
+
+package sha1cd
+
+func block(dig *digest, p []byte) {
+ blockGeneric(dig, p)
+}
diff --git a/vendor/github.com/pjbgf/sha1cd/ubc/check.go b/vendor/github.com/pjbgf/sha1cd/ubc/check.go
new file mode 100644
index 00000000..167a5558
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/ubc/check.go
@@ -0,0 +1,368 @@
+// Based on the C implementation from Marc Stevens and Dan Shumow.
+// https://github.com/cr-marcstevens/sha1collisiondetection
+
+package ubc
+
+type DvInfo struct {
+ // DvType, DvK and DvB define the DV: I(K,B) or II(K,B) (see the paper).
+ // https://marc-stevens.nl/research/papers/C13-S.pdf
+ DvType uint32
+ DvK uint32
+ DvB uint32
+
+ // TestT is the step to do the recompression from for collision detection.
+ TestT uint32
+
+ // MaskI and MaskB define the bit to check for each DV in the dvmask returned by ubc_check.
+ MaskI uint32
+ MaskB uint32
+
+ // Dm is the expanded message block XOR-difference defined by the DV.
+ Dm [80]uint32
+}
+
+// CalculateDvMask takes as input an expanded message block and verifies the unavoidable bitconditions
+// for all listed DVs. It returns a dvmask where each bit belonging to a DV is set if all
+// unavoidable bitconditions for that DV have been met.
+// Thus, one needs to do the recompression check for each DV that has its bit set.
+func CalculateDvMask(W [80]uint32) uint32 {
+ mask := uint32(0xFFFFFFFF)
+ mask &= (((((W[44] ^ W[45]) >> 29) & 1) - 1) | ^(DV_I_48_0_bit | DV_I_51_0_bit | DV_I_52_0_bit | DV_II_45_0_bit | DV_II_46_0_bit | DV_II_50_0_bit | DV_II_51_0_bit))
+ mask &= (((((W[49] ^ W[50]) >> 29) & 1) - 1) | ^(DV_I_46_0_bit | DV_II_45_0_bit | DV_II_50_0_bit | DV_II_51_0_bit | DV_II_55_0_bit | DV_II_56_0_bit))
+ mask &= (((((W[48] ^ W[49]) >> 29) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_52_0_bit | DV_II_49_0_bit | DV_II_50_0_bit | DV_II_54_0_bit | DV_II_55_0_bit))
+ mask &= ((((W[47] ^ (W[50] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_51_0_bit | DV_II_56_0_bit))
+ mask &= (((((W[47] ^ W[48]) >> 29) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_51_0_bit | DV_II_48_0_bit | DV_II_49_0_bit | DV_II_53_0_bit | DV_II_54_0_bit))
+ mask &= (((((W[46] >> 4) ^ (W[49] >> 29)) & 1) - 1) | ^(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit | DV_II_50_0_bit | DV_II_55_0_bit))
+ mask &= (((((W[46] ^ W[47]) >> 29) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_50_0_bit | DV_II_47_0_bit | DV_II_48_0_bit | DV_II_52_0_bit | DV_II_53_0_bit))
+ mask &= (((((W[45] >> 4) ^ (W[48] >> 29)) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit | DV_II_49_0_bit | DV_II_54_0_bit))
+ mask &= (((((W[45] ^ W[46]) >> 29) & 1) - 1) | ^(DV_I_49_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_47_0_bit | DV_II_51_0_bit | DV_II_52_0_bit))
+ mask &= (((((W[44] >> 4) ^ (W[47] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit | DV_II_48_0_bit | DV_II_53_0_bit))
+ mask &= (((((W[43] >> 4) ^ (W[46] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit | DV_II_47_0_bit | DV_II_52_0_bit))
+ mask &= (((((W[43] ^ W[44]) >> 29) & 1) - 1) | ^(DV_I_47_0_bit | DV_I_50_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_49_0_bit | DV_II_50_0_bit))
+ mask &= (((((W[42] >> 4) ^ (W[45] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_51_0_bit))
+ mask &= (((((W[41] >> 4) ^ (W[44] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_50_0_bit))
+ mask &= (((((W[40] ^ W[41]) >> 29) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_47_0_bit | DV_I_48_0_bit | DV_II_46_0_bit | DV_II_47_0_bit | DV_II_56_0_bit))
+ mask &= (((((W[54] ^ W[55]) >> 29) & 1) - 1) | ^(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_50_0_bit | DV_II_55_0_bit | DV_II_56_0_bit))
+ mask &= (((((W[53] ^ W[54]) >> 29) & 1) - 1) | ^(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_49_0_bit | DV_II_54_0_bit | DV_II_55_0_bit))
+ mask &= (((((W[52] ^ W[53]) >> 29) & 1) - 1) | ^(DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit | DV_II_53_0_bit | DV_II_54_0_bit))
+ mask &= ((((W[50] ^ (W[53] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_50_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_48_0_bit | DV_II_54_0_bit))
+ mask &= (((((W[50] ^ W[51]) >> 29) & 1) - 1) | ^(DV_I_47_0_bit | DV_II_46_0_bit | DV_II_51_0_bit | DV_II_52_0_bit | DV_II_56_0_bit))
+ mask &= ((((W[49] ^ (W[52] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_47_0_bit | DV_II_53_0_bit))
+ mask &= ((((W[48] ^ (W[51] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_52_0_bit))
+ mask &= (((((W[42] ^ W[43]) >> 29) & 1) - 1) | ^(DV_I_46_0_bit | DV_I_49_0_bit | DV_I_50_0_bit | DV_II_48_0_bit | DV_II_49_0_bit))
+ mask &= (((((W[41] ^ W[42]) >> 29) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_48_0_bit | DV_I_49_0_bit | DV_II_47_0_bit | DV_II_48_0_bit))
+ mask &= (((((W[40] >> 4) ^ (W[43] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_50_0_bit | DV_II_49_0_bit | DV_II_56_0_bit))
+ mask &= (((((W[39] >> 4) ^ (W[42] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_49_0_bit | DV_II_48_0_bit | DV_II_55_0_bit))
+
+ if (mask & (DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)) != 0 {
+ mask &= (((((W[38] >> 4) ^ (W[41] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit | DV_II_54_0_bit | DV_II_56_0_bit))
+ }
+ mask &= (((((W[37] >> 4) ^ (W[40] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_47_0_bit | DV_II_46_0_bit | DV_II_53_0_bit | DV_II_55_0_bit))
+ if (mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_51_0_bit | DV_II_56_0_bit)) != 0 {
+ mask &= (((((W[55] ^ W[56]) >> 29) & 1) - 1) | ^(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_51_0_bit | DV_II_56_0_bit))
+ }
+ if (mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit | DV_II_56_0_bit)) != 0 {
+ mask &= ((((W[52] ^ (W[55] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit | DV_II_56_0_bit))
+ }
+ if (mask & (DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit | DV_II_55_0_bit)) != 0 {
+ mask &= ((((W[51] ^ (W[54] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit | DV_II_55_0_bit))
+ }
+ if (mask & (DV_I_48_0_bit | DV_II_47_0_bit | DV_II_52_0_bit | DV_II_53_0_bit)) != 0 {
+ mask &= (((((W[51] ^ W[52]) >> 29) & 1) - 1) | ^(DV_I_48_0_bit | DV_II_47_0_bit | DV_II_52_0_bit | DV_II_53_0_bit))
+ }
+ if (mask & (DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit)) != 0 {
+ mask &= (((((W[36] >> 4) ^ (W[40] >> 29)) & 1) - 1) | ^(DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit))
+ }
+ if (mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit)) != 0 {
+ mask &= ((0 - (((W[53] ^ W[56]) >> 29) & 1)) | ^(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit))
+ }
+ if (mask & (DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit)) != 0 {
+ mask &= ((0 - (((W[51] ^ W[54]) >> 29) & 1)) | ^(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit))
+ }
+ if (mask & (DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit)) != 0 {
+ mask &= ((0 - (((W[50] ^ W[52]) >> 29) & 1)) | ^(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit))
+ }
+ if (mask & (DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit)) != 0 {
+ mask &= ((0 - (((W[49] ^ W[51]) >> 29) & 1)) | ^(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit))
+ }
+ if (mask & (DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit)) != 0 {
+ mask &= ((0 - (((W[48] ^ W[50]) >> 29) & 1)) | ^(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit))
+ }
+ if (mask & (DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit)) != 0 {
+ mask &= ((0 - (((W[47] ^ W[49]) >> 29) & 1)) | ^(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit))
+ }
+ if (mask & (DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit)) != 0 {
+ mask &= ((0 - (((W[46] ^ W[48]) >> 29) & 1)) | ^(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit))
+ }
+ mask &= ((((W[45] ^ W[47]) & (1 << 6)) - (1 << 6)) | ^(DV_I_47_2_bit | DV_I_49_2_bit | DV_I_51_2_bit))
+ if (mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit)) != 0 {
+ mask &= ((0 - (((W[45] ^ W[47]) >> 29) & 1)) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit))
+ }
+ mask &= (((((W[44] ^ W[46]) >> 6) & 1) - 1) | ^(DV_I_46_2_bit | DV_I_48_2_bit | DV_I_50_2_bit))
+ if (mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit)) != 0 {
+ mask &= ((0 - (((W[44] ^ W[46]) >> 29) & 1)) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit))
+ }
+ mask &= ((0 - ((W[41] ^ (W[42] >> 5)) & (1 << 1))) | ^(DV_I_48_2_bit | DV_II_46_2_bit | DV_II_51_2_bit))
+ mask &= ((0 - ((W[40] ^ (W[41] >> 5)) & (1 << 1))) | ^(DV_I_47_2_bit | DV_I_51_2_bit | DV_II_50_2_bit))
+ if (mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit)) != 0 {
+ mask &= ((0 - (((W[40] ^ W[42]) >> 4) & 1)) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit))
+ }
+ mask &= ((0 - ((W[39] ^ (W[40] >> 5)) & (1 << 1))) | ^(DV_I_46_2_bit | DV_I_50_2_bit | DV_II_49_2_bit))
+ if (mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit)) != 0 {
+ mask &= ((0 - (((W[39] ^ W[41]) >> 4) & 1)) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit))
+ }
+ if (mask & (DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)) != 0 {
+ mask &= ((0 - (((W[38] ^ W[40]) >> 4) & 1)) | ^(DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit))
+ }
+ if (mask & (DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit)) != 0 {
+ mask &= ((0 - (((W[37] ^ W[39]) >> 4) & 1)) | ^(DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit))
+ }
+ mask &= ((0 - ((W[36] ^ (W[37] >> 5)) & (1 << 1))) | ^(DV_I_47_2_bit | DV_I_50_2_bit | DV_II_46_2_bit))
+ if (mask & (DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit)) != 0 {
+ mask &= (((((W[35] >> 4) ^ (W[39] >> 29)) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit))
+ }
+ if (mask & (DV_I_48_0_bit | DV_II_48_0_bit)) != 0 {
+ mask &= ((0 - ((W[63] ^ (W[64] >> 5)) & (1 << 0))) | ^(DV_I_48_0_bit | DV_II_48_0_bit))
+ }
+ if (mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0 {
+ mask &= ((0 - ((W[63] ^ (W[64] >> 5)) & (1 << 1))) | ^(DV_I_45_0_bit | DV_II_45_0_bit))
+ }
+ if (mask & (DV_I_47_0_bit | DV_II_47_0_bit)) != 0 {
+ mask &= ((0 - ((W[62] ^ (W[63] >> 5)) & (1 << 0))) | ^(DV_I_47_0_bit | DV_II_47_0_bit))
+ }
+ if (mask & (DV_I_46_0_bit | DV_II_46_0_bit)) != 0 {
+ mask &= ((0 - ((W[61] ^ (W[62] >> 5)) & (1 << 0))) | ^(DV_I_46_0_bit | DV_II_46_0_bit))
+ }
+ mask &= ((0 - ((W[61] ^ (W[62] >> 5)) & (1 << 2))) | ^(DV_I_46_2_bit | DV_II_46_2_bit))
+ if (mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0 {
+ mask &= ((0 - ((W[60] ^ (W[61] >> 5)) & (1 << 0))) | ^(DV_I_45_0_bit | DV_II_45_0_bit))
+ }
+ if (mask & (DV_II_51_0_bit | DV_II_54_0_bit)) != 0 {
+ mask &= (((((W[58] ^ W[59]) >> 29) & 1) - 1) | ^(DV_II_51_0_bit | DV_II_54_0_bit))
+ }
+ if (mask & (DV_II_50_0_bit | DV_II_53_0_bit)) != 0 {
+ mask &= (((((W[57] ^ W[58]) >> 29) & 1) - 1) | ^(DV_II_50_0_bit | DV_II_53_0_bit))
+ }
+ if (mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0 {
+ mask &= ((((W[56] ^ (W[59] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_52_0_bit | DV_II_54_0_bit))
+ }
+ if (mask & (DV_II_51_0_bit | DV_II_52_0_bit)) != 0 {
+ mask &= ((0 - (((W[56] ^ W[59]) >> 29) & 1)) | ^(DV_II_51_0_bit | DV_II_52_0_bit))
+ }
+ if (mask & (DV_II_49_0_bit | DV_II_52_0_bit)) != 0 {
+ mask &= (((((W[56] ^ W[57]) >> 29) & 1) - 1) | ^(DV_II_49_0_bit | DV_II_52_0_bit))
+ }
+ if (mask & (DV_II_51_0_bit | DV_II_53_0_bit)) != 0 {
+ mask &= ((((W[55] ^ (W[58] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_51_0_bit | DV_II_53_0_bit))
+ }
+ if (mask & (DV_II_50_0_bit | DV_II_52_0_bit)) != 0 {
+ mask &= ((((W[54] ^ (W[57] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_50_0_bit | DV_II_52_0_bit))
+ }
+ if (mask & (DV_II_49_0_bit | DV_II_51_0_bit)) != 0 {
+ mask &= ((((W[53] ^ (W[56] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_49_0_bit | DV_II_51_0_bit))
+ }
+ mask &= ((((W[51] ^ (W[50] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_50_2_bit | DV_II_46_2_bit))
+ mask &= ((((W[48] ^ W[50]) & (1 << 6)) - (1 << 6)) | ^(DV_I_50_2_bit | DV_II_46_2_bit))
+ if (mask & (DV_I_51_0_bit | DV_I_52_0_bit)) != 0 {
+ mask &= ((0 - (((W[48] ^ W[55]) >> 29) & 1)) | ^(DV_I_51_0_bit | DV_I_52_0_bit))
+ }
+ mask &= ((((W[47] ^ W[49]) & (1 << 6)) - (1 << 6)) | ^(DV_I_49_2_bit | DV_I_51_2_bit))
+ mask &= ((((W[48] ^ (W[47] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_47_2_bit | DV_II_51_2_bit))
+ mask &= ((((W[46] ^ W[48]) & (1 << 6)) - (1 << 6)) | ^(DV_I_48_2_bit | DV_I_50_2_bit))
+ mask &= ((((W[47] ^ (W[46] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_46_2_bit | DV_II_50_2_bit))
+ mask &= ((0 - ((W[44] ^ (W[45] >> 5)) & (1 << 1))) | ^(DV_I_51_2_bit | DV_II_49_2_bit))
+ mask &= ((((W[43] ^ W[45]) & (1 << 6)) - (1 << 6)) | ^(DV_I_47_2_bit | DV_I_49_2_bit))
+ mask &= (((((W[42] ^ W[44]) >> 6) & 1) - 1) | ^(DV_I_46_2_bit | DV_I_48_2_bit))
+ mask &= ((((W[43] ^ (W[42] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_II_46_2_bit | DV_II_51_2_bit))
+ mask &= ((((W[42] ^ (W[41] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_51_2_bit | DV_II_50_2_bit))
+ mask &= ((((W[41] ^ (W[40] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_50_2_bit | DV_II_49_2_bit))
+ if (mask & (DV_I_52_0_bit | DV_II_51_0_bit)) != 0 {
+ mask &= ((((W[39] ^ (W[43] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_52_0_bit | DV_II_51_0_bit))
+ }
+ if (mask & (DV_I_51_0_bit | DV_II_50_0_bit)) != 0 {
+ mask &= ((((W[38] ^ (W[42] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_51_0_bit | DV_II_50_0_bit))
+ }
+ if (mask & (DV_I_48_2_bit | DV_I_51_2_bit)) != 0 {
+ mask &= ((0 - ((W[37] ^ (W[38] >> 5)) & (1 << 1))) | ^(DV_I_48_2_bit | DV_I_51_2_bit))
+ }
+ if (mask & (DV_I_50_0_bit | DV_II_49_0_bit)) != 0 {
+ mask &= ((((W[37] ^ (W[41] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_50_0_bit | DV_II_49_0_bit))
+ }
+ if (mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0 {
+ mask &= ((0 - ((W[36] ^ W[38]) & (1 << 4))) | ^(DV_II_52_0_bit | DV_II_54_0_bit))
+ }
+ mask &= ((0 - ((W[35] ^ (W[36] >> 5)) & (1 << 1))) | ^(DV_I_46_2_bit | DV_I_49_2_bit))
+ if (mask & (DV_I_51_0_bit | DV_II_47_0_bit)) != 0 {
+ mask &= ((((W[35] ^ (W[39] >> 25)) & (1 << 3)) - (1 << 3)) | ^(DV_I_51_0_bit | DV_II_47_0_bit))
+ }
+
+ if mask != 0 {
+ if (mask & DV_I_43_0_bit) != 0 {
+ if not((W[61]^(W[62]>>5))&(1<<1)) != 0 ||
+ not(not((W[59]^(W[63]>>25))&(1<<5))) != 0 ||
+ not((W[58]^(W[63]>>30))&(1<<0)) != 0 {
+ mask &= ^DV_I_43_0_bit
+ }
+ }
+ if (mask & DV_I_44_0_bit) != 0 {
+ if not((W[62]^(W[63]>>5))&(1<<1)) != 0 ||
+ not(not((W[60]^(W[64]>>25))&(1<<5))) != 0 ||
+ not((W[59]^(W[64]>>30))&(1<<0)) != 0 {
+ mask &= ^DV_I_44_0_bit
+ }
+ }
+ if (mask & DV_I_46_2_bit) != 0 {
+ mask &= ((^((W[40] ^ W[42]) >> 2)) | ^DV_I_46_2_bit)
+ }
+ if (mask & DV_I_47_2_bit) != 0 {
+ if not((W[62]^(W[63]>>5))&(1<<2)) != 0 ||
+ not(not((W[41]^W[43])&(1<<6))) != 0 {
+ mask &= ^DV_I_47_2_bit
+ }
+ }
+ if (mask & DV_I_48_2_bit) != 0 {
+ if not((W[63]^(W[64]>>5))&(1<<2)) != 0 ||
+ not(not((W[48]^(W[49]<<5))&(1<<6))) != 0 {
+ mask &= ^DV_I_48_2_bit
+ }
+ }
+ if (mask & DV_I_49_2_bit) != 0 {
+ if not(not((W[49]^(W[50]<<5))&(1<<6))) != 0 ||
+ not((W[42]^W[50])&(1<<1)) != 0 ||
+ not(not((W[39]^(W[40]<<5))&(1<<6))) != 0 ||
+ not((W[38]^W[40])&(1<<1)) != 0 {
+ mask &= ^DV_I_49_2_bit
+ }
+ }
+ if (mask & DV_I_50_0_bit) != 0 {
+ mask &= (((W[36] ^ W[37]) << 7) | ^DV_I_50_0_bit)
+ }
+ if (mask & DV_I_50_2_bit) != 0 {
+ mask &= (((W[43] ^ W[51]) << 11) | ^DV_I_50_2_bit)
+ }
+ if (mask & DV_I_51_0_bit) != 0 {
+ mask &= (((W[37] ^ W[38]) << 9) | ^DV_I_51_0_bit)
+ }
+ if (mask & DV_I_51_2_bit) != 0 {
+ if not(not((W[51]^(W[52]<<5))&(1<<6))) != 0 ||
+ not(not((W[49]^W[51])&(1<<6))) != 0 ||
+ not(not((W[37]^(W[37]>>5))&(1<<1))) != 0 ||
+ not(not((W[35]^(W[39]>>25))&(1<<5))) != 0 {
+ mask &= ^DV_I_51_2_bit
+ }
+ }
+ if (mask & DV_I_52_0_bit) != 0 {
+ mask &= (((W[38] ^ W[39]) << 11) | ^DV_I_52_0_bit)
+ }
+ if (mask & DV_II_46_2_bit) != 0 {
+ mask &= (((W[47] ^ W[51]) << 17) | ^DV_II_46_2_bit)
+ }
+ if (mask & DV_II_48_0_bit) != 0 {
+ if not(not((W[36]^(W[40]>>25))&(1<<3))) != 0 ||
+ not((W[35]^(W[40]<<2))&(1<<30)) != 0 {
+ mask &= ^DV_II_48_0_bit
+ }
+ }
+ if (mask & DV_II_49_0_bit) != 0 {
+ if not(not((W[37]^(W[41]>>25))&(1<<3))) != 0 ||
+ not((W[36]^(W[41]<<2))&(1<<30)) != 0 {
+ mask &= ^DV_II_49_0_bit
+ }
+ }
+ if (mask & DV_II_49_2_bit) != 0 {
+ if not(not((W[53]^(W[54]<<5))&(1<<6))) != 0 ||
+ not(not((W[51]^W[53])&(1<<6))) != 0 ||
+ not((W[50]^W[54])&(1<<1)) != 0 ||
+ not(not((W[45]^(W[46]<<5))&(1<<6))) != 0 ||
+ not(not((W[37]^(W[41]>>25))&(1<<5))) != 0 ||
+ not((W[36]^(W[41]>>30))&(1<<0)) != 0 {
+ mask &= ^DV_II_49_2_bit
+ }
+ }
+ if (mask & DV_II_50_0_bit) != 0 {
+ if not((W[55]^W[58])&(1<<29)) != 0 ||
+ not(not((W[38]^(W[42]>>25))&(1<<3))) != 0 ||
+ not((W[37]^(W[42]<<2))&(1<<30)) != 0 {
+ mask &= ^DV_II_50_0_bit
+ }
+ }
+ if (mask & DV_II_50_2_bit) != 0 {
+ if not(not((W[54]^(W[55]<<5))&(1<<6))) != 0 ||
+ not(not((W[52]^W[54])&(1<<6))) != 0 ||
+ not((W[51]^W[55])&(1<<1)) != 0 ||
+ not((W[45]^W[47])&(1<<1)) != 0 ||
+ not(not((W[38]^(W[42]>>25))&(1<<5))) != 0 ||
+ not((W[37]^(W[42]>>30))&(1<<0)) != 0 {
+ mask &= ^DV_II_50_2_bit
+ }
+ }
+ if (mask & DV_II_51_0_bit) != 0 {
+ if not(not((W[39]^(W[43]>>25))&(1<<3))) != 0 ||
+ not((W[38]^(W[43]<<2))&(1<<30)) != 0 {
+ mask &= ^DV_II_51_0_bit
+ }
+ }
+ if (mask & DV_II_51_2_bit) != 0 {
+ if not(not((W[55]^(W[56]<<5))&(1<<6))) != 0 ||
+ not(not((W[53]^W[55])&(1<<6))) != 0 ||
+ not((W[52]^W[56])&(1<<1)) != 0 ||
+ not((W[46]^W[48])&(1<<1)) != 0 ||
+ not(not((W[39]^(W[43]>>25))&(1<<5))) != 0 ||
+ not((W[38]^(W[43]>>30))&(1<<0)) != 0 {
+ mask &= ^DV_II_51_2_bit
+ }
+ }
+ if (mask & DV_II_52_0_bit) != 0 {
+ if not(not((W[59]^W[60])&(1<<29))) != 0 ||
+ not(not((W[40]^(W[44]>>25))&(1<<3))) != 0 ||
+ not(not((W[40]^(W[44]>>25))&(1<<4))) != 0 ||
+ not((W[39]^(W[44]<<2))&(1<<30)) != 0 {
+ mask &= ^DV_II_52_0_bit
+ }
+ }
+ if (mask & DV_II_53_0_bit) != 0 {
+ if not((W[58]^W[61])&(1<<29)) != 0 ||
+ not(not((W[57]^(W[61]>>25))&(1<<4))) != 0 ||
+ not(not((W[41]^(W[45]>>25))&(1<<3))) != 0 ||
+ not(not((W[41]^(W[45]>>25))&(1<<4))) != 0 {
+ mask &= ^DV_II_53_0_bit
+ }
+ }
+ if (mask & DV_II_54_0_bit) != 0 {
+ if not(not((W[58]^(W[62]>>25))&(1<<4))) != 0 ||
+ not(not((W[42]^(W[46]>>25))&(1<<3))) != 0 ||
+ not(not((W[42]^(W[46]>>25))&(1<<4))) != 0 {
+ mask &= ^DV_II_54_0_bit
+ }
+ }
+ if (mask & DV_II_55_0_bit) != 0 {
+ if not(not((W[59]^(W[63]>>25))&(1<<4))) != 0 ||
+ not(not((W[57]^(W[59]>>25))&(1<<4))) != 0 ||
+ not(not((W[43]^(W[47]>>25))&(1<<3))) != 0 ||
+ not(not((W[43]^(W[47]>>25))&(1<<4))) != 0 {
+ mask &= ^DV_II_55_0_bit
+ }
+ }
+ if (mask & DV_II_56_0_bit) != 0 {
+ if not(not((W[60]^(W[64]>>25))&(1<<4))) != 0 ||
+ not(not((W[44]^(W[48]>>25))&(1<<3))) != 0 ||
+ not(not((W[44]^(W[48]>>25))&(1<<4))) != 0 {
+ mask &= ^DV_II_56_0_bit
+ }
+ }
+ }
+
+ return mask
+}
+
+func not(x uint32) uint32 {
+ if x == 0 {
+ return 1
+ }
+
+ return 0
+}
+
+func SHA1_dvs() []DvInfo {
+ return sha1_dvs
+}
diff --git a/vendor/github.com/pjbgf/sha1cd/ubc/const.go b/vendor/github.com/pjbgf/sha1cd/ubc/const.go
new file mode 100644
index 00000000..eac14f46
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/ubc/const.go
@@ -0,0 +1,624 @@
+// Based on the C implementation from Marc Stevens and Dan Shumow.
+// https://github.com/cr-marcstevens/sha1collisiondetection
+
+package ubc
+
+const (
+ CheckSize = 80
+
+ DV_I_43_0_bit = (uint32)(1 << 0)
+ DV_I_44_0_bit = (uint32)(1 << 1)
+ DV_I_45_0_bit = (uint32)(1 << 2)
+ DV_I_46_0_bit = (uint32)(1 << 3)
+ DV_I_46_2_bit = (uint32)(1 << 4)
+ DV_I_47_0_bit = (uint32)(1 << 5)
+ DV_I_47_2_bit = (uint32)(1 << 6)
+ DV_I_48_0_bit = (uint32)(1 << 7)
+ DV_I_48_2_bit = (uint32)(1 << 8)
+ DV_I_49_0_bit = (uint32)(1 << 9)
+ DV_I_49_2_bit = (uint32)(1 << 10)
+ DV_I_50_0_bit = (uint32)(1 << 11)
+ DV_I_50_2_bit = (uint32)(1 << 12)
+ DV_I_51_0_bit = (uint32)(1 << 13)
+ DV_I_51_2_bit = (uint32)(1 << 14)
+ DV_I_52_0_bit = (uint32)(1 << 15)
+ DV_II_45_0_bit = (uint32)(1 << 16)
+ DV_II_46_0_bit = (uint32)(1 << 17)
+ DV_II_46_2_bit = (uint32)(1 << 18)
+ DV_II_47_0_bit = (uint32)(1 << 19)
+ DV_II_48_0_bit = (uint32)(1 << 20)
+ DV_II_49_0_bit = (uint32)(1 << 21)
+ DV_II_49_2_bit = (uint32)(1 << 22)
+ DV_II_50_0_bit = (uint32)(1 << 23)
+ DV_II_50_2_bit = (uint32)(1 << 24)
+ DV_II_51_0_bit = (uint32)(1 << 25)
+ DV_II_51_2_bit = (uint32)(1 << 26)
+ DV_II_52_0_bit = (uint32)(1 << 27)
+ DV_II_53_0_bit = (uint32)(1 << 28)
+ DV_II_54_0_bit = (uint32)(1 << 29)
+ DV_II_55_0_bit = (uint32)(1 << 30)
+ DV_II_56_0_bit = (uint32)(1 << 31)
+)
+
+// sha1_dvs contains a list of SHA-1 Disturbance Vectors (DV) which defines the
+// unavoidable bit conditions when a collision attack is in progress.
+var sha1_dvs = []DvInfo{
+ {
+ DvType: 1, DvK: 43, DvB: 0, TestT: 58, MaskI: 0, MaskB: 0,
+ Dm: [CheckSize]uint32{
+ 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000,
+ 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010,
+ 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000,
+ 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018,
+ 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000,
+ 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010,
+ 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040,
+ 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009,
+ 0x80000012, 0x80000202, 0x00000018, 0x00000164, 0x00000408, 0x800000e6, 0x8000004c,
+ 0x00000803, 0x80000161, 0x80000599},
+ }, {
+ DvType: 1, DvK: 44, DvB: 0, TestT: 58, MaskI: 0, MaskB: 1,
+ Dm: [CheckSize]uint32{
+ 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000,
+ 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000,
+ 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008,
+ 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010,
+ 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010,
+ 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000,
+ 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002,
+ 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103,
+ 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164, 0x00000408, 0x800000e6,
+ 0x8000004c, 0x00000803, 0x80000161},
+ },
+ {
+ DvType: 1, DvK: 45, DvB: 0, TestT: 58, MaskI: 0, MaskB: 2,
+ Dm: [CheckSize]uint32{
+ 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010,
+ 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014,
+ 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010,
+ 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000,
+ 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000,
+ 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010,
+ 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000,
+ 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001,
+ 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049,
+ 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164, 0x00000408,
+ 0x800000e6, 0x8000004c, 0x00000803},
+ },
+ {
+ DvType: 1, DvK: 46, DvB: 0, TestT: 58, MaskI: 0, MaskB: 3,
+ Dm: [CheckSize]uint32{
+ 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010,
+ 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010,
+ 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010,
+ 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000,
+ 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000,
+ 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000,
+ 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000,
+ 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020,
+ 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006,
+ 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164,
+ 0x00000408, 0x800000e6, 0x8000004c},
+ },
+ {
+ DvType: 1, DvK: 46, DvB: 2, TestT: 58, MaskI: 0, MaskB: 4,
+ Dm: [CheckSize]uint32{
+ 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, 0x60000032, 0x60000043,
+ 0x20000040, 0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003,
+ 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, 0x20000001,
+ 0x20000060, 0x80000001, 0x40000042, 0xc0000043, 0x40000022, 0x00000003,
+ 0x40000042, 0xc0000043, 0xc0000022, 0x00000001, 0x40000002, 0xc0000043,
+ 0x40000062, 0x80000001, 0x40000042, 0x40000042, 0x40000002, 0x00000002,
+ 0x00000040, 0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000,
+ 0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040, 0x80000002,
+ 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000101,
+ 0x00000009, 0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c,
+ 0x00000026, 0x0000004a, 0x0000080a, 0x00000060, 0x00000590, 0x00001020,
+ 0x0000039a, 0x00000132},
+ },
+ {
+ DvType: 1, DvK: 47, DvB: 0, TestT: 58, MaskI: 0, MaskB: 5,
+ Dm: [CheckSize]uint32{
+ 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c,
+ 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008,
+ 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010,
+ 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008,
+ 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000,
+ 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000,
+ 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010,
+ 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010,
+ 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002,
+ 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049,
+ 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164,
+ 0x00000408, 0x800000e6},
+ },
+ {
+ DvType: 1, DvK: 47, DvB: 2, TestT: 58, MaskI: 0, MaskB: 6,
+ Dm: [CheckSize]uint32{
+ 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, 0x60000032,
+ 0x60000043, 0x20000040, 0xe0000042, 0x60000002, 0x80000001, 0x00000020,
+ 0x00000003, 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040,
+ 0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043, 0x40000022,
+ 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, 0x00000001, 0x40000002,
+ 0xc0000043, 0x40000062, 0x80000001, 0x40000042, 0x40000042, 0x40000002,
+ 0x00000002, 0x00000040, 0x80000002, 0x80000000, 0x80000002, 0x80000040,
+ 0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040,
+ 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004, 0x00000009,
+ 0x00000101, 0x00000009, 0x00000012, 0x00000202, 0x0000001a, 0x00000124,
+ 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, 0x00000060, 0x00000590,
+ 0x00001020, 0x0000039a,
+ },
+ },
+ {
+ DvType: 1, DvK: 48, DvB: 0, TestT: 58, MaskI: 0, MaskB: 7,
+ Dm: [CheckSize]uint32{
+ 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000,
+ 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000,
+ 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000,
+ 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010,
+ 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000,
+ 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010,
+ 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000,
+ 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000,
+ 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001,
+ 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006,
+ 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018,
+ 0x00000164, 0x00000408,
+ },
+ },
+ {
+ DvType: 1, DvK: 48, DvB: 2, TestT: 58, MaskI: 0, MaskB: 8,
+ Dm: [CheckSize]uint32{
+ 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000,
+ 0x60000032, 0x60000043, 0x20000040, 0xe0000042, 0x60000002, 0x80000001,
+ 0x00000020, 0x00000003, 0x40000052, 0x40000040, 0xe0000052, 0xa0000000,
+ 0x80000040, 0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043,
+ 0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, 0x00000001,
+ 0x40000002, 0xc0000043, 0x40000062, 0x80000001, 0x40000042, 0x40000042,
+ 0x40000002, 0x00000002, 0x00000040, 0x80000002, 0x80000000, 0x80000002,
+ 0x80000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000000,
+ 0x00000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004,
+ 0x00000009, 0x00000101, 0x00000009, 0x00000012, 0x00000202, 0x0000001a,
+ 0x00000124, 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, 0x00000060,
+ 0x00000590, 0x00001020},
+ },
+ {
+ DvType: 1, DvK: 49, DvB: 0, TestT: 58, MaskI: 0, MaskB: 9,
+ Dm: [CheckSize]uint32{
+ 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008,
+ 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000,
+ 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014,
+ 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010,
+ 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008,
+ 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010,
+ 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000,
+ 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010,
+ 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020,
+ 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080,
+ 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202,
+ 0x00000018, 0x00000164},
+ },
+ {
+ DvType: 1, DvK: 49, DvB: 2, TestT: 58, MaskI: 0, MaskB: 10,
+ Dm: [CheckSize]uint32{
+ 0x60000000, 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022,
+ 0x20000000, 0x60000032, 0x60000043, 0x20000040, 0xe0000042, 0x60000002,
+ 0x80000001, 0x00000020, 0x00000003, 0x40000052, 0x40000040, 0xe0000052,
+ 0xa0000000, 0x80000040, 0x20000001, 0x20000060, 0x80000001, 0x40000042,
+ 0xc0000043, 0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022,
+ 0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001, 0x40000042,
+ 0x40000042, 0x40000002, 0x00000002, 0x00000040, 0x80000002, 0x80000000,
+ 0x80000002, 0x80000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040,
+ 0x80000000, 0x00000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080,
+ 0x00000004, 0x00000009, 0x00000101, 0x00000009, 0x00000012, 0x00000202,
+ 0x0000001a, 0x00000124, 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a,
+ 0x00000060, 0x00000590},
+ },
+ {
+ DvType: 1, DvK: 50, DvB: 0, TestT: 65, MaskI: 0, MaskB: 11,
+ Dm: [CheckSize]uint32{
+ 0x0800000c, 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014,
+ 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010,
+ 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010,
+ 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000,
+ 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010,
+ 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000,
+ 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000,
+ 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000,
+ 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000,
+ 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+ 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004,
+ 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012,
+ 0x80000202, 0x00000018,
+ },
+ },
+ {
+ DvType: 1, DvK: 50, DvB: 2, TestT: 65, MaskI: 0, MaskB: 12,
+ Dm: [CheckSize]uint32{
+ 0x20000030, 0x60000000, 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053,
+ 0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040, 0xe0000042,
+ 0x60000002, 0x80000001, 0x00000020, 0x00000003, 0x40000052, 0x40000040,
+ 0xe0000052, 0xa0000000, 0x80000040, 0x20000001, 0x20000060, 0x80000001,
+ 0x40000042, 0xc0000043, 0x40000022, 0x00000003, 0x40000042, 0xc0000043,
+ 0xc0000022, 0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001,
+ 0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040, 0x80000002,
+ 0x80000000, 0x80000002, 0x80000040, 0x00000000, 0x80000040, 0x80000000,
+ 0x00000040, 0x80000000, 0x00000040, 0x80000002, 0x00000000, 0x80000000,
+ 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009, 0x00000012,
+ 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, 0x00000026, 0x0000004a,
+ 0x0000080a, 0x00000060},
+ },
+ {
+ DvType: 1, DvK: 51, DvB: 0, TestT: 65, MaskI: 0, MaskB: 13,
+ Dm: [CheckSize]uint32{
+ 0xe8000000, 0x0800000c, 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010,
+ 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010,
+ 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014,
+ 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018,
+ 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010,
+ 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018,
+ 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010,
+ 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010,
+ 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000,
+ 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002,
+ 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009,
+ 0x80000012, 0x80000202},
+ },
+ {
+ DvType: 1, DvK: 51, DvB: 2, TestT: 65, MaskI: 0, MaskB: 14,
+ Dm: [CheckSize]uint32{
+ 0xa0000003, 0x20000030, 0x60000000, 0xe000002a, 0x20000043, 0xb0000040,
+ 0xd0000053, 0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040,
+ 0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003, 0x40000052,
+ 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, 0x20000001, 0x20000060,
+ 0x80000001, 0x40000042, 0xc0000043, 0x40000022, 0x00000003, 0x40000042,
+ 0xc0000043, 0xc0000022, 0x00000001, 0x40000002, 0xc0000043, 0x40000062,
+ 0x80000001, 0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040,
+ 0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000, 0x80000040,
+ 0x80000000, 0x00000040, 0x80000000, 0x00000040, 0x80000002, 0x00000000,
+ 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009,
+ 0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, 0x00000026,
+ 0x0000004a, 0x0000080a},
+ },
+ {
+ DvType: 1, DvK: 52, DvB: 0, TestT: 65, MaskI: 0, MaskB: 15,
+ Dm: [CheckSize]uint32{
+ 0x04000010, 0xe8000000, 0x0800000c, 0x18000000, 0xb800000a, 0xc8000010,
+ 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010,
+ 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000,
+ 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000,
+ 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000,
+ 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010,
+ 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000,
+ 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000,
+ 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000,
+ 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040,
+ 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103,
+ 0x80000009, 0x80000012},
+ },
+ {
+ DvType: 2, DvK: 45, DvB: 0, TestT: 58, MaskI: 0, MaskB: 16,
+ Dm: [CheckSize]uint32{
+ 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018,
+ 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014,
+ 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c,
+ 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000,
+ 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010,
+ 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000,
+ 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010,
+ 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010,
+ 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022,
+ 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089,
+ 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, 0x8000041a, 0x000002e4,
+ 0x80000054, 0x00000967},
+ },
+ {
+ DvType: 2, DvK: 46, DvB: 0, TestT: 58, MaskI: 0, MaskB: 17,
+ Dm: [CheckSize]uint32{
+ 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004,
+ 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010,
+ 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010,
+ 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000,
+ 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000,
+ 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000,
+ 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000,
+ 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000,
+ 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000,
+ 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041,
+ 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107,
+ 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, 0x8000041a,
+ 0x000002e4, 0x80000054},
+ },
+ {
+ DvType: 2, DvK: 46, DvB: 2, TestT: 58, MaskI: 0, MaskB: 18,
+ Dm: [CheckSize]uint32{
+ 0x90000070, 0xb0000053, 0x30000008, 0x00000043, 0xd0000072, 0xb0000010,
+ 0xf0000062, 0xc0000042, 0x00000030, 0xe0000042, 0x20000060, 0xe0000041,
+ 0x20000050, 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012, 0x60000041,
+ 0xc0000032, 0x20000001, 0xc0000002, 0xe0000042, 0x60000042, 0x80000002,
+ 0x00000000, 0x00000000, 0x80000000, 0x00000002, 0x00000040, 0x00000000,
+ 0x80000040, 0x80000000, 0x00000040, 0x80000001, 0x00000060, 0x80000003,
+ 0x40000002, 0xc0000040, 0xc0000002, 0x80000000, 0x80000000, 0x80000002,
+ 0x00000040, 0x00000002, 0x80000000, 0x80000000, 0x80000000, 0x00000002,
+ 0x00000040, 0x00000000, 0x80000040, 0x80000002, 0x00000000, 0x80000000,
+ 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000105,
+ 0x00000089, 0x00000016, 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e,
+ 0x00000224, 0x00000050, 0x0000092e, 0x0000046c, 0x000005b6, 0x0000106a,
+ 0x00000b90, 0x00000152},
+ },
+ {
+ DvType: 2, DvK: 47, DvB: 0, TestT: 58, MaskI: 0, MaskB: 19,
+ Dm: [CheckSize]uint32{
+ 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c,
+ 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018,
+ 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004,
+ 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010,
+ 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010,
+ 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018,
+ 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000,
+ 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000,
+ 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000,
+ 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002,
+ 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b,
+ 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d,
+ 0x8000041a, 0x000002e4},
+ },
+ {
+ DvType: 2, DvK: 48, DvB: 0, TestT: 58, MaskI: 0, MaskB: 20,
+ Dm: [CheckSize]uint32{
+ 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010,
+ 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010,
+ 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000,
+ 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010,
+ 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000,
+ 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000,
+ 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000,
+ 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000,
+ 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000,
+ 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001,
+ 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046,
+ 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b,
+ 0x8000016d, 0x8000041a},
+ },
+ {
+ DvType: 2, DvK: 49, DvB: 0, TestT: 58, MaskI: 0, MaskB: 21,
+ Dm: [CheckSize]uint32{
+ 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002,
+ 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c,
+ 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c,
+ 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000,
+ 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000,
+ 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010,
+ 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000,
+ 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000,
+ 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010,
+ 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020,
+ 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082,
+ 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b,
+ 0x0000011b, 0x8000016d},
+ },
+ {
+ DvType: 2, DvK: 49, DvB: 2, TestT: 58, MaskI: 0, MaskB: 22,
+ Dm: [CheckSize]uint32{
+ 0xf0000010, 0xf000006a, 0x80000040, 0x90000070, 0xb0000053, 0x30000008,
+ 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062, 0xc0000042, 0x00000030,
+ 0xe0000042, 0x20000060, 0xe0000041, 0x20000050, 0xc0000041, 0xe0000072,
+ 0xa0000003, 0xc0000012, 0x60000041, 0xc0000032, 0x20000001, 0xc0000002,
+ 0xe0000042, 0x60000042, 0x80000002, 0x00000000, 0x00000000, 0x80000000,
+ 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040,
+ 0x80000001, 0x00000060, 0x80000003, 0x40000002, 0xc0000040, 0xc0000002,
+ 0x80000000, 0x80000000, 0x80000002, 0x00000040, 0x00000002, 0x80000000,
+ 0x80000000, 0x80000000, 0x00000002, 0x00000040, 0x00000000, 0x80000040,
+ 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080,
+ 0x00000004, 0x00000009, 0x00000105, 0x00000089, 0x00000016, 0x0000020b,
+ 0x0000011b, 0x0000012d, 0x0000041e, 0x00000224, 0x00000050, 0x0000092e,
+ 0x0000046c, 0x000005b6},
+ },
+ {
+ DvType: 2, DvK: 50, DvB: 0, TestT: 65, MaskI: 0, MaskB: 23,
+ Dm: [CheckSize]uint32{
+ 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014,
+ 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010,
+ 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010,
+ 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000,
+ 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000,
+ 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000,
+ 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010,
+ 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000,
+ 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000,
+ 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+ 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005,
+ 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014,
+ 0x8000024b, 0x0000011b},
+ },
+ {
+ DvType: 2, DvK: 50, DvB: 2, TestT: 65, MaskI: 0, MaskB: 24,
+ Dm: [CheckSize]uint32{
+ 0xd0000072, 0xf0000010, 0xf000006a, 0x80000040, 0x90000070, 0xb0000053,
+ 0x30000008, 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062, 0xc0000042,
+ 0x00000030, 0xe0000042, 0x20000060, 0xe0000041, 0x20000050, 0xc0000041,
+ 0xe0000072, 0xa0000003, 0xc0000012, 0x60000041, 0xc0000032, 0x20000001,
+ 0xc0000002, 0xe0000042, 0x60000042, 0x80000002, 0x00000000, 0x00000000,
+ 0x80000000, 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000000,
+ 0x00000040, 0x80000001, 0x00000060, 0x80000003, 0x40000002, 0xc0000040,
+ 0xc0000002, 0x80000000, 0x80000000, 0x80000002, 0x00000040, 0x00000002,
+ 0x80000000, 0x80000000, 0x80000000, 0x00000002, 0x00000040, 0x00000000,
+ 0x80000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000080, 0x00000004, 0x00000009, 0x00000105, 0x00000089, 0x00000016,
+ 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e, 0x00000224, 0x00000050,
+ 0x0000092e, 0x0000046c},
+ },
+ {
+ DvType: 2, DvK: 51, DvB: 0, TestT: 65, MaskI: 0, MaskB: 25,
+ Dm: [CheckSize]uint32{
+ 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c,
+ 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018,
+ 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014,
+ 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c,
+ 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000,
+ 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010,
+ 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000,
+ 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010,
+ 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010,
+ 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022,
+ 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089,
+ 0x00000014, 0x8000024b},
+ },
+ {
+ DvType: 2, DvK: 51, DvB: 2, TestT: 65, MaskI: 0, MaskB: 26,
+ Dm: [CheckSize]uint32{
+ 0x00000043, 0xd0000072, 0xf0000010, 0xf000006a, 0x80000040, 0x90000070,
+ 0xb0000053, 0x30000008, 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062,
+ 0xc0000042, 0x00000030, 0xe0000042, 0x20000060, 0xe0000041, 0x20000050,
+ 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012, 0x60000041, 0xc0000032,
+ 0x20000001, 0xc0000002, 0xe0000042, 0x60000042, 0x80000002, 0x00000000,
+ 0x00000000, 0x80000000, 0x00000002, 0x00000040, 0x00000000, 0x80000040,
+ 0x80000000, 0x00000040, 0x80000001, 0x00000060, 0x80000003, 0x40000002,
+ 0xc0000040, 0xc0000002, 0x80000000, 0x80000000, 0x80000002, 0x00000040,
+ 0x00000002, 0x80000000, 0x80000000, 0x80000000, 0x00000002, 0x00000040,
+ 0x00000000, 0x80000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000105, 0x00000089,
+ 0x00000016, 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e, 0x00000224,
+ 0x00000050, 0x0000092e},
+ },
+ {
+ DvType: 2, DvK: 52, DvB: 0, TestT: 65, MaskI: 0, MaskB: 27,
+ Dm: [CheckSize]uint32{
+ 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010,
+ 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004,
+ 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010,
+ 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010,
+ 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000,
+ 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000,
+ 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000,
+ 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000,
+ 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000,
+ 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000,
+ 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041,
+ 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107,
+ 0x00000089, 0x00000014},
+ },
+ {
+ DvType: 2, DvK: 53, DvB: 0, TestT: 65, MaskI: 0, MaskB: 28,
+ Dm: [CheckSize]uint32{
+ 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a,
+ 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c,
+ 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018,
+ 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004,
+ 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010,
+ 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010,
+ 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018,
+ 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000,
+ 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000,
+ 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000,
+ 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002,
+ 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b,
+ 0x80000107, 0x00000089},
+ },
+ {
+ DvType: 2, DvK: 54, DvB: 0, TestT: 65, MaskI: 0, MaskB: 29,
+ Dm: [CheckSize]uint32{
+ 0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004,
+ 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010,
+ 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010,
+ 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000,
+ 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010,
+ 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000,
+ 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000,
+ 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000,
+ 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000,
+ 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000,
+ 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001,
+ 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046,
+ 0x4000004b, 0x80000107},
+ },
+ {
+ DvType: 2, DvK: 55, DvB: 0, TestT: 65, MaskI: 0, MaskB: 30,
+ Dm: [CheckSize]uint32{
+ 0x00000010, 0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c,
+ 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002,
+ 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c,
+ 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c,
+ 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000,
+ 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000,
+ 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010,
+ 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000,
+ 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000,
+ 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010,
+ 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020,
+ 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082,
+ 0xc0000046, 0x4000004b},
+ },
+ {
+ DvType: 2, DvK: 56, DvB: 0, TestT: 65, MaskI: 0, MaskB: 31,
+ Dm: [CheckSize]uint32{
+ 0x2600001a, 0x00000010, 0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010,
+ 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014,
+ 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010,
+ 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010,
+ 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000,
+ 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000,
+ 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000,
+ 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010,
+ 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000,
+ 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000,
+ 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+ 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005,
+ 0xc0000082, 0xc0000046},
+ },
+ {
+ DvType: 0, DvK: 0, DvB: 0, TestT: 0, MaskI: 0, MaskB: 0,
+ Dm: [CheckSize]uint32{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0},
+ },
+}
diff --git a/vendor/github.com/pjbgf/sha1cd/ubc/doc.go b/vendor/github.com/pjbgf/sha1cd/ubc/doc.go
new file mode 100644
index 00000000..0090e36b
--- /dev/null
+++ b/vendor/github.com/pjbgf/sha1cd/ubc/doc.go
@@ -0,0 +1,3 @@
+// ubc package provides ways for SHA1 blocks to be checked for
+// Unavoidable Bit Conditions that arise from crypto analysis attacks.
+package ubc
diff --git a/vendor/github.com/sergi/go-diff/AUTHORS b/vendor/github.com/sergi/go-diff/AUTHORS
new file mode 100644
index 00000000..2d7bb2bf
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/AUTHORS
@@ -0,0 +1,25 @@
+# This is the official list of go-diff authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+
+# Names should be added to this file as
+# Name or Organization
+# The email address is not required for organizations.
+
+# Please keep the list sorted.
+
+Danny Yoo
+James Kolb
+Jonathan Amsterdam
+Markus Zimmermann
+Matt Kovars
+Örjan Persson
+Osman Masood
+Robert Carlsen
+Rory Flynn
+Sergi Mansilla
+Shatrugna Sadhu
+Shawn Smith
+Stas Maksimov
+Tor Arvid Lund
+Zac Bergquist
diff --git a/vendor/github.com/sergi/go-diff/CONTRIBUTORS b/vendor/github.com/sergi/go-diff/CONTRIBUTORS
new file mode 100644
index 00000000..369e3d55
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/CONTRIBUTORS
@@ -0,0 +1,32 @@
+# This is the official list of people who can contribute
+# (and typically have contributed) code to the go-diff
+# repository.
+#
+# The AUTHORS file lists the copyright holders; this file
+# lists people. For example, ACME Inc. employees would be listed here
+# but not in AUTHORS, because ACME Inc. would hold the copyright.
+#
+# When adding J Random Contributor's name to this file,
+# either J's name or J's organization's name should be
+# added to the AUTHORS file.
+#
+# Names should be added to this file like so:
+# Name
+#
+# Please keep the list sorted.
+
+Danny Yoo
+James Kolb
+Jonathan Amsterdam
+Markus Zimmermann
+Matt Kovars
+Örjan Persson
+Osman Masood
+Robert Carlsen
+Rory Flynn
+Sergi Mansilla
+Shatrugna Sadhu
+Shawn Smith
+Stas Maksimov
+Tor Arvid Lund
+Zac Bergquist
diff --git a/vendor/github.com/sergi/go-diff/LICENSE b/vendor/github.com/sergi/go-diff/LICENSE
new file mode 100644
index 00000000..937942c2
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2012-2016 The go-diff Authors. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go
new file mode 100644
index 00000000..915d5090
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go
@@ -0,0 +1,1347 @@
+// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
+// https://github.com/sergi/go-diff
+// See the included LICENSE file for license details.
+//
+// go-diff is a Go implementation of Google's Diff, Match, and Patch library
+// Original library is Copyright (c) 2006 Google Inc.
+// http://code.google.com/p/google-diff-match-patch/
+
+package diffmatchpatch
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "html"
+ "math"
+ "net/url"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+)
+
+// Operation defines the operation of a diff item.
+type Operation int8
+
+//go:generate stringer -type=Operation -trimprefix=Diff
+
+const (
+ // DiffDelete item represents a delete diff.
+ DiffDelete Operation = -1
+ // DiffInsert item represents an insert diff.
+ DiffInsert Operation = 1
+ // DiffEqual item represents an equal diff.
+ DiffEqual Operation = 0
+)
+
+// Diff represents one diff operation
+type Diff struct {
+ Type Operation
+ Text string
+}
+
+// splice removes amount elements from slice at index index, replacing them with elements.
+func splice(slice []Diff, index int, amount int, elements ...Diff) []Diff {
+ if len(elements) == amount {
+ // Easy case: overwrite the relevant items.
+ copy(slice[index:], elements)
+ return slice
+ }
+ if len(elements) < amount {
+ // Fewer new items than old.
+ // Copy in the new items.
+ copy(slice[index:], elements)
+ // Shift the remaining items left.
+ copy(slice[index+len(elements):], slice[index+amount:])
+ // Calculate the new end of the slice.
+ end := len(slice) - amount + len(elements)
+ // Zero stranded elements at end so that they can be garbage collected.
+ tail := slice[end:]
+ for i := range tail {
+ tail[i] = Diff{}
+ }
+ return slice[:end]
+ }
+ // More new items than old.
+ // Make room in slice for new elements.
+ // There's probably an even more efficient way to do this,
+ // but this is simple and clear.
+ need := len(slice) - amount + len(elements)
+ for len(slice) < need {
+ slice = append(slice, Diff{})
+ }
+ // Shift slice elements right to make room for new elements.
+ copy(slice[index+len(elements):], slice[index+amount:])
+ // Copy in new elements.
+ copy(slice[index:], elements)
+ return slice
+}
+
+// DiffMain finds the differences between two texts.
+// If an invalid UTF-8 sequence is encountered, it will be replaced by the Unicode replacement character.
+func (dmp *DiffMatchPatch) DiffMain(text1, text2 string, checklines bool) []Diff {
+ return dmp.DiffMainRunes([]rune(text1), []rune(text2), checklines)
+}
+
+// DiffMainRunes finds the differences between two rune sequences.
+// If an invalid UTF-8 sequence is encountered, it will be replaced by the Unicode replacement character.
+func (dmp *DiffMatchPatch) DiffMainRunes(text1, text2 []rune, checklines bool) []Diff {
+ var deadline time.Time
+ if dmp.DiffTimeout > 0 {
+ deadline = time.Now().Add(dmp.DiffTimeout)
+ }
+ return dmp.diffMainRunes(text1, text2, checklines, deadline)
+}
+
+func (dmp *DiffMatchPatch) diffMainRunes(text1, text2 []rune, checklines bool, deadline time.Time) []Diff {
+ if runesEqual(text1, text2) {
+ var diffs []Diff
+ if len(text1) > 0 {
+ diffs = append(diffs, Diff{DiffEqual, string(text1)})
+ }
+ return diffs
+ }
+ // Trim off common prefix (speedup).
+ commonlength := commonPrefixLength(text1, text2)
+ commonprefix := text1[:commonlength]
+ text1 = text1[commonlength:]
+ text2 = text2[commonlength:]
+
+ // Trim off common suffix (speedup).
+ commonlength = commonSuffixLength(text1, text2)
+ commonsuffix := text1[len(text1)-commonlength:]
+ text1 = text1[:len(text1)-commonlength]
+ text2 = text2[:len(text2)-commonlength]
+
+ // Compute the diff on the middle block.
+ diffs := dmp.diffCompute(text1, text2, checklines, deadline)
+
+ // Restore the prefix and suffix.
+ if len(commonprefix) != 0 {
+ diffs = append([]Diff{{DiffEqual, string(commonprefix)}}, diffs...)
+ }
+ if len(commonsuffix) != 0 {
+ diffs = append(diffs, Diff{DiffEqual, string(commonsuffix)})
+ }
+
+ return dmp.DiffCleanupMerge(diffs)
+}
+
+// diffCompute finds the differences between two rune slices. Assumes that the texts do not have any common prefix or suffix.
+func (dmp *DiffMatchPatch) diffCompute(text1, text2 []rune, checklines bool, deadline time.Time) []Diff {
+ diffs := []Diff{}
+ if len(text1) == 0 {
+ // Just add some text (speedup).
+ return append(diffs, Diff{DiffInsert, string(text2)})
+ } else if len(text2) == 0 {
+ // Just delete some text (speedup).
+ return append(diffs, Diff{DiffDelete, string(text1)})
+ }
+
+ var longtext, shorttext []rune
+ if len(text1) > len(text2) {
+ longtext = text1
+ shorttext = text2
+ } else {
+ longtext = text2
+ shorttext = text1
+ }
+
+ if i := runesIndex(longtext, shorttext); i != -1 {
+ op := DiffInsert
+ // Swap insertions for deletions if diff is reversed.
+ if len(text1) > len(text2) {
+ op = DiffDelete
+ }
+ // Shorter text is inside the longer text (speedup).
+ return []Diff{
+ Diff{op, string(longtext[:i])},
+ Diff{DiffEqual, string(shorttext)},
+ Diff{op, string(longtext[i+len(shorttext):])},
+ }
+ } else if len(shorttext) == 1 {
+ // Single character string.
+ // After the previous speedup, the character can't be an equality.
+ return []Diff{
+ {DiffDelete, string(text1)},
+ {DiffInsert, string(text2)},
+ }
+ // Check to see if the problem can be split in two.
+ } else if hm := dmp.diffHalfMatch(text1, text2); hm != nil {
+ // A half-match was found, sort out the return data.
+ text1A := hm[0]
+ text1B := hm[1]
+ text2A := hm[2]
+ text2B := hm[3]
+ midCommon := hm[4]
+ // Send both pairs off for separate processing.
+ diffsA := dmp.diffMainRunes(text1A, text2A, checklines, deadline)
+ diffsB := dmp.diffMainRunes(text1B, text2B, checklines, deadline)
+ // Merge the results.
+ diffs := diffsA
+ diffs = append(diffs, Diff{DiffEqual, string(midCommon)})
+ diffs = append(diffs, diffsB...)
+ return diffs
+ } else if checklines && len(text1) > 100 && len(text2) > 100 {
+ return dmp.diffLineMode(text1, text2, deadline)
+ }
+ return dmp.diffBisect(text1, text2, deadline)
+}
+
+// diffLineMode does a quick line-level diff on both []runes, then rediff the parts for greater accuracy. This speedup can produce non-minimal diffs.
+func (dmp *DiffMatchPatch) diffLineMode(text1, text2 []rune, deadline time.Time) []Diff {
+ // Scan the text on a line-by-line basis first.
+ text1, text2, linearray := dmp.DiffLinesToRunes(string(text1), string(text2))
+
+ diffs := dmp.diffMainRunes(text1, text2, false, deadline)
+
+ // Convert the diff back to original text.
+ diffs = dmp.DiffCharsToLines(diffs, linearray)
+ // Eliminate freak matches (e.g. blank lines)
+ diffs = dmp.DiffCleanupSemantic(diffs)
+
+ // Rediff any replacement blocks, this time character-by-character.
+ // Add a dummy entry at the end.
+ diffs = append(diffs, Diff{DiffEqual, ""})
+
+ pointer := 0
+ countDelete := 0
+ countInsert := 0
+
+ // NOTE: Rune slices are slower than using strings in this case.
+ textDelete := ""
+ textInsert := ""
+
+ for pointer < len(diffs) {
+ switch diffs[pointer].Type {
+ case DiffInsert:
+ countInsert++
+ textInsert += diffs[pointer].Text
+ case DiffDelete:
+ countDelete++
+ textDelete += diffs[pointer].Text
+ case DiffEqual:
+ // Upon reaching an equality, check for prior redundancies.
+ if countDelete >= 1 && countInsert >= 1 {
+ // Delete the offending records and add the merged ones.
+ diffs = splice(diffs, pointer-countDelete-countInsert,
+ countDelete+countInsert)
+
+ pointer = pointer - countDelete - countInsert
+ a := dmp.diffMainRunes([]rune(textDelete), []rune(textInsert), false, deadline)
+ for j := len(a) - 1; j >= 0; j-- {
+ diffs = splice(diffs, pointer, 0, a[j])
+ }
+ pointer = pointer + len(a)
+ }
+
+ countInsert = 0
+ countDelete = 0
+ textDelete = ""
+ textInsert = ""
+ }
+ pointer++
+ }
+
+ return diffs[:len(diffs)-1] // Remove the dummy entry at the end.
+}
+
+// DiffBisect finds the 'middle snake' of a diff, split the problem in two and return the recursively constructed diff.
+// If an invalid UTF-8 sequence is encountered, it will be replaced by the Unicode replacement character.
+// See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.
+func (dmp *DiffMatchPatch) DiffBisect(text1, text2 string, deadline time.Time) []Diff {
+ // Unused in this code, but retained for interface compatibility.
+ return dmp.diffBisect([]rune(text1), []rune(text2), deadline)
+}
+
+// diffBisect finds the 'middle snake' of a diff, splits the problem in two and returns the recursively constructed diff.
+// See Myers's 1986 paper: An O(ND) Difference Algorithm and Its Variations.
+func (dmp *DiffMatchPatch) diffBisect(runes1, runes2 []rune, deadline time.Time) []Diff {
+ // Cache the text lengths to prevent multiple calls.
+ runes1Len, runes2Len := len(runes1), len(runes2)
+
+ maxD := (runes1Len + runes2Len + 1) / 2
+ vOffset := maxD
+ vLength := 2 * maxD
+
+ v1 := make([]int, vLength)
+ v2 := make([]int, vLength)
+ for i := range v1 {
+ v1[i] = -1
+ v2[i] = -1
+ }
+ v1[vOffset+1] = 0
+ v2[vOffset+1] = 0
+
+ delta := runes1Len - runes2Len
+ // If the total number of characters is odd, then the front path will collide with the reverse path.
+ front := (delta%2 != 0)
+ // Offsets for start and end of k loop. Prevents mapping of space beyond the grid.
+ k1start := 0
+ k1end := 0
+ k2start := 0
+ k2end := 0
+ for d := 0; d < maxD; d++ {
+ // Bail out if deadline is reached.
+ if !deadline.IsZero() && d%16 == 0 && time.Now().After(deadline) {
+ break
+ }
+
+ // Walk the front path one step.
+ for k1 := -d + k1start; k1 <= d-k1end; k1 += 2 {
+ k1Offset := vOffset + k1
+ var x1 int
+
+ if k1 == -d || (k1 != d && v1[k1Offset-1] < v1[k1Offset+1]) {
+ x1 = v1[k1Offset+1]
+ } else {
+ x1 = v1[k1Offset-1] + 1
+ }
+
+ y1 := x1 - k1
+ for x1 < runes1Len && y1 < runes2Len {
+ if runes1[x1] != runes2[y1] {
+ break
+ }
+ x1++
+ y1++
+ }
+ v1[k1Offset] = x1
+ if x1 > runes1Len {
+ // Ran off the right of the graph.
+ k1end += 2
+ } else if y1 > runes2Len {
+ // Ran off the bottom of the graph.
+ k1start += 2
+ } else if front {
+ k2Offset := vOffset + delta - k1
+ if k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] != -1 {
+ // Mirror x2 onto top-left coordinate system.
+ x2 := runes1Len - v2[k2Offset]
+ if x1 >= x2 {
+ // Overlap detected.
+ return dmp.diffBisectSplit(runes1, runes2, x1, y1, deadline)
+ }
+ }
+ }
+ }
+ // Walk the reverse path one step.
+ for k2 := -d + k2start; k2 <= d-k2end; k2 += 2 {
+ k2Offset := vOffset + k2
+ var x2 int
+ if k2 == -d || (k2 != d && v2[k2Offset-1] < v2[k2Offset+1]) {
+ x2 = v2[k2Offset+1]
+ } else {
+ x2 = v2[k2Offset-1] + 1
+ }
+ var y2 = x2 - k2
+ for x2 < runes1Len && y2 < runes2Len {
+ if runes1[runes1Len-x2-1] != runes2[runes2Len-y2-1] {
+ break
+ }
+ x2++
+ y2++
+ }
+ v2[k2Offset] = x2
+ if x2 > runes1Len {
+ // Ran off the left of the graph.
+ k2end += 2
+ } else if y2 > runes2Len {
+ // Ran off the top of the graph.
+ k2start += 2
+ } else if !front {
+ k1Offset := vOffset + delta - k2
+ if k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] != -1 {
+ x1 := v1[k1Offset]
+ y1 := vOffset + x1 - k1Offset
+ // Mirror x2 onto top-left coordinate system.
+ x2 = runes1Len - x2
+ if x1 >= x2 {
+ // Overlap detected.
+ return dmp.diffBisectSplit(runes1, runes2, x1, y1, deadline)
+ }
+ }
+ }
+ }
+ }
+ // Diff took too long and hit the deadline or number of diffs equals number of characters, no commonality at all.
+ return []Diff{
+ {DiffDelete, string(runes1)},
+ {DiffInsert, string(runes2)},
+ }
+}
+
+func (dmp *DiffMatchPatch) diffBisectSplit(runes1, runes2 []rune, x, y int,
+ deadline time.Time) []Diff {
+ runes1a := runes1[:x]
+ runes2a := runes2[:y]
+ runes1b := runes1[x:]
+ runes2b := runes2[y:]
+
+ // Compute both diffs serially.
+ diffs := dmp.diffMainRunes(runes1a, runes2a, false, deadline)
+ diffsb := dmp.diffMainRunes(runes1b, runes2b, false, deadline)
+
+ return append(diffs, diffsb...)
+}
+
+// DiffLinesToChars splits two texts into a list of strings, and educes the texts to a string of hashes where each Unicode character represents one line.
+// It's slightly faster to call DiffLinesToRunes first, followed by DiffMainRunes.
+func (dmp *DiffMatchPatch) DiffLinesToChars(text1, text2 string) (string, string, []string) {
+ chars1, chars2, lineArray := dmp.diffLinesToStrings(text1, text2)
+ return chars1, chars2, lineArray
+}
+
+// DiffLinesToRunes splits two texts into a list of runes.
+func (dmp *DiffMatchPatch) DiffLinesToRunes(text1, text2 string) ([]rune, []rune, []string) {
+ chars1, chars2, lineArray := dmp.diffLinesToStrings(text1, text2)
+ return []rune(chars1), []rune(chars2), lineArray
+}
+
+// DiffCharsToLines rehydrates the text in a diff from a string of line hashes to real lines of text.
+func (dmp *DiffMatchPatch) DiffCharsToLines(diffs []Diff, lineArray []string) []Diff {
+ hydrated := make([]Diff, 0, len(diffs))
+ for _, aDiff := range diffs {
+ runes := []rune(aDiff.Text)
+ text := make([]string, len(runes))
+
+ for i, r := range runes {
+ text[i] = lineArray[runeToInt(r)]
+ }
+
+ aDiff.Text = strings.Join(text, "")
+ hydrated = append(hydrated, aDiff)
+ }
+ return hydrated
+}
+
+// DiffCommonPrefix determines the common prefix length of two strings.
+func (dmp *DiffMatchPatch) DiffCommonPrefix(text1, text2 string) int {
+ // Unused in this code, but retained for interface compatibility.
+ return commonPrefixLength([]rune(text1), []rune(text2))
+}
+
+// DiffCommonSuffix determines the common suffix length of two strings.
+func (dmp *DiffMatchPatch) DiffCommonSuffix(text1, text2 string) int {
+ // Unused in this code, but retained for interface compatibility.
+ return commonSuffixLength([]rune(text1), []rune(text2))
+}
+
+// commonPrefixLength returns the length of the common prefix of two rune slices.
+func commonPrefixLength(text1, text2 []rune) int {
+ // Linear search. See comment in commonSuffixLength.
+ n := 0
+ for ; n < len(text1) && n < len(text2); n++ {
+ if text1[n] != text2[n] {
+ return n
+ }
+ }
+ return n
+}
+
+// commonSuffixLength returns the length of the common suffix of two rune slices.
+func commonSuffixLength(text1, text2 []rune) int {
+ // Use linear search rather than the binary search discussed at https://neil.fraser.name/news/2007/10/09/.
+ // See discussion at https://github.com/sergi/go-diff/issues/54.
+ i1 := len(text1)
+ i2 := len(text2)
+ for n := 0; ; n++ {
+ i1--
+ i2--
+ if i1 < 0 || i2 < 0 || text1[i1] != text2[i2] {
+ return n
+ }
+ }
+}
+
+// DiffCommonOverlap determines if the suffix of one string is the prefix of another.
+func (dmp *DiffMatchPatch) DiffCommonOverlap(text1 string, text2 string) int {
+ // Cache the text lengths to prevent multiple calls.
+ text1Length := len(text1)
+ text2Length := len(text2)
+ // Eliminate the null case.
+ if text1Length == 0 || text2Length == 0 {
+ return 0
+ }
+ // Truncate the longer string.
+ if text1Length > text2Length {
+ text1 = text1[text1Length-text2Length:]
+ } else if text1Length < text2Length {
+ text2 = text2[0:text1Length]
+ }
+ textLength := int(math.Min(float64(text1Length), float64(text2Length)))
+ // Quick check for the worst case.
+ if text1 == text2 {
+ return textLength
+ }
+
+ // Start by looking for a single character match and increase length until no match is found. Performance analysis: http://neil.fraser.name/news/2010/11/04/
+ best := 0
+ length := 1
+ for {
+ pattern := text1[textLength-length:]
+ found := strings.Index(text2, pattern)
+ if found == -1 {
+ break
+ }
+ length += found
+ if found == 0 || text1[textLength-length:] == text2[0:length] {
+ best = length
+ length++
+ }
+ }
+
+ return best
+}
+
+// DiffHalfMatch checks whether the two texts share a substring which is at least half the length of the longer text. This speedup can produce non-minimal diffs.
+func (dmp *DiffMatchPatch) DiffHalfMatch(text1, text2 string) []string {
+ // Unused in this code, but retained for interface compatibility.
+ runeSlices := dmp.diffHalfMatch([]rune(text1), []rune(text2))
+ if runeSlices == nil {
+ return nil
+ }
+
+ result := make([]string, len(runeSlices))
+ for i, r := range runeSlices {
+ result[i] = string(r)
+ }
+ return result
+}
+
+func (dmp *DiffMatchPatch) diffHalfMatch(text1, text2 []rune) [][]rune {
+ if dmp.DiffTimeout <= 0 {
+ // Don't risk returning a non-optimal diff if we have unlimited time.
+ return nil
+ }
+
+ var longtext, shorttext []rune
+ if len(text1) > len(text2) {
+ longtext = text1
+ shorttext = text2
+ } else {
+ longtext = text2
+ shorttext = text1
+ }
+
+ if len(longtext) < 4 || len(shorttext)*2 < len(longtext) {
+ return nil // Pointless.
+ }
+
+ // First check if the second quarter is the seed for a half-match.
+ hm1 := dmp.diffHalfMatchI(longtext, shorttext, int(float64(len(longtext)+3)/4))
+
+ // Check again based on the third quarter.
+ hm2 := dmp.diffHalfMatchI(longtext, shorttext, int(float64(len(longtext)+1)/2))
+
+ hm := [][]rune{}
+ if hm1 == nil && hm2 == nil {
+ return nil
+ } else if hm2 == nil {
+ hm = hm1
+ } else if hm1 == nil {
+ hm = hm2
+ } else {
+ // Both matched. Select the longest.
+ if len(hm1[4]) > len(hm2[4]) {
+ hm = hm1
+ } else {
+ hm = hm2
+ }
+ }
+
+ // A half-match was found, sort out the return data.
+ if len(text1) > len(text2) {
+ return hm
+ }
+
+ return [][]rune{hm[2], hm[3], hm[0], hm[1], hm[4]}
+}
+
+// diffHalfMatchI checks if a substring of shorttext exist within longtext such that the substring is at least half the length of longtext?
+// Returns a slice containing the prefix of longtext, the suffix of longtext, the prefix of shorttext, the suffix of shorttext and the common middle, or null if there was no match.
+func (dmp *DiffMatchPatch) diffHalfMatchI(l, s []rune, i int) [][]rune {
+ var bestCommonA []rune
+ var bestCommonB []rune
+ var bestCommonLen int
+ var bestLongtextA []rune
+ var bestLongtextB []rune
+ var bestShorttextA []rune
+ var bestShorttextB []rune
+
+ // Start with a 1/4 length substring at position i as a seed.
+ seed := l[i : i+len(l)/4]
+
+ for j := runesIndexOf(s, seed, 0); j != -1; j = runesIndexOf(s, seed, j+1) {
+ prefixLength := commonPrefixLength(l[i:], s[j:])
+ suffixLength := commonSuffixLength(l[:i], s[:j])
+
+ if bestCommonLen < suffixLength+prefixLength {
+ bestCommonA = s[j-suffixLength : j]
+ bestCommonB = s[j : j+prefixLength]
+ bestCommonLen = len(bestCommonA) + len(bestCommonB)
+ bestLongtextA = l[:i-suffixLength]
+ bestLongtextB = l[i+prefixLength:]
+ bestShorttextA = s[:j-suffixLength]
+ bestShorttextB = s[j+prefixLength:]
+ }
+ }
+
+ if bestCommonLen*2 < len(l) {
+ return nil
+ }
+
+ return [][]rune{
+ bestLongtextA,
+ bestLongtextB,
+ bestShorttextA,
+ bestShorttextB,
+ append(bestCommonA, bestCommonB...),
+ }
+}
+
+// DiffCleanupSemantic reduces the number of edits by eliminating semantically trivial equalities.
+func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff {
+ changes := false
+ // Stack of indices where equalities are found.
+ equalities := make([]int, 0, len(diffs))
+
+ var lastequality string
+ // Always equal to diffs[equalities[equalitiesLength - 1]][1]
+ var pointer int // Index of current position.
+ // Number of characters that changed prior to the equality.
+ var lengthInsertions1, lengthDeletions1 int
+ // Number of characters that changed after the equality.
+ var lengthInsertions2, lengthDeletions2 int
+
+ for pointer < len(diffs) {
+ if diffs[pointer].Type == DiffEqual {
+ // Equality found.
+ equalities = append(equalities, pointer)
+ lengthInsertions1 = lengthInsertions2
+ lengthDeletions1 = lengthDeletions2
+ lengthInsertions2 = 0
+ lengthDeletions2 = 0
+ lastequality = diffs[pointer].Text
+ } else {
+ // An insertion or deletion.
+
+ if diffs[pointer].Type == DiffInsert {
+ lengthInsertions2 += utf8.RuneCountInString(diffs[pointer].Text)
+ } else {
+ lengthDeletions2 += utf8.RuneCountInString(diffs[pointer].Text)
+ }
+ // Eliminate an equality that is smaller or equal to the edits on both sides of it.
+ difference1 := int(math.Max(float64(lengthInsertions1), float64(lengthDeletions1)))
+ difference2 := int(math.Max(float64(lengthInsertions2), float64(lengthDeletions2)))
+ if utf8.RuneCountInString(lastequality) > 0 &&
+ (utf8.RuneCountInString(lastequality) <= difference1) &&
+ (utf8.RuneCountInString(lastequality) <= difference2) {
+ // Duplicate record.
+ insPoint := equalities[len(equalities)-1]
+ diffs = splice(diffs, insPoint, 0, Diff{DiffDelete, lastequality})
+
+ // Change second copy to insert.
+ diffs[insPoint+1].Type = DiffInsert
+ // Throw away the equality we just deleted.
+ equalities = equalities[:len(equalities)-1]
+
+ if len(equalities) > 0 {
+ equalities = equalities[:len(equalities)-1]
+ }
+ pointer = -1
+ if len(equalities) > 0 {
+ pointer = equalities[len(equalities)-1]
+ }
+
+ lengthInsertions1 = 0 // Reset the counters.
+ lengthDeletions1 = 0
+ lengthInsertions2 = 0
+ lengthDeletions2 = 0
+ lastequality = ""
+ changes = true
+ }
+ }
+ pointer++
+ }
+
+ // Normalize the diff.
+ if changes {
+ diffs = dmp.DiffCleanupMerge(diffs)
+ }
+ diffs = dmp.DiffCleanupSemanticLossless(diffs)
+ // Find any overlaps between deletions and insertions.
+ // e.g: ]abcxxxxxxdef
+ // -> abcxxxdef
+ // e.g: xxxabcdefxxx
+ // -> defxxxabc
+ // Only extract an overlap if it is as big as the edit ahead or behind it.
+ pointer = 1
+ for pointer < len(diffs) {
+ if diffs[pointer-1].Type == DiffDelete &&
+ diffs[pointer].Type == DiffInsert {
+ deletion := diffs[pointer-1].Text
+ insertion := diffs[pointer].Text
+ overlapLength1 := dmp.DiffCommonOverlap(deletion, insertion)
+ overlapLength2 := dmp.DiffCommonOverlap(insertion, deletion)
+ if overlapLength1 >= overlapLength2 {
+ if float64(overlapLength1) >= float64(utf8.RuneCountInString(deletion))/2 ||
+ float64(overlapLength1) >= float64(utf8.RuneCountInString(insertion))/2 {
+
+ // Overlap found. Insert an equality and trim the surrounding edits.
+ diffs = splice(diffs, pointer, 0, Diff{DiffEqual, insertion[:overlapLength1]})
+ diffs[pointer-1].Text =
+ deletion[0 : len(deletion)-overlapLength1]
+ diffs[pointer+1].Text = insertion[overlapLength1:]
+ pointer++
+ }
+ } else {
+ if float64(overlapLength2) >= float64(utf8.RuneCountInString(deletion))/2 ||
+ float64(overlapLength2) >= float64(utf8.RuneCountInString(insertion))/2 {
+ // Reverse overlap found. Insert an equality and swap and trim the surrounding edits.
+ overlap := Diff{DiffEqual, deletion[:overlapLength2]}
+ diffs = splice(diffs, pointer, 0, overlap)
+ diffs[pointer-1].Type = DiffInsert
+ diffs[pointer-1].Text = insertion[0 : len(insertion)-overlapLength2]
+ diffs[pointer+1].Type = DiffDelete
+ diffs[pointer+1].Text = deletion[overlapLength2:]
+ pointer++
+ }
+ }
+ pointer++
+ }
+ pointer++
+ }
+
+ return diffs
+}
+
+// Define some regex patterns for matching boundaries.
+var (
+ nonAlphaNumericRegex = regexp.MustCompile(`[^a-zA-Z0-9]`)
+ whitespaceRegex = regexp.MustCompile(`\s`)
+ linebreakRegex = regexp.MustCompile(`[\r\n]`)
+ blanklineEndRegex = regexp.MustCompile(`\n\r?\n$`)
+ blanklineStartRegex = regexp.MustCompile(`^\r?\n\r?\n`)
+)
+
+// diffCleanupSemanticScore computes a score representing whether the internal boundary falls on logical boundaries.
+// Scores range from 6 (best) to 0 (worst). Closure, but does not reference any external variables.
+func diffCleanupSemanticScore(one, two string) int {
+ if len(one) == 0 || len(two) == 0 {
+ // Edges are the best.
+ return 6
+ }
+
+ // Each port of this function behaves slightly differently due to subtle differences in each language's definition of things like 'whitespace'. Since this function's purpose is largely cosmetic, the choice has been made to use each language's native features rather than force total conformity.
+ rune1, _ := utf8.DecodeLastRuneInString(one)
+ rune2, _ := utf8.DecodeRuneInString(two)
+ char1 := string(rune1)
+ char2 := string(rune2)
+
+ nonAlphaNumeric1 := nonAlphaNumericRegex.MatchString(char1)
+ nonAlphaNumeric2 := nonAlphaNumericRegex.MatchString(char2)
+ whitespace1 := nonAlphaNumeric1 && whitespaceRegex.MatchString(char1)
+ whitespace2 := nonAlphaNumeric2 && whitespaceRegex.MatchString(char2)
+ lineBreak1 := whitespace1 && linebreakRegex.MatchString(char1)
+ lineBreak2 := whitespace2 && linebreakRegex.MatchString(char2)
+ blankLine1 := lineBreak1 && blanklineEndRegex.MatchString(one)
+ blankLine2 := lineBreak2 && blanklineEndRegex.MatchString(two)
+
+ if blankLine1 || blankLine2 {
+ // Five points for blank lines.
+ return 5
+ } else if lineBreak1 || lineBreak2 {
+ // Four points for line breaks.
+ return 4
+ } else if nonAlphaNumeric1 && !whitespace1 && whitespace2 {
+ // Three points for end of sentences.
+ return 3
+ } else if whitespace1 || whitespace2 {
+ // Two points for whitespace.
+ return 2
+ } else if nonAlphaNumeric1 || nonAlphaNumeric2 {
+ // One point for non-alphanumeric.
+ return 1
+ }
+ return 0
+}
+
+// DiffCleanupSemanticLossless looks for single edits surrounded on both sides by equalities which can be shifted sideways to align the edit to a word boundary.
+// E.g: The cat came. -> The cat came.
+func (dmp *DiffMatchPatch) DiffCleanupSemanticLossless(diffs []Diff) []Diff {
+ pointer := 1
+
+ // Intentionally ignore the first and last element (don't need checking).
+ for pointer < len(diffs)-1 {
+ if diffs[pointer-1].Type == DiffEqual &&
+ diffs[pointer+1].Type == DiffEqual {
+
+ // This is a single edit surrounded by equalities.
+ equality1 := diffs[pointer-1].Text
+ edit := diffs[pointer].Text
+ equality2 := diffs[pointer+1].Text
+
+ // First, shift the edit as far left as possible.
+ commonOffset := dmp.DiffCommonSuffix(equality1, edit)
+ if commonOffset > 0 {
+ commonString := edit[len(edit)-commonOffset:]
+ equality1 = equality1[0 : len(equality1)-commonOffset]
+ edit = commonString + edit[:len(edit)-commonOffset]
+ equality2 = commonString + equality2
+ }
+
+ // Second, step character by character right, looking for the best fit.
+ bestEquality1 := equality1
+ bestEdit := edit
+ bestEquality2 := equality2
+ bestScore := diffCleanupSemanticScore(equality1, edit) +
+ diffCleanupSemanticScore(edit, equality2)
+
+ for len(edit) != 0 && len(equality2) != 0 {
+ _, sz := utf8.DecodeRuneInString(edit)
+ if len(equality2) < sz || edit[:sz] != equality2[:sz] {
+ break
+ }
+ equality1 += edit[:sz]
+ edit = edit[sz:] + equality2[:sz]
+ equality2 = equality2[sz:]
+ score := diffCleanupSemanticScore(equality1, edit) +
+ diffCleanupSemanticScore(edit, equality2)
+ // The >= encourages trailing rather than leading whitespace on edits.
+ if score >= bestScore {
+ bestScore = score
+ bestEquality1 = equality1
+ bestEdit = edit
+ bestEquality2 = equality2
+ }
+ }
+
+ if diffs[pointer-1].Text != bestEquality1 {
+ // We have an improvement, save it back to the diff.
+ if len(bestEquality1) != 0 {
+ diffs[pointer-1].Text = bestEquality1
+ } else {
+ diffs = splice(diffs, pointer-1, 1)
+ pointer--
+ }
+
+ diffs[pointer].Text = bestEdit
+ if len(bestEquality2) != 0 {
+ diffs[pointer+1].Text = bestEquality2
+ } else {
+ diffs = append(diffs[:pointer+1], diffs[pointer+2:]...)
+ pointer--
+ }
+ }
+ }
+ pointer++
+ }
+
+ return diffs
+}
+
+// DiffCleanupEfficiency reduces the number of edits by eliminating operationally trivial equalities.
+func (dmp *DiffMatchPatch) DiffCleanupEfficiency(diffs []Diff) []Diff {
+ changes := false
+ // Stack of indices where equalities are found.
+ type equality struct {
+ data int
+ next *equality
+ }
+ var equalities *equality
+ // Always equal to equalities[equalitiesLength-1][1]
+ lastequality := ""
+ pointer := 0 // Index of current position.
+ // Is there an insertion operation before the last equality.
+ preIns := false
+ // Is there a deletion operation before the last equality.
+ preDel := false
+ // Is there an insertion operation after the last equality.
+ postIns := false
+ // Is there a deletion operation after the last equality.
+ postDel := false
+ for pointer < len(diffs) {
+ if diffs[pointer].Type == DiffEqual { // Equality found.
+ if len(diffs[pointer].Text) < dmp.DiffEditCost &&
+ (postIns || postDel) {
+ // Candidate found.
+ equalities = &equality{
+ data: pointer,
+ next: equalities,
+ }
+ preIns = postIns
+ preDel = postDel
+ lastequality = diffs[pointer].Text
+ } else {
+ // Not a candidate, and can never become one.
+ equalities = nil
+ lastequality = ""
+ }
+ postIns = false
+ postDel = false
+ } else { // An insertion or deletion.
+ if diffs[pointer].Type == DiffDelete {
+ postDel = true
+ } else {
+ postIns = true
+ }
+
+ // Five types to be split:
+ // ABXYCD
+ // AXCD
+ // ABXC
+ // AXCD
+ // ABXC
+ var sumPres int
+ if preIns {
+ sumPres++
+ }
+ if preDel {
+ sumPres++
+ }
+ if postIns {
+ sumPres++
+ }
+ if postDel {
+ sumPres++
+ }
+ if len(lastequality) > 0 &&
+ ((preIns && preDel && postIns && postDel) ||
+ ((len(lastequality) < dmp.DiffEditCost/2) && sumPres == 3)) {
+
+ insPoint := equalities.data
+
+ // Duplicate record.
+ diffs = splice(diffs, insPoint, 0, Diff{DiffDelete, lastequality})
+
+ // Change second copy to insert.
+ diffs[insPoint+1].Type = DiffInsert
+ // Throw away the equality we just deleted.
+ equalities = equalities.next
+ lastequality = ""
+
+ if preIns && preDel {
+ // No changes made which could affect previous entry, keep going.
+ postIns = true
+ postDel = true
+ equalities = nil
+ } else {
+ if equalities != nil {
+ equalities = equalities.next
+ }
+ if equalities != nil {
+ pointer = equalities.data
+ } else {
+ pointer = -1
+ }
+ postIns = false
+ postDel = false
+ }
+ changes = true
+ }
+ }
+ pointer++
+ }
+
+ if changes {
+ diffs = dmp.DiffCleanupMerge(diffs)
+ }
+
+ return diffs
+}
+
+// DiffCleanupMerge reorders and merges like edit sections. Merge equalities.
+// Any edit section can move as long as it doesn't cross an equality.
+func (dmp *DiffMatchPatch) DiffCleanupMerge(diffs []Diff) []Diff {
+ // Add a dummy entry at the end.
+ diffs = append(diffs, Diff{DiffEqual, ""})
+ pointer := 0
+ countDelete := 0
+ countInsert := 0
+ commonlength := 0
+ textDelete := []rune(nil)
+ textInsert := []rune(nil)
+
+ for pointer < len(diffs) {
+ switch diffs[pointer].Type {
+ case DiffInsert:
+ countInsert++
+ textInsert = append(textInsert, []rune(diffs[pointer].Text)...)
+ pointer++
+ break
+ case DiffDelete:
+ countDelete++
+ textDelete = append(textDelete, []rune(diffs[pointer].Text)...)
+ pointer++
+ break
+ case DiffEqual:
+ // Upon reaching an equality, check for prior redundancies.
+ if countDelete+countInsert > 1 {
+ if countDelete != 0 && countInsert != 0 {
+ // Factor out any common prefixies.
+ commonlength = commonPrefixLength(textInsert, textDelete)
+ if commonlength != 0 {
+ x := pointer - countDelete - countInsert
+ if x > 0 && diffs[x-1].Type == DiffEqual {
+ diffs[x-1].Text += string(textInsert[:commonlength])
+ } else {
+ diffs = append([]Diff{{DiffEqual, string(textInsert[:commonlength])}}, diffs...)
+ pointer++
+ }
+ textInsert = textInsert[commonlength:]
+ textDelete = textDelete[commonlength:]
+ }
+ // Factor out any common suffixies.
+ commonlength = commonSuffixLength(textInsert, textDelete)
+ if commonlength != 0 {
+ insertIndex := len(textInsert) - commonlength
+ deleteIndex := len(textDelete) - commonlength
+ diffs[pointer].Text = string(textInsert[insertIndex:]) + diffs[pointer].Text
+ textInsert = textInsert[:insertIndex]
+ textDelete = textDelete[:deleteIndex]
+ }
+ }
+ // Delete the offending records and add the merged ones.
+ if countDelete == 0 {
+ diffs = splice(diffs, pointer-countInsert,
+ countDelete+countInsert,
+ Diff{DiffInsert, string(textInsert)})
+ } else if countInsert == 0 {
+ diffs = splice(diffs, pointer-countDelete,
+ countDelete+countInsert,
+ Diff{DiffDelete, string(textDelete)})
+ } else {
+ diffs = splice(diffs, pointer-countDelete-countInsert,
+ countDelete+countInsert,
+ Diff{DiffDelete, string(textDelete)},
+ Diff{DiffInsert, string(textInsert)})
+ }
+
+ pointer = pointer - countDelete - countInsert + 1
+ if countDelete != 0 {
+ pointer++
+ }
+ if countInsert != 0 {
+ pointer++
+ }
+ } else if pointer != 0 && diffs[pointer-1].Type == DiffEqual {
+ // Merge this equality with the previous one.
+ diffs[pointer-1].Text += diffs[pointer].Text
+ diffs = append(diffs[:pointer], diffs[pointer+1:]...)
+ } else {
+ pointer++
+ }
+ countInsert = 0
+ countDelete = 0
+ textDelete = nil
+ textInsert = nil
+ break
+ }
+ }
+
+ if len(diffs[len(diffs)-1].Text) == 0 {
+ diffs = diffs[0 : len(diffs)-1] // Remove the dummy entry at the end.
+ }
+
+ // Second pass: look for single edits surrounded on both sides by equalities which can be shifted sideways to eliminate an equality. E.g: ABAC -> ABAC
+ changes := false
+ pointer = 1
+ // Intentionally ignore the first and last element (don't need checking).
+ for pointer < (len(diffs) - 1) {
+ if diffs[pointer-1].Type == DiffEqual &&
+ diffs[pointer+1].Type == DiffEqual {
+ // This is a single edit surrounded by equalities.
+ if strings.HasSuffix(diffs[pointer].Text, diffs[pointer-1].Text) {
+ // Shift the edit over the previous equality.
+ diffs[pointer].Text = diffs[pointer-1].Text +
+ diffs[pointer].Text[:len(diffs[pointer].Text)-len(diffs[pointer-1].Text)]
+ diffs[pointer+1].Text = diffs[pointer-1].Text + diffs[pointer+1].Text
+ diffs = splice(diffs, pointer-1, 1)
+ changes = true
+ } else if strings.HasPrefix(diffs[pointer].Text, diffs[pointer+1].Text) {
+ // Shift the edit over the next equality.
+ diffs[pointer-1].Text += diffs[pointer+1].Text
+ diffs[pointer].Text =
+ diffs[pointer].Text[len(diffs[pointer+1].Text):] + diffs[pointer+1].Text
+ diffs = splice(diffs, pointer+1, 1)
+ changes = true
+ }
+ }
+ pointer++
+ }
+
+ // If shifts were made, the diff needs reordering and another shift sweep.
+ if changes {
+ diffs = dmp.DiffCleanupMerge(diffs)
+ }
+
+ return diffs
+}
+
+// DiffXIndex returns the equivalent location in s2.
+func (dmp *DiffMatchPatch) DiffXIndex(diffs []Diff, loc int) int {
+ chars1 := 0
+ chars2 := 0
+ lastChars1 := 0
+ lastChars2 := 0
+ lastDiff := Diff{}
+ for i := 0; i < len(diffs); i++ {
+ aDiff := diffs[i]
+ if aDiff.Type != DiffInsert {
+ // Equality or deletion.
+ chars1 += len(aDiff.Text)
+ }
+ if aDiff.Type != DiffDelete {
+ // Equality or insertion.
+ chars2 += len(aDiff.Text)
+ }
+ if chars1 > loc {
+ // Overshot the location.
+ lastDiff = aDiff
+ break
+ }
+ lastChars1 = chars1
+ lastChars2 = chars2
+ }
+ if lastDiff.Type == DiffDelete {
+ // The location was deleted.
+ return lastChars2
+ }
+ // Add the remaining character length.
+ return lastChars2 + (loc - lastChars1)
+}
+
+// DiffPrettyHtml converts a []Diff into a pretty HTML report.
+// It is intended as an example from which to write one's own display functions.
+func (dmp *DiffMatchPatch) DiffPrettyHtml(diffs []Diff) string {
+ var buff bytes.Buffer
+ for _, diff := range diffs {
+ text := strings.Replace(html.EscapeString(diff.Text), "\n", "¶
", -1)
+ switch diff.Type {
+ case DiffInsert:
+ _, _ = buff.WriteString("")
+ _, _ = buff.WriteString(text)
+ _, _ = buff.WriteString("")
+ case DiffDelete:
+ _, _ = buff.WriteString("")
+ _, _ = buff.WriteString(text)
+ _, _ = buff.WriteString("")
+ case DiffEqual:
+ _, _ = buff.WriteString("")
+ _, _ = buff.WriteString(text)
+ _, _ = buff.WriteString("")
+ }
+ }
+ return buff.String()
+}
+
+// DiffPrettyText converts a []Diff into a colored text report.
+func (dmp *DiffMatchPatch) DiffPrettyText(diffs []Diff) string {
+ var buff bytes.Buffer
+ for _, diff := range diffs {
+ text := diff.Text
+
+ switch diff.Type {
+ case DiffInsert:
+ _, _ = buff.WriteString("\x1b[32m")
+ _, _ = buff.WriteString(text)
+ _, _ = buff.WriteString("\x1b[0m")
+ case DiffDelete:
+ _, _ = buff.WriteString("\x1b[31m")
+ _, _ = buff.WriteString(text)
+ _, _ = buff.WriteString("\x1b[0m")
+ case DiffEqual:
+ _, _ = buff.WriteString(text)
+ }
+ }
+
+ return buff.String()
+}
+
+// DiffText1 computes and returns the source text (all equalities and deletions).
+func (dmp *DiffMatchPatch) DiffText1(diffs []Diff) string {
+ //StringBuilder text = new StringBuilder()
+ var text bytes.Buffer
+
+ for _, aDiff := range diffs {
+ if aDiff.Type != DiffInsert {
+ _, _ = text.WriteString(aDiff.Text)
+ }
+ }
+ return text.String()
+}
+
+// DiffText2 computes and returns the destination text (all equalities and insertions).
+func (dmp *DiffMatchPatch) DiffText2(diffs []Diff) string {
+ var text bytes.Buffer
+
+ for _, aDiff := range diffs {
+ if aDiff.Type != DiffDelete {
+ _, _ = text.WriteString(aDiff.Text)
+ }
+ }
+ return text.String()
+}
+
+// DiffLevenshtein computes the Levenshtein distance that is the number of inserted, deleted or substituted characters.
+func (dmp *DiffMatchPatch) DiffLevenshtein(diffs []Diff) int {
+ levenshtein := 0
+ insertions := 0
+ deletions := 0
+
+ for _, aDiff := range diffs {
+ switch aDiff.Type {
+ case DiffInsert:
+ insertions += utf8.RuneCountInString(aDiff.Text)
+ case DiffDelete:
+ deletions += utf8.RuneCountInString(aDiff.Text)
+ case DiffEqual:
+ // A deletion and an insertion is one substitution.
+ levenshtein += max(insertions, deletions)
+ insertions = 0
+ deletions = 0
+ }
+ }
+
+ levenshtein += max(insertions, deletions)
+ return levenshtein
+}
+
+// DiffToDelta crushes the diff into an encoded string which describes the operations required to transform text1 into text2.
+// E.g. =3\t-2\t+ing -> Keep 3 chars, delete 2 chars, insert 'ing'. Operations are tab-separated. Inserted text is escaped using %xx notation.
+func (dmp *DiffMatchPatch) DiffToDelta(diffs []Diff) string {
+ var text bytes.Buffer
+ for _, aDiff := range diffs {
+ switch aDiff.Type {
+ case DiffInsert:
+ _, _ = text.WriteString("+")
+ _, _ = text.WriteString(strings.Replace(url.QueryEscape(aDiff.Text), "+", " ", -1))
+ _, _ = text.WriteString("\t")
+ break
+ case DiffDelete:
+ _, _ = text.WriteString("-")
+ _, _ = text.WriteString(strconv.Itoa(utf8.RuneCountInString(aDiff.Text)))
+ _, _ = text.WriteString("\t")
+ break
+ case DiffEqual:
+ _, _ = text.WriteString("=")
+ _, _ = text.WriteString(strconv.Itoa(utf8.RuneCountInString(aDiff.Text)))
+ _, _ = text.WriteString("\t")
+ break
+ }
+ }
+ delta := text.String()
+ if len(delta) != 0 {
+ // Strip off trailing tab character.
+ delta = delta[0 : utf8.RuneCountInString(delta)-1]
+ delta = unescaper.Replace(delta)
+ }
+ return delta
+}
+
+// DiffFromDelta given the original text1, and an encoded string which describes the operations required to transform text1 into text2, comAdde the full diff.
+func (dmp *DiffMatchPatch) DiffFromDelta(text1 string, delta string) (diffs []Diff, err error) {
+ i := 0
+ runes := []rune(text1)
+
+ for _, token := range strings.Split(delta, "\t") {
+ if len(token) == 0 {
+ // Blank tokens are ok (from a trailing \t).
+ continue
+ }
+
+ // Each token begins with a one character parameter which specifies the operation of this token (delete, insert, equality).
+ param := token[1:]
+
+ switch op := token[0]; op {
+ case '+':
+ // Decode would Diff all "+" to " "
+ param = strings.Replace(param, "+", "%2b", -1)
+ param, err = url.QueryUnescape(param)
+ if err != nil {
+ return nil, err
+ }
+ if !utf8.ValidString(param) {
+ return nil, fmt.Errorf("invalid UTF-8 token: %q", param)
+ }
+
+ diffs = append(diffs, Diff{DiffInsert, param})
+ case '=', '-':
+ n, err := strconv.ParseInt(param, 10, 0)
+ if err != nil {
+ return nil, err
+ } else if n < 0 {
+ return nil, errors.New("Negative number in DiffFromDelta: " + param)
+ }
+
+ i += int(n)
+ // Break out if we are out of bounds, go1.6 can't handle this very well
+ if i > len(runes) {
+ break
+ }
+ // Remember that string slicing is by byte - we want by rune here.
+ text := string(runes[i-int(n) : i])
+
+ if op == '=' {
+ diffs = append(diffs, Diff{DiffEqual, text})
+ } else {
+ diffs = append(diffs, Diff{DiffDelete, text})
+ }
+ default:
+ // Anything else is an error.
+ return nil, errors.New("Invalid diff operation in DiffFromDelta: " + string(token[0]))
+ }
+ }
+
+ if i != len(runes) {
+ return nil, fmt.Errorf("Delta length (%v) is different from source text length (%v)", i, len(text1))
+ }
+
+ return diffs, nil
+}
+
+// diffLinesToStrings splits two texts into a list of strings. Each string represents one line.
+func (dmp *DiffMatchPatch) diffLinesToStrings(text1, text2 string) (string, string, []string) {
+ // '\x00' is a valid character, but various debuggers don't like it. So we'll insert a junk entry to avoid generating a null character.
+ lineArray := []string{""} // e.g. lineArray[4] == 'Hello\n'
+
+ lineHash := make(map[string]int)
+ //Each string has the index of lineArray which it points to
+ strIndexArray1 := dmp.diffLinesToStringsMunge(text1, &lineArray, lineHash)
+ strIndexArray2 := dmp.diffLinesToStringsMunge(text2, &lineArray, lineHash)
+
+ return intArrayToString(strIndexArray1), intArrayToString(strIndexArray2), lineArray
+}
+
+// diffLinesToStringsMunge splits a text into an array of strings, and reduces the texts to a []string.
+func (dmp *DiffMatchPatch) diffLinesToStringsMunge(text string, lineArray *[]string, lineHash map[string]int) []uint32 {
+ // Walk the text, pulling out a substring for each line. text.split('\n') would would temporarily double our memory footprint. Modifying text would create many large strings to garbage collect.
+ lineStart := 0
+ lineEnd := -1
+ strs := []uint32{}
+
+ for lineEnd < len(text)-1 {
+ lineEnd = indexOf(text, "\n", lineStart)
+
+ if lineEnd == -1 {
+ lineEnd = len(text) - 1
+ }
+
+ line := text[lineStart : lineEnd+1]
+ lineStart = lineEnd + 1
+ lineValue, ok := lineHash[line]
+
+ if ok {
+ strs = append(strs, uint32(lineValue))
+ } else {
+ *lineArray = append(*lineArray, line)
+ lineHash[line] = len(*lineArray) - 1
+ strs = append(strs, uint32(len(*lineArray)-1))
+ }
+ }
+
+ return strs
+}
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/diffmatchpatch.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/diffmatchpatch.go
new file mode 100644
index 00000000..d3acc32c
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/diffmatchpatch.go
@@ -0,0 +1,46 @@
+// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
+// https://github.com/sergi/go-diff
+// See the included LICENSE file for license details.
+//
+// go-diff is a Go implementation of Google's Diff, Match, and Patch library
+// Original library is Copyright (c) 2006 Google Inc.
+// http://code.google.com/p/google-diff-match-patch/
+
+// Package diffmatchpatch offers robust algorithms to perform the operations required for synchronizing plain text.
+package diffmatchpatch
+
+import (
+ "time"
+)
+
+// DiffMatchPatch holds the configuration for diff-match-patch operations.
+type DiffMatchPatch struct {
+ // Number of seconds to map a diff before giving up (0 for infinity).
+ DiffTimeout time.Duration
+ // Cost of an empty edit operation in terms of edit characters.
+ DiffEditCost int
+ // How far to search for a match (0 = exact location, 1000+ = broad match). A match this many characters away from the expected location will add 1.0 to the score (0.0 is a perfect match).
+ MatchDistance int
+ // When deleting a large block of text (over ~64 characters), how close do the contents have to be to match the expected contents. (0.0 = perfection, 1.0 = very loose). Note that MatchThreshold controls how closely the end points of a delete need to match.
+ PatchDeleteThreshold float64
+ // Chunk size for context length.
+ PatchMargin int
+ // The number of bits in an int.
+ MatchMaxBits int
+ // At what point is no match declared (0.0 = perfection, 1.0 = very loose).
+ MatchThreshold float64
+}
+
+// New creates a new DiffMatchPatch object with default parameters.
+func New() *DiffMatchPatch {
+ // Defaults.
+ return &DiffMatchPatch{
+ DiffTimeout: time.Second,
+ DiffEditCost: 4,
+ MatchThreshold: 0.5,
+ MatchDistance: 1000,
+ PatchDeleteThreshold: 0.5,
+ PatchMargin: 4,
+ MatchMaxBits: 32,
+ }
+}
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/match.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/match.go
new file mode 100644
index 00000000..17374e10
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/match.go
@@ -0,0 +1,160 @@
+// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
+// https://github.com/sergi/go-diff
+// See the included LICENSE file for license details.
+//
+// go-diff is a Go implementation of Google's Diff, Match, and Patch library
+// Original library is Copyright (c) 2006 Google Inc.
+// http://code.google.com/p/google-diff-match-patch/
+
+package diffmatchpatch
+
+import (
+ "math"
+)
+
+// MatchMain locates the best instance of 'pattern' in 'text' near 'loc'.
+// Returns -1 if no match found.
+func (dmp *DiffMatchPatch) MatchMain(text, pattern string, loc int) int {
+ // Check for null inputs not needed since null can't be passed in C#.
+
+ loc = int(math.Max(0, math.Min(float64(loc), float64(len(text)))))
+ if text == pattern {
+ // Shortcut (potentially not guaranteed by the algorithm)
+ return 0
+ } else if len(text) == 0 {
+ // Nothing to match.
+ return -1
+ } else if loc+len(pattern) <= len(text) && text[loc:loc+len(pattern)] == pattern {
+ // Perfect match at the perfect spot! (Includes case of null pattern)
+ return loc
+ }
+ // Do a fuzzy compare.
+ return dmp.MatchBitap(text, pattern, loc)
+}
+
+// MatchBitap locates the best instance of 'pattern' in 'text' near 'loc' using the Bitap algorithm.
+// Returns -1 if no match was found.
+func (dmp *DiffMatchPatch) MatchBitap(text, pattern string, loc int) int {
+ // Initialise the alphabet.
+ s := dmp.MatchAlphabet(pattern)
+
+ // Highest score beyond which we give up.
+ scoreThreshold := dmp.MatchThreshold
+ // Is there a nearby exact match? (speedup)
+ bestLoc := indexOf(text, pattern, loc)
+ if bestLoc != -1 {
+ scoreThreshold = math.Min(dmp.matchBitapScore(0, bestLoc, loc,
+ pattern), scoreThreshold)
+ // What about in the other direction? (speedup)
+ bestLoc = lastIndexOf(text, pattern, loc+len(pattern))
+ if bestLoc != -1 {
+ scoreThreshold = math.Min(dmp.matchBitapScore(0, bestLoc, loc,
+ pattern), scoreThreshold)
+ }
+ }
+
+ // Initialise the bit arrays.
+ matchmask := 1 << uint((len(pattern) - 1))
+ bestLoc = -1
+
+ var binMin, binMid int
+ binMax := len(pattern) + len(text)
+ lastRd := []int{}
+ for d := 0; d < len(pattern); d++ {
+ // Scan for the best match; each iteration allows for one more error. Run a binary search to determine how far from 'loc' we can stray at this error level.
+ binMin = 0
+ binMid = binMax
+ for binMin < binMid {
+ if dmp.matchBitapScore(d, loc+binMid, loc, pattern) <= scoreThreshold {
+ binMin = binMid
+ } else {
+ binMax = binMid
+ }
+ binMid = (binMax-binMin)/2 + binMin
+ }
+ // Use the result from this iteration as the maximum for the next.
+ binMax = binMid
+ start := int(math.Max(1, float64(loc-binMid+1)))
+ finish := int(math.Min(float64(loc+binMid), float64(len(text))) + float64(len(pattern)))
+
+ rd := make([]int, finish+2)
+ rd[finish+1] = (1 << uint(d)) - 1
+
+ for j := finish; j >= start; j-- {
+ var charMatch int
+ if len(text) <= j-1 {
+ // Out of range.
+ charMatch = 0
+ } else if _, ok := s[text[j-1]]; !ok {
+ charMatch = 0
+ } else {
+ charMatch = s[text[j-1]]
+ }
+
+ if d == 0 {
+ // First pass: exact match.
+ rd[j] = ((rd[j+1] << 1) | 1) & charMatch
+ } else {
+ // Subsequent passes: fuzzy match.
+ rd[j] = ((rd[j+1]<<1)|1)&charMatch | (((lastRd[j+1] | lastRd[j]) << 1) | 1) | lastRd[j+1]
+ }
+ if (rd[j] & matchmask) != 0 {
+ score := dmp.matchBitapScore(d, j-1, loc, pattern)
+ // This match will almost certainly be better than any existing match. But check anyway.
+ if score <= scoreThreshold {
+ // Told you so.
+ scoreThreshold = score
+ bestLoc = j - 1
+ if bestLoc > loc {
+ // When passing loc, don't exceed our current distance from loc.
+ start = int(math.Max(1, float64(2*loc-bestLoc)))
+ } else {
+ // Already passed loc, downhill from here on in.
+ break
+ }
+ }
+ }
+ }
+ if dmp.matchBitapScore(d+1, loc, loc, pattern) > scoreThreshold {
+ // No hope for a (better) match at greater error levels.
+ break
+ }
+ lastRd = rd
+ }
+ return bestLoc
+}
+
+// matchBitapScore computes and returns the score for a match with e errors and x location.
+func (dmp *DiffMatchPatch) matchBitapScore(e, x, loc int, pattern string) float64 {
+ accuracy := float64(e) / float64(len(pattern))
+ proximity := math.Abs(float64(loc - x))
+ if dmp.MatchDistance == 0 {
+ // Dodge divide by zero error.
+ if proximity == 0 {
+ return accuracy
+ }
+
+ return 1.0
+ }
+ return accuracy + (proximity / float64(dmp.MatchDistance))
+}
+
+// MatchAlphabet initialises the alphabet for the Bitap algorithm.
+func (dmp *DiffMatchPatch) MatchAlphabet(pattern string) map[byte]int {
+ s := map[byte]int{}
+ charPattern := []byte(pattern)
+ for _, c := range charPattern {
+ _, ok := s[c]
+ if !ok {
+ s[c] = 0
+ }
+ }
+ i := 0
+
+ for _, c := range charPattern {
+ value := s[c] | int(uint(1)< y {
+ return x
+ }
+ return y
+}
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/operation_string.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/operation_string.go
new file mode 100644
index 00000000..533ec0da
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/operation_string.go
@@ -0,0 +1,17 @@
+// Code generated by "stringer -type=Operation -trimprefix=Diff"; DO NOT EDIT.
+
+package diffmatchpatch
+
+import "fmt"
+
+const _Operation_name = "DeleteEqualInsert"
+
+var _Operation_index = [...]uint8{0, 6, 11, 17}
+
+func (i Operation) String() string {
+ i -= -1
+ if i < 0 || i >= Operation(len(_Operation_index)-1) {
+ return fmt.Sprintf("Operation(%d)", i+-1)
+ }
+ return _Operation_name[_Operation_index[i]:_Operation_index[i+1]]
+}
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/patch.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/patch.go
new file mode 100644
index 00000000..0dbe3bdd
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/patch.go
@@ -0,0 +1,556 @@
+// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
+// https://github.com/sergi/go-diff
+// See the included LICENSE file for license details.
+//
+// go-diff is a Go implementation of Google's Diff, Match, and Patch library
+// Original library is Copyright (c) 2006 Google Inc.
+// http://code.google.com/p/google-diff-match-patch/
+
+package diffmatchpatch
+
+import (
+ "bytes"
+ "errors"
+ "math"
+ "net/url"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+// Patch represents one patch operation.
+type Patch struct {
+ diffs []Diff
+ Start1 int
+ Start2 int
+ Length1 int
+ Length2 int
+}
+
+// String emulates GNU diff's format.
+// Header: @@ -382,8 +481,9 @@
+// Indices are printed as 1-based, not 0-based.
+func (p *Patch) String() string {
+ var coords1, coords2 string
+
+ if p.Length1 == 0 {
+ coords1 = strconv.Itoa(p.Start1) + ",0"
+ } else if p.Length1 == 1 {
+ coords1 = strconv.Itoa(p.Start1 + 1)
+ } else {
+ coords1 = strconv.Itoa(p.Start1+1) + "," + strconv.Itoa(p.Length1)
+ }
+
+ if p.Length2 == 0 {
+ coords2 = strconv.Itoa(p.Start2) + ",0"
+ } else if p.Length2 == 1 {
+ coords2 = strconv.Itoa(p.Start2 + 1)
+ } else {
+ coords2 = strconv.Itoa(p.Start2+1) + "," + strconv.Itoa(p.Length2)
+ }
+
+ var text bytes.Buffer
+ _, _ = text.WriteString("@@ -" + coords1 + " +" + coords2 + " @@\n")
+
+ // Escape the body of the patch with %xx notation.
+ for _, aDiff := range p.diffs {
+ switch aDiff.Type {
+ case DiffInsert:
+ _, _ = text.WriteString("+")
+ case DiffDelete:
+ _, _ = text.WriteString("-")
+ case DiffEqual:
+ _, _ = text.WriteString(" ")
+ }
+
+ _, _ = text.WriteString(strings.Replace(url.QueryEscape(aDiff.Text), "+", " ", -1))
+ _, _ = text.WriteString("\n")
+ }
+
+ return unescaper.Replace(text.String())
+}
+
+// PatchAddContext increases the context until it is unique, but doesn't let the pattern expand beyond MatchMaxBits.
+func (dmp *DiffMatchPatch) PatchAddContext(patch Patch, text string) Patch {
+ if len(text) == 0 {
+ return patch
+ }
+
+ pattern := text[patch.Start2 : patch.Start2+patch.Length1]
+ padding := 0
+
+ // Look for the first and last matches of pattern in text. If two different matches are found, increase the pattern length.
+ for strings.Index(text, pattern) != strings.LastIndex(text, pattern) &&
+ len(pattern) < dmp.MatchMaxBits-2*dmp.PatchMargin {
+ padding += dmp.PatchMargin
+ maxStart := max(0, patch.Start2-padding)
+ minEnd := min(len(text), patch.Start2+patch.Length1+padding)
+ pattern = text[maxStart:minEnd]
+ }
+ // Add one chunk for good luck.
+ padding += dmp.PatchMargin
+
+ // Add the prefix.
+ prefix := text[max(0, patch.Start2-padding):patch.Start2]
+ if len(prefix) != 0 {
+ patch.diffs = append([]Diff{Diff{DiffEqual, prefix}}, patch.diffs...)
+ }
+ // Add the suffix.
+ suffix := text[patch.Start2+patch.Length1 : min(len(text), patch.Start2+patch.Length1+padding)]
+ if len(suffix) != 0 {
+ patch.diffs = append(patch.diffs, Diff{DiffEqual, suffix})
+ }
+
+ // Roll back the start points.
+ patch.Start1 -= len(prefix)
+ patch.Start2 -= len(prefix)
+ // Extend the lengths.
+ patch.Length1 += len(prefix) + len(suffix)
+ patch.Length2 += len(prefix) + len(suffix)
+
+ return patch
+}
+
+// PatchMake computes a list of patches.
+func (dmp *DiffMatchPatch) PatchMake(opt ...interface{}) []Patch {
+ if len(opt) == 1 {
+ diffs, _ := opt[0].([]Diff)
+ text1 := dmp.DiffText1(diffs)
+ return dmp.PatchMake(text1, diffs)
+ } else if len(opt) == 2 {
+ text1 := opt[0].(string)
+ switch t := opt[1].(type) {
+ case string:
+ diffs := dmp.DiffMain(text1, t, true)
+ if len(diffs) > 2 {
+ diffs = dmp.DiffCleanupSemantic(diffs)
+ diffs = dmp.DiffCleanupEfficiency(diffs)
+ }
+ return dmp.PatchMake(text1, diffs)
+ case []Diff:
+ return dmp.patchMake2(text1, t)
+ }
+ } else if len(opt) == 3 {
+ return dmp.PatchMake(opt[0], opt[2])
+ }
+ return []Patch{}
+}
+
+// patchMake2 computes a list of patches to turn text1 into text2.
+// text2 is not provided, diffs are the delta between text1 and text2.
+func (dmp *DiffMatchPatch) patchMake2(text1 string, diffs []Diff) []Patch {
+ // Check for null inputs not needed since null can't be passed in C#.
+ patches := []Patch{}
+ if len(diffs) == 0 {
+ return patches // Get rid of the null case.
+ }
+
+ patch := Patch{}
+ charCount1 := 0 // Number of characters into the text1 string.
+ charCount2 := 0 // Number of characters into the text2 string.
+ // Start with text1 (prepatchText) and apply the diffs until we arrive at text2 (postpatchText). We recreate the patches one by one to determine context info.
+ prepatchText := text1
+ postpatchText := text1
+
+ for i, aDiff := range diffs {
+ if len(patch.diffs) == 0 && aDiff.Type != DiffEqual {
+ // A new patch starts here.
+ patch.Start1 = charCount1
+ patch.Start2 = charCount2
+ }
+
+ switch aDiff.Type {
+ case DiffInsert:
+ patch.diffs = append(patch.diffs, aDiff)
+ patch.Length2 += len(aDiff.Text)
+ postpatchText = postpatchText[:charCount2] +
+ aDiff.Text + postpatchText[charCount2:]
+ case DiffDelete:
+ patch.Length1 += len(aDiff.Text)
+ patch.diffs = append(patch.diffs, aDiff)
+ postpatchText = postpatchText[:charCount2] + postpatchText[charCount2+len(aDiff.Text):]
+ case DiffEqual:
+ if len(aDiff.Text) <= 2*dmp.PatchMargin &&
+ len(patch.diffs) != 0 && i != len(diffs)-1 {
+ // Small equality inside a patch.
+ patch.diffs = append(patch.diffs, aDiff)
+ patch.Length1 += len(aDiff.Text)
+ patch.Length2 += len(aDiff.Text)
+ }
+ if len(aDiff.Text) >= 2*dmp.PatchMargin {
+ // Time for a new patch.
+ if len(patch.diffs) != 0 {
+ patch = dmp.PatchAddContext(patch, prepatchText)
+ patches = append(patches, patch)
+ patch = Patch{}
+ // Unlike Unidiff, our patch lists have a rolling context. http://code.google.com/p/google-diff-match-patch/wiki/Unidiff Update prepatch text & pos to reflect the application of the just completed patch.
+ prepatchText = postpatchText
+ charCount1 = charCount2
+ }
+ }
+ }
+
+ // Update the current character count.
+ if aDiff.Type != DiffInsert {
+ charCount1 += len(aDiff.Text)
+ }
+ if aDiff.Type != DiffDelete {
+ charCount2 += len(aDiff.Text)
+ }
+ }
+
+ // Pick up the leftover patch if not empty.
+ if len(patch.diffs) != 0 {
+ patch = dmp.PatchAddContext(patch, prepatchText)
+ patches = append(patches, patch)
+ }
+
+ return patches
+}
+
+// PatchDeepCopy returns an array that is identical to a given an array of patches.
+func (dmp *DiffMatchPatch) PatchDeepCopy(patches []Patch) []Patch {
+ patchesCopy := []Patch{}
+ for _, aPatch := range patches {
+ patchCopy := Patch{}
+ for _, aDiff := range aPatch.diffs {
+ patchCopy.diffs = append(patchCopy.diffs, Diff{
+ aDiff.Type,
+ aDiff.Text,
+ })
+ }
+ patchCopy.Start1 = aPatch.Start1
+ patchCopy.Start2 = aPatch.Start2
+ patchCopy.Length1 = aPatch.Length1
+ patchCopy.Length2 = aPatch.Length2
+ patchesCopy = append(patchesCopy, patchCopy)
+ }
+ return patchesCopy
+}
+
+// PatchApply merges a set of patches onto the text. Returns a patched text, as well as an array of true/false values indicating which patches were applied.
+func (dmp *DiffMatchPatch) PatchApply(patches []Patch, text string) (string, []bool) {
+ if len(patches) == 0 {
+ return text, []bool{}
+ }
+
+ // Deep copy the patches so that no changes are made to originals.
+ patches = dmp.PatchDeepCopy(patches)
+
+ nullPadding := dmp.PatchAddPadding(patches)
+ text = nullPadding + text + nullPadding
+ patches = dmp.PatchSplitMax(patches)
+
+ x := 0
+ // delta keeps track of the offset between the expected and actual location of the previous patch. If there are patches expected at positions 10 and 20, but the first patch was found at 12, delta is 2 and the second patch has an effective expected position of 22.
+ delta := 0
+ results := make([]bool, len(patches))
+ for _, aPatch := range patches {
+ expectedLoc := aPatch.Start2 + delta
+ text1 := dmp.DiffText1(aPatch.diffs)
+ var startLoc int
+ endLoc := -1
+ if len(text1) > dmp.MatchMaxBits {
+ // PatchSplitMax will only provide an oversized pattern in the case of a monster delete.
+ startLoc = dmp.MatchMain(text, text1[:dmp.MatchMaxBits], expectedLoc)
+ if startLoc != -1 {
+ endLoc = dmp.MatchMain(text,
+ text1[len(text1)-dmp.MatchMaxBits:], expectedLoc+len(text1)-dmp.MatchMaxBits)
+ if endLoc == -1 || startLoc >= endLoc {
+ // Can't find valid trailing context. Drop this patch.
+ startLoc = -1
+ }
+ }
+ } else {
+ startLoc = dmp.MatchMain(text, text1, expectedLoc)
+ }
+ if startLoc == -1 {
+ // No match found. :(
+ results[x] = false
+ // Subtract the delta for this failed patch from subsequent patches.
+ delta -= aPatch.Length2 - aPatch.Length1
+ } else {
+ // Found a match. :)
+ results[x] = true
+ delta = startLoc - expectedLoc
+ var text2 string
+ if endLoc == -1 {
+ text2 = text[startLoc:int(math.Min(float64(startLoc+len(text1)), float64(len(text))))]
+ } else {
+ text2 = text[startLoc:int(math.Min(float64(endLoc+dmp.MatchMaxBits), float64(len(text))))]
+ }
+ if text1 == text2 {
+ // Perfect match, just shove the Replacement text in.
+ text = text[:startLoc] + dmp.DiffText2(aPatch.diffs) + text[startLoc+len(text1):]
+ } else {
+ // Imperfect match. Run a diff to get a framework of equivalent indices.
+ diffs := dmp.DiffMain(text1, text2, false)
+ if len(text1) > dmp.MatchMaxBits && float64(dmp.DiffLevenshtein(diffs))/float64(len(text1)) > dmp.PatchDeleteThreshold {
+ // The end points match, but the content is unacceptably bad.
+ results[x] = false
+ } else {
+ diffs = dmp.DiffCleanupSemanticLossless(diffs)
+ index1 := 0
+ for _, aDiff := range aPatch.diffs {
+ if aDiff.Type != DiffEqual {
+ index2 := dmp.DiffXIndex(diffs, index1)
+ if aDiff.Type == DiffInsert {
+ // Insertion
+ text = text[:startLoc+index2] + aDiff.Text + text[startLoc+index2:]
+ } else if aDiff.Type == DiffDelete {
+ // Deletion
+ startIndex := startLoc + index2
+ text = text[:startIndex] +
+ text[startIndex+dmp.DiffXIndex(diffs, index1+len(aDiff.Text))-index2:]
+ }
+ }
+ if aDiff.Type != DiffDelete {
+ index1 += len(aDiff.Text)
+ }
+ }
+ }
+ }
+ }
+ x++
+ }
+ // Strip the padding off.
+ text = text[len(nullPadding) : len(nullPadding)+(len(text)-2*len(nullPadding))]
+ return text, results
+}
+
+// PatchAddPadding adds some padding on text start and end so that edges can match something.
+// Intended to be called only from within patchApply.
+func (dmp *DiffMatchPatch) PatchAddPadding(patches []Patch) string {
+ paddingLength := dmp.PatchMargin
+ nullPadding := ""
+ for x := 1; x <= paddingLength; x++ {
+ nullPadding += string(rune(x))
+ }
+
+ // Bump all the patches forward.
+ for i := range patches {
+ patches[i].Start1 += paddingLength
+ patches[i].Start2 += paddingLength
+ }
+
+ // Add some padding on start of first diff.
+ if len(patches[0].diffs) == 0 || patches[0].diffs[0].Type != DiffEqual {
+ // Add nullPadding equality.
+ patches[0].diffs = append([]Diff{Diff{DiffEqual, nullPadding}}, patches[0].diffs...)
+ patches[0].Start1 -= paddingLength // Should be 0.
+ patches[0].Start2 -= paddingLength // Should be 0.
+ patches[0].Length1 += paddingLength
+ patches[0].Length2 += paddingLength
+ } else if paddingLength > len(patches[0].diffs[0].Text) {
+ // Grow first equality.
+ extraLength := paddingLength - len(patches[0].diffs[0].Text)
+ patches[0].diffs[0].Text = nullPadding[len(patches[0].diffs[0].Text):] + patches[0].diffs[0].Text
+ patches[0].Start1 -= extraLength
+ patches[0].Start2 -= extraLength
+ patches[0].Length1 += extraLength
+ patches[0].Length2 += extraLength
+ }
+
+ // Add some padding on end of last diff.
+ last := len(patches) - 1
+ if len(patches[last].diffs) == 0 || patches[last].diffs[len(patches[last].diffs)-1].Type != DiffEqual {
+ // Add nullPadding equality.
+ patches[last].diffs = append(patches[last].diffs, Diff{DiffEqual, nullPadding})
+ patches[last].Length1 += paddingLength
+ patches[last].Length2 += paddingLength
+ } else if paddingLength > len(patches[last].diffs[len(patches[last].diffs)-1].Text) {
+ // Grow last equality.
+ lastDiff := patches[last].diffs[len(patches[last].diffs)-1]
+ extraLength := paddingLength - len(lastDiff.Text)
+ patches[last].diffs[len(patches[last].diffs)-1].Text += nullPadding[:extraLength]
+ patches[last].Length1 += extraLength
+ patches[last].Length2 += extraLength
+ }
+
+ return nullPadding
+}
+
+// PatchSplitMax looks through the patches and breaks up any which are longer than the maximum limit of the match algorithm.
+// Intended to be called only from within patchApply.
+func (dmp *DiffMatchPatch) PatchSplitMax(patches []Patch) []Patch {
+ patchSize := dmp.MatchMaxBits
+ for x := 0; x < len(patches); x++ {
+ if patches[x].Length1 <= patchSize {
+ continue
+ }
+ bigpatch := patches[x]
+ // Remove the big old patch.
+ patches = append(patches[:x], patches[x+1:]...)
+ x--
+
+ Start1 := bigpatch.Start1
+ Start2 := bigpatch.Start2
+ precontext := ""
+ for len(bigpatch.diffs) != 0 {
+ // Create one of several smaller patches.
+ patch := Patch{}
+ empty := true
+ patch.Start1 = Start1 - len(precontext)
+ patch.Start2 = Start2 - len(precontext)
+ if len(precontext) != 0 {
+ patch.Length1 = len(precontext)
+ patch.Length2 = len(precontext)
+ patch.diffs = append(patch.diffs, Diff{DiffEqual, precontext})
+ }
+ for len(bigpatch.diffs) != 0 && patch.Length1 < patchSize-dmp.PatchMargin {
+ diffType := bigpatch.diffs[0].Type
+ diffText := bigpatch.diffs[0].Text
+ if diffType == DiffInsert {
+ // Insertions are harmless.
+ patch.Length2 += len(diffText)
+ Start2 += len(diffText)
+ patch.diffs = append(patch.diffs, bigpatch.diffs[0])
+ bigpatch.diffs = bigpatch.diffs[1:]
+ empty = false
+ } else if diffType == DiffDelete && len(patch.diffs) == 1 && patch.diffs[0].Type == DiffEqual && len(diffText) > 2*patchSize {
+ // This is a large deletion. Let it pass in one chunk.
+ patch.Length1 += len(diffText)
+ Start1 += len(diffText)
+ empty = false
+ patch.diffs = append(patch.diffs, Diff{diffType, diffText})
+ bigpatch.diffs = bigpatch.diffs[1:]
+ } else {
+ // Deletion or equality. Only take as much as we can stomach.
+ diffText = diffText[:min(len(diffText), patchSize-patch.Length1-dmp.PatchMargin)]
+
+ patch.Length1 += len(diffText)
+ Start1 += len(diffText)
+ if diffType == DiffEqual {
+ patch.Length2 += len(diffText)
+ Start2 += len(diffText)
+ } else {
+ empty = false
+ }
+ patch.diffs = append(patch.diffs, Diff{diffType, diffText})
+ if diffText == bigpatch.diffs[0].Text {
+ bigpatch.diffs = bigpatch.diffs[1:]
+ } else {
+ bigpatch.diffs[0].Text =
+ bigpatch.diffs[0].Text[len(diffText):]
+ }
+ }
+ }
+ // Compute the head context for the next patch.
+ precontext = dmp.DiffText2(patch.diffs)
+ precontext = precontext[max(0, len(precontext)-dmp.PatchMargin):]
+
+ postcontext := ""
+ // Append the end context for this patch.
+ if len(dmp.DiffText1(bigpatch.diffs)) > dmp.PatchMargin {
+ postcontext = dmp.DiffText1(bigpatch.diffs)[:dmp.PatchMargin]
+ } else {
+ postcontext = dmp.DiffText1(bigpatch.diffs)
+ }
+
+ if len(postcontext) != 0 {
+ patch.Length1 += len(postcontext)
+ patch.Length2 += len(postcontext)
+ if len(patch.diffs) != 0 && patch.diffs[len(patch.diffs)-1].Type == DiffEqual {
+ patch.diffs[len(patch.diffs)-1].Text += postcontext
+ } else {
+ patch.diffs = append(patch.diffs, Diff{DiffEqual, postcontext})
+ }
+ }
+ if !empty {
+ x++
+ patches = append(patches[:x], append([]Patch{patch}, patches[x:]...)...)
+ }
+ }
+ }
+ return patches
+}
+
+// PatchToText takes a list of patches and returns a textual representation.
+func (dmp *DiffMatchPatch) PatchToText(patches []Patch) string {
+ var text bytes.Buffer
+ for _, aPatch := range patches {
+ _, _ = text.WriteString(aPatch.String())
+ }
+ return text.String()
+}
+
+// PatchFromText parses a textual representation of patches and returns a List of Patch objects.
+func (dmp *DiffMatchPatch) PatchFromText(textline string) ([]Patch, error) {
+ patches := []Patch{}
+ if len(textline) == 0 {
+ return patches, nil
+ }
+ text := strings.Split(textline, "\n")
+ textPointer := 0
+ patchHeader := regexp.MustCompile("^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$")
+
+ var patch Patch
+ var sign uint8
+ var line string
+ for textPointer < len(text) {
+
+ if !patchHeader.MatchString(text[textPointer]) {
+ return patches, errors.New("Invalid patch string: " + text[textPointer])
+ }
+
+ patch = Patch{}
+ m := patchHeader.FindStringSubmatch(text[textPointer])
+
+ patch.Start1, _ = strconv.Atoi(m[1])
+ if len(m[2]) == 0 {
+ patch.Start1--
+ patch.Length1 = 1
+ } else if m[2] == "0" {
+ patch.Length1 = 0
+ } else {
+ patch.Start1--
+ patch.Length1, _ = strconv.Atoi(m[2])
+ }
+
+ patch.Start2, _ = strconv.Atoi(m[3])
+
+ if len(m[4]) == 0 {
+ patch.Start2--
+ patch.Length2 = 1
+ } else if m[4] == "0" {
+ patch.Length2 = 0
+ } else {
+ patch.Start2--
+ patch.Length2, _ = strconv.Atoi(m[4])
+ }
+ textPointer++
+
+ for textPointer < len(text) {
+ if len(text[textPointer]) > 0 {
+ sign = text[textPointer][0]
+ } else {
+ textPointer++
+ continue
+ }
+
+ line = text[textPointer][1:]
+ line = strings.Replace(line, "+", "%2b", -1)
+ line, _ = url.QueryUnescape(line)
+ if sign == '-' {
+ // Deletion.
+ patch.diffs = append(patch.diffs, Diff{DiffDelete, line})
+ } else if sign == '+' {
+ // Insertion.
+ patch.diffs = append(patch.diffs, Diff{DiffInsert, line})
+ } else if sign == ' ' {
+ // Minor equality.
+ patch.diffs = append(patch.diffs, Diff{DiffEqual, line})
+ } else if sign == '@' {
+ // Start of next patch.
+ break
+ } else {
+ // WTF?
+ return patches, errors.New("Invalid patch mode '" + string(sign) + "' in: " + string(line))
+ }
+ textPointer++
+ }
+
+ patches = append(patches, patch)
+ }
+ return patches, nil
+}
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go
new file mode 100644
index 00000000..eb727bb5
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go
@@ -0,0 +1,190 @@
+// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
+// https://github.com/sergi/go-diff
+// See the included LICENSE file for license details.
+//
+// go-diff is a Go implementation of Google's Diff, Match, and Patch library
+// Original library is Copyright (c) 2006 Google Inc.
+// http://code.google.com/p/google-diff-match-patch/
+
+package diffmatchpatch
+
+import (
+ "fmt"
+ "strings"
+ "unicode/utf8"
+)
+
+const UNICODE_INVALID_RANGE_START = 0xD800
+const UNICODE_INVALID_RANGE_END = 0xDFFF
+const UNICODE_INVALID_RANGE_DELTA = UNICODE_INVALID_RANGE_END - UNICODE_INVALID_RANGE_START + 1
+const UNICODE_RANGE_MAX = 0x10FFFF
+
+// unescaper unescapes selected chars for compatibility with JavaScript's encodeURI.
+// In speed critical applications this could be dropped since the receiving application will certainly decode these fine. Note that this function is case-sensitive. Thus "%3F" would not be unescaped. But this is ok because it is only called with the output of HttpUtility.UrlEncode which returns lowercase hex. Example: "%3f" -> "?", "%24" -> "$", etc.
+var unescaper = strings.NewReplacer(
+ "%21", "!", "%7E", "~", "%27", "'",
+ "%28", "(", "%29", ")", "%3B", ";",
+ "%2F", "/", "%3F", "?", "%3A", ":",
+ "%40", "@", "%26", "&", "%3D", "=",
+ "%2B", "+", "%24", "$", "%2C", ",", "%23", "#", "%2A", "*")
+
+// indexOf returns the first index of pattern in str, starting at str[i].
+func indexOf(str string, pattern string, i int) int {
+ if i > len(str)-1 {
+ return -1
+ }
+ if i <= 0 {
+ return strings.Index(str, pattern)
+ }
+ ind := strings.Index(str[i:], pattern)
+ if ind == -1 {
+ return -1
+ }
+ return ind + i
+}
+
+// lastIndexOf returns the last index of pattern in str, starting at str[i].
+func lastIndexOf(str string, pattern string, i int) int {
+ if i < 0 {
+ return -1
+ }
+ if i >= len(str) {
+ return strings.LastIndex(str, pattern)
+ }
+ _, size := utf8.DecodeRuneInString(str[i:])
+ return strings.LastIndex(str[:i+size], pattern)
+}
+
+// runesIndexOf returns the index of pattern in target, starting at target[i].
+func runesIndexOf(target, pattern []rune, i int) int {
+ if i > len(target)-1 {
+ return -1
+ }
+ if i <= 0 {
+ return runesIndex(target, pattern)
+ }
+ ind := runesIndex(target[i:], pattern)
+ if ind == -1 {
+ return -1
+ }
+ return ind + i
+}
+
+func runesEqual(r1, r2 []rune) bool {
+ if len(r1) != len(r2) {
+ return false
+ }
+ for i, c := range r1 {
+ if c != r2[i] {
+ return false
+ }
+ }
+ return true
+}
+
+// runesIndex is the equivalent of strings.Index for rune slices.
+func runesIndex(r1, r2 []rune) int {
+ last := len(r1) - len(r2)
+ for i := 0; i <= last; i++ {
+ if runesEqual(r1[i:i+len(r2)], r2) {
+ return i
+ }
+ }
+ return -1
+}
+
+func intArrayToString(ns []uint32) string {
+ if len(ns) == 0 {
+ return ""
+ }
+
+ b := []rune{}
+ for _, n := range ns {
+ b = append(b, intToRune(n))
+ }
+ return string(b)
+}
+
+// These constants define the number of bits representable
+// in 1,2,3,4 byte utf8 sequences, respectively.
+const ONE_BYTE_BITS = 7
+const TWO_BYTE_BITS = 11
+const THREE_BYTE_BITS = 16
+const FOUR_BYTE_BITS = 21
+
+// Helper for getting a sequence of bits from an integer.
+func getBits(i uint32, cnt byte, from byte) byte {
+ return byte((i >> from) & ((1 << cnt) - 1))
+}
+
+// Converts an integer in the range 0~1112060 into a rune.
+// Based on the ranges table in https://en.wikipedia.org/wiki/UTF-8
+func intToRune(i uint32) rune {
+ if i < (1 << ONE_BYTE_BITS) {
+ return rune(i)
+ }
+
+ if i < (1 << TWO_BYTE_BITS) {
+ r, size := utf8.DecodeRune([]byte{0b11000000 | getBits(i, 5, 6), 0b10000000 | getBits(i, 6, 0)})
+ if size != 2 || r == utf8.RuneError {
+ panic(fmt.Sprintf("Error encoding an int %d with size 2, got rune %v and size %d", size, r, i))
+ }
+ return r
+ }
+
+ // Last -3 here needed because for some reason 3rd to last codepoint 65533 in this range
+ // was returning utf8.RuneError during encoding.
+ if i < ((1 << THREE_BYTE_BITS) - UNICODE_INVALID_RANGE_DELTA - 3) {
+ if i >= UNICODE_INVALID_RANGE_START {
+ i += UNICODE_INVALID_RANGE_DELTA
+ }
+
+ r, size := utf8.DecodeRune([]byte{0b11100000 | getBits(i, 4, 12), 0b10000000 | getBits(i, 6, 6), 0b10000000 | getBits(i, 6, 0)})
+ if size != 3 || r == utf8.RuneError {
+ panic(fmt.Sprintf("Error encoding an int %d with size 3, got rune %v and size %d", size, r, i))
+ }
+ return r
+ }
+
+ if i < (1<= UNICODE_INVALID_RANGE_END {
+ return result - UNICODE_INVALID_RANGE_DELTA
+ }
+
+ return result
+ }
+
+ if size == 4 {
+ result := uint32(bytes[0]&0b111)<<18 | uint32(bytes[1]&0b111111)<<12 | uint32(bytes[2]&0b111111)<<6 | uint32(bytes[3]&0b111111)
+ return result - UNICODE_INVALID_RANGE_DELTA - 3
+ }
+
+ panic(fmt.Sprintf("Unexpected state decoding rune=%v size=%d", r, size))
+}
diff --git a/vendor/github.com/skeema/knownhosts/LICENSE b/vendor/github.com/skeema/knownhosts/LICENSE
new file mode 100644
index 00000000..8dada3ed
--- /dev/null
+++ b/vendor/github.com/skeema/knownhosts/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ 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 "{}"
+ 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
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ 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.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/skeema/knownhosts/NOTICE b/vendor/github.com/skeema/knownhosts/NOTICE
new file mode 100644
index 00000000..a92cb34d
--- /dev/null
+++ b/vendor/github.com/skeema/knownhosts/NOTICE
@@ -0,0 +1,13 @@
+Copyright 2024 Skeema LLC and the Skeema Knownhosts 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.
diff --git a/vendor/github.com/skeema/knownhosts/README.md b/vendor/github.com/skeema/knownhosts/README.md
new file mode 100644
index 00000000..36b84761
--- /dev/null
+++ b/vendor/github.com/skeema/knownhosts/README.md
@@ -0,0 +1,117 @@
+# knownhosts: enhanced Golang SSH known_hosts management
+
+[![build status](https://img.shields.io/github/actions/workflow/status/skeema/knownhosts/tests.yml?branch=main)](https://github.com/skeema/knownhosts/actions)
+[![godoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/skeema/knownhosts)
+
+
+> This repo is brought to you by [Skeema](https://github.com/skeema/skeema), a
+> declarative pure-SQL schema management system for MySQL and MariaDB. Our
+> premium products include extensive [SSH tunnel](https://www.skeema.io/docs/options/#ssh)
+> functionality, which internally makes use of this package.
+
+Go provides excellent functionality for OpenSSH known_hosts files in its
+external package [golang.org/x/crypto/ssh/knownhosts](https://pkg.go.dev/golang.org/x/crypto/ssh/knownhosts).
+However, that package is somewhat low-level, making it difficult to implement full known_hosts management similar to command-line `ssh`'s behavior for `StrictHostKeyChecking=no` configuration.
+
+This repo ([github.com/skeema/knownhosts](https://github.com/skeema/knownhosts)) is a thin wrapper package around [golang.org/x/crypto/ssh/knownhosts](https://pkg.go.dev/golang.org/x/crypto/ssh/knownhosts), adding the following functionality:
+
+* Look up known_hosts public keys for any given host
+* Auto-populate ssh.ClientConfig.HostKeyAlgorithms easily based on known_hosts, providing a solution for [golang/go#29286](https://github.com/golang/go/issues/29286)
+* Write new known_hosts entries to an io.Writer
+* Properly format/normalize new known_hosts entries containing ipv6 addresses, providing a solution for [golang/go#53463](https://github.com/golang/go/issues/53463)
+* Determine if an ssh.HostKeyCallback's error corresponds to a host whose key has changed (indicating potential MitM attack) vs a host that just isn't known yet
+
+## How host key lookup works
+
+Although [golang.org/x/crypto/ssh/knownhosts](https://pkg.go.dev/golang.org/x/crypto/ssh/knownhosts) doesn't directly expose a way to query its known_host map, we use a subtle trick to do so: invoke the HostKeyCallback with a valid host but a bogus key. The resulting KeyError allows us to determine which public keys are actually present for that host.
+
+By using this technique, [github.com/skeema/knownhosts](https://github.com/skeema/knownhosts) doesn't need to duplicate or re-implement any of the actual known_hosts management from [golang.org/x/crypto/ssh/knownhosts](https://pkg.go.dev/golang.org/x/crypto/ssh/knownhosts).
+
+## Populating ssh.ClientConfig.HostKeyAlgorithms based on known_hosts
+
+Hosts often have multiple public keys, each of a different type (algorithm). This can be [problematic](https://github.com/golang/go/issues/29286) in [golang.org/x/crypto/ssh/knownhosts](https://pkg.go.dev/golang.org/x/crypto/ssh/knownhosts): if a host's first public key is *not* in known_hosts, but a key of a different type *is*, the HostKeyCallback returns an error. The solution is to populate `ssh.ClientConfig.HostKeyAlgorithms` based on the algorithms of the known_hosts entries for that host, but
+[golang.org/x/crypto/ssh/knownhosts](https://pkg.go.dev/golang.org/x/crypto/ssh/knownhosts)
+does not provide an obvious way to do so.
+
+This package uses its host key lookup trick in order to make ssh.ClientConfig.HostKeyAlgorithms easy to populate:
+
+```golang
+import (
+ "golang.org/x/crypto/ssh"
+ "github.com/skeema/knownhosts"
+)
+
+func sshConfigForHost(hostWithPort string) (*ssh.ClientConfig, error) {
+ kh, err := knownhosts.New("/home/myuser/.ssh/known_hosts")
+ if err != nil {
+ return nil, err
+ }
+ config := &ssh.ClientConfig{
+ User: "myuser",
+ Auth: []ssh.AuthMethod{ /* ... */ },
+ HostKeyCallback: kh.HostKeyCallback(), // or, equivalently, use ssh.HostKeyCallback(kh)
+ HostKeyAlgorithms: kh.HostKeyAlgorithms(hostWithPort),
+ }
+ return config, nil
+}
+```
+
+## Writing new known_hosts entries
+
+If you wish to mimic the behavior of OpenSSH's `StrictHostKeyChecking=no` or `StrictHostKeyChecking=ask`, this package provides a few functions to simplify this task. For example:
+
+```golang
+sshHost := "yourserver.com:22"
+khPath := "/home/myuser/.ssh/known_hosts"
+kh, err := knownhosts.New(khPath)
+if err != nil {
+ log.Fatal("Failed to read known_hosts: ", err)
+}
+
+// Create a custom permissive hostkey callback which still errors on hosts
+// with changed keys, but allows unknown hosts and adds them to known_hosts
+cb := ssh.HostKeyCallback(func(hostname string, remote net.Addr, key ssh.PublicKey) error {
+ err := kh(hostname, remote, key)
+ if knownhosts.IsHostKeyChanged(err) {
+ return fmt.Errorf("REMOTE HOST IDENTIFICATION HAS CHANGED for host %s! This may indicate a MitM attack.", hostname)
+ } else if knownhosts.IsHostUnknown(err) {
+ f, ferr := os.OpenFile(khPath, os.O_APPEND|os.O_WRONLY, 0600)
+ if ferr == nil {
+ defer f.Close()
+ ferr = knownhosts.WriteKnownHost(f, hostname, remote, key)
+ }
+ if ferr == nil {
+ log.Printf("Added host %s to known_hosts\n", hostname)
+ } else {
+ log.Printf("Failed to add host %s to known_hosts: %v\n", hostname, ferr)
+ }
+ return nil // permit previously-unknown hosts (warning: may be insecure)
+ }
+ return err
+})
+
+config := &ssh.ClientConfig{
+ User: "myuser",
+ Auth: []ssh.AuthMethod{ /* ... */ },
+ HostKeyCallback: cb,
+ HostKeyAlgorithms: kh.HostKeyAlgorithms(sshHost),
+}
+```
+
+## License
+
+**Source code copyright 2024 Skeema LLC and the Skeema Knownhosts authors**
+
+```text
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+```
diff --git a/vendor/github.com/skeema/knownhosts/knownhosts.go b/vendor/github.com/skeema/knownhosts/knownhosts.go
new file mode 100644
index 00000000..4dad7771
--- /dev/null
+++ b/vendor/github.com/skeema/knownhosts/knownhosts.go
@@ -0,0 +1,192 @@
+// Package knownhosts is a thin wrapper around golang.org/x/crypto/ssh/knownhosts,
+// adding the ability to obtain the list of host key algorithms for a known host.
+package knownhosts
+
+import (
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "sort"
+ "strings"
+
+ "golang.org/x/crypto/ssh"
+ xknownhosts "golang.org/x/crypto/ssh/knownhosts"
+)
+
+// HostKeyCallback wraps ssh.HostKeyCallback with an additional method to
+// perform host key algorithm lookups from the known_hosts entries.
+type HostKeyCallback ssh.HostKeyCallback
+
+// New creates a host key callback from the given OpenSSH host key files. The
+// returned value may be used in ssh.ClientConfig.HostKeyCallback by casting it
+// to ssh.HostKeyCallback, or using its HostKeyCallback method. Otherwise, it
+// operates the same as the New function in golang.org/x/crypto/ssh/knownhosts.
+func New(files ...string) (HostKeyCallback, error) {
+ cb, err := xknownhosts.New(files...)
+ return HostKeyCallback(cb), err
+}
+
+// HostKeyCallback simply casts the receiver back to ssh.HostKeyCallback, for
+// use in ssh.ClientConfig.HostKeyCallback.
+func (hkcb HostKeyCallback) HostKeyCallback() ssh.HostKeyCallback {
+ return ssh.HostKeyCallback(hkcb)
+}
+
+// HostKeys returns a slice of known host public keys for the supplied host:port
+// found in the known_hosts file(s), or an empty slice if the host is not
+// already known. For hosts that have multiple known_hosts entries (for
+// different key types), the result will be sorted by known_hosts filename and
+// line number.
+func (hkcb HostKeyCallback) HostKeys(hostWithPort string) (keys []ssh.PublicKey) {
+ var keyErr *xknownhosts.KeyError
+ placeholderAddr := &net.TCPAddr{IP: []byte{0, 0, 0, 0}}
+ placeholderPubKey := &fakePublicKey{}
+ var kkeys []xknownhosts.KnownKey
+ if hkcbErr := hkcb(hostWithPort, placeholderAddr, placeholderPubKey); errors.As(hkcbErr, &keyErr) {
+ kkeys = append(kkeys, keyErr.Want...)
+ knownKeyLess := func(i, j int) bool {
+ if kkeys[i].Filename < kkeys[j].Filename {
+ return true
+ }
+ return (kkeys[i].Filename == kkeys[j].Filename && kkeys[i].Line < kkeys[j].Line)
+ }
+ sort.Slice(kkeys, knownKeyLess)
+ keys = make([]ssh.PublicKey, len(kkeys))
+ for n := range kkeys {
+ keys[n] = kkeys[n].Key
+ }
+ }
+ return keys
+}
+
+// HostKeyAlgorithms returns a slice of host key algorithms for the supplied
+// host:port found in the known_hosts file(s), or an empty slice if the host
+// is not already known. The result may be used in ssh.ClientConfig's
+// HostKeyAlgorithms field, either as-is or after filtering (if you wish to
+// ignore or prefer particular algorithms). For hosts that have multiple
+// known_hosts entries (for different key types), the result will be sorted by
+// known_hosts filename and line number.
+func (hkcb HostKeyCallback) HostKeyAlgorithms(hostWithPort string) (algos []string) {
+ // We ensure that algos never contains duplicates. This is done for robustness
+ // even though currently golang.org/x/crypto/ssh/knownhosts never exposes
+ // multiple keys of the same type. This way our behavior here is unaffected
+ // even if https://github.com/golang/go/issues/28870 is implemented, for
+ // example by https://github.com/golang/crypto/pull/254.
+ hostKeys := hkcb.HostKeys(hostWithPort)
+ seen := make(map[string]struct{}, len(hostKeys))
+ addAlgo := func(typ string) {
+ if _, already := seen[typ]; !already {
+ algos = append(algos, typ)
+ seen[typ] = struct{}{}
+ }
+ }
+ for _, key := range hostKeys {
+ typ := key.Type()
+ if typ == ssh.KeyAlgoRSA {
+ // KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms,
+ // not public key formats, so they can't appear as a PublicKey.Type.
+ // The corresponding PublicKey.Type is KeyAlgoRSA. See RFC 8332, Section 2.
+ addAlgo(ssh.KeyAlgoRSASHA512)
+ addAlgo(ssh.KeyAlgoRSASHA256)
+ }
+ addAlgo(typ)
+ }
+ return algos
+}
+
+// HostKeyAlgorithms is a convenience function for performing host key algorithm
+// lookups on an ssh.HostKeyCallback directly. It is intended for use in code
+// paths that stay with the New method of golang.org/x/crypto/ssh/knownhosts
+// rather than this package's New method.
+func HostKeyAlgorithms(cb ssh.HostKeyCallback, hostWithPort string) []string {
+ return HostKeyCallback(cb).HostKeyAlgorithms(hostWithPort)
+}
+
+// IsHostKeyChanged returns a boolean indicating whether the error indicates
+// the host key has changed. It is intended to be called on the error returned
+// from invoking a HostKeyCallback to check whether an SSH host is known.
+func IsHostKeyChanged(err error) bool {
+ var keyErr *xknownhosts.KeyError
+ return errors.As(err, &keyErr) && len(keyErr.Want) > 0
+}
+
+// IsHostUnknown returns a boolean indicating whether the error represents an
+// unknown host. It is intended to be called on the error returned from invoking
+// a HostKeyCallback to check whether an SSH host is known.
+func IsHostUnknown(err error) bool {
+ var keyErr *xknownhosts.KeyError
+ return errors.As(err, &keyErr) && len(keyErr.Want) == 0
+}
+
+// Normalize normalizes an address into the form used in known_hosts. This
+// implementation includes a fix for https://github.com/golang/go/issues/53463
+// and will omit brackets around ipv6 addresses on standard port 22.
+func Normalize(address string) string {
+ host, port, err := net.SplitHostPort(address)
+ if err != nil {
+ host = address
+ port = "22"
+ }
+ entry := host
+ if port != "22" {
+ entry = "[" + entry + "]:" + port
+ } else if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
+ entry = entry[1 : len(entry)-1]
+ }
+ return entry
+}
+
+// Line returns a line to append to the known_hosts files. This implementation
+// uses the local patched implementation of Normalize in order to solve
+// https://github.com/golang/go/issues/53463.
+func Line(addresses []string, key ssh.PublicKey) string {
+ var trimmed []string
+ for _, a := range addresses {
+ trimmed = append(trimmed, Normalize(a))
+ }
+
+ return strings.Join([]string{
+ strings.Join(trimmed, ","),
+ key.Type(),
+ base64.StdEncoding.EncodeToString(key.Marshal()),
+ }, " ")
+}
+
+// WriteKnownHost writes a known_hosts line to writer for the supplied hostname,
+// remote, and key. This is useful when writing a custom hostkey callback which
+// wraps a callback obtained from knownhosts.New to provide additional
+// known_hosts management functionality. The hostname, remote, and key typically
+// correspond to the callback's args.
+func WriteKnownHost(w io.Writer, hostname string, remote net.Addr, key ssh.PublicKey) error {
+ // Always include hostname; only also include remote if it isn't a zero value
+ // and doesn't normalize to the same string as hostname.
+ hostnameNormalized := Normalize(hostname)
+ if strings.ContainsAny(hostnameNormalized, "\t ") {
+ return fmt.Errorf("knownhosts: hostname '%s' contains spaces", hostnameNormalized)
+ }
+ addresses := []string{hostnameNormalized}
+ remoteStrNormalized := Normalize(remote.String())
+ if remoteStrNormalized != "[0.0.0.0]:0" && remoteStrNormalized != hostnameNormalized &&
+ !strings.ContainsAny(remoteStrNormalized, "\t ") {
+ addresses = append(addresses, remoteStrNormalized)
+ }
+ line := Line(addresses, key) + "\n"
+ _, err := w.Write([]byte(line))
+ return err
+}
+
+// fakePublicKey is used as part of the work-around for
+// https://github.com/golang/go/issues/29286
+type fakePublicKey struct{}
+
+func (fakePublicKey) Type() string {
+ return "fake-public-key"
+}
+func (fakePublicKey) Marshal() []byte {
+ return []byte("fake public key")
+}
+func (fakePublicKey) Verify(_ []byte, _ *ssh.Signature) error {
+ return errors.New("Verify called on placeholder key")
+}
diff --git a/vendor/github.com/xanzy/ssh-agent/.gitignore b/vendor/github.com/xanzy/ssh-agent/.gitignore
new file mode 100644
index 00000000..daf913b1
--- /dev/null
+++ b/vendor/github.com/xanzy/ssh-agent/.gitignore
@@ -0,0 +1,24 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
diff --git a/vendor/github.com/xanzy/ssh-agent/LICENSE b/vendor/github.com/xanzy/ssh-agent/LICENSE
new file mode 100644
index 00000000..8f71f43f
--- /dev/null
+++ b/vendor/github.com/xanzy/ssh-agent/LICENSE
@@ -0,0 +1,202 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ 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 "{}"
+ 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
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ 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.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
diff --git a/vendor/github.com/xanzy/ssh-agent/README.md b/vendor/github.com/xanzy/ssh-agent/README.md
new file mode 100644
index 00000000..e2dfcedc
--- /dev/null
+++ b/vendor/github.com/xanzy/ssh-agent/README.md
@@ -0,0 +1,23 @@
+# ssh-agent
+
+Create a new [agent.Agent](https://godoc.org/golang.org/x/crypto/ssh/agent#Agent) on any type of OS (so including Windows) from any [Go](https://golang.org) application.
+
+## Limitations
+
+When compiled for Windows, it will only support [Pageant](http://the.earth.li/~sgtatham/putty/0.66/htmldoc/Chapter9.html#pageant) as the SSH authentication agent.
+
+## Credits
+
+Big thanks to [Давид Мзареулян (David Mzareulyan)](https://github.com/davidmz) for creating the [go-pageant](https://github.com/davidmz/go-pageant) package!
+
+## Issues
+
+If you have an issue: report it on the [issue tracker](https://github.com/xanzy/ssh-agent/issues)
+
+## Author
+
+Sander van Harmelen ()
+
+## License
+
+The files `pageant_windows.go` and `sshagent_windows.go` have their own license (see file headers). The rest of this package is 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
diff --git a/vendor/github.com/xanzy/ssh-agent/pageant_windows.go b/vendor/github.com/xanzy/ssh-agent/pageant_windows.go
new file mode 100644
index 00000000..1608e54c
--- /dev/null
+++ b/vendor/github.com/xanzy/ssh-agent/pageant_windows.go
@@ -0,0 +1,149 @@
+//
+// Copyright (c) 2014 David Mzareulyan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+// and associated documentation files (the "Software"), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge, publish, distribute,
+// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
+// is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+//go:build windows
+// +build windows
+
+package sshagent
+
+// see https://github.com/Yasushi/putty/blob/master/windows/winpgntc.c#L155
+// see https://github.com/paramiko/paramiko/blob/master/paramiko/win_pageant.py
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "sync"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+// Maximum size of message can be sent to pageant
+const MaxMessageLen = 8192
+
+var (
+ ErrPageantNotFound = errors.New("pageant process not found")
+ ErrSendMessage = errors.New("error sending message")
+
+ ErrMessageTooLong = errors.New("message too long")
+ ErrInvalidMessageFormat = errors.New("invalid message format")
+ ErrResponseTooLong = errors.New("response too long")
+)
+
+const (
+ agentCopydataID = 0x804e50ba
+ wmCopydata = 74
+)
+
+type copyData struct {
+ dwData uintptr
+ cbData uint32
+ lpData unsafe.Pointer
+}
+
+var (
+ lock sync.Mutex
+
+ user32dll = windows.NewLazySystemDLL("user32.dll")
+ winFindWindow = winAPI(user32dll, "FindWindowW")
+ winSendMessage = winAPI(user32dll, "SendMessageW")
+
+ kernel32dll = windows.NewLazySystemDLL("kernel32.dll")
+ winGetCurrentThreadID = winAPI(kernel32dll, "GetCurrentThreadId")
+)
+
+func winAPI(dll *windows.LazyDLL, funcName string) func(...uintptr) (uintptr, uintptr, error) {
+ proc := dll.NewProc(funcName)
+ return func(a ...uintptr) (uintptr, uintptr, error) { return proc.Call(a...) }
+}
+
+// Query sends message msg to Pageant and returns response or error.
+// 'msg' is raw agent request with length prefix
+// Response is raw agent response with length prefix
+func query(msg []byte) ([]byte, error) {
+ if len(msg) > MaxMessageLen {
+ return nil, ErrMessageTooLong
+ }
+
+ msgLen := binary.BigEndian.Uint32(msg[:4])
+ if len(msg) != int(msgLen)+4 {
+ return nil, ErrInvalidMessageFormat
+ }
+
+ lock.Lock()
+ defer lock.Unlock()
+
+ paWin := pageantWindow()
+
+ if paWin == 0 {
+ return nil, ErrPageantNotFound
+ }
+
+ thID, _, _ := winGetCurrentThreadID()
+ mapName := fmt.Sprintf("PageantRequest%08x", thID)
+ pMapName, _ := syscall.UTF16PtrFromString(mapName)
+
+ mmap, err := syscall.CreateFileMapping(syscall.InvalidHandle, nil, syscall.PAGE_READWRITE, 0, MaxMessageLen+4, pMapName)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CloseHandle(mmap)
+
+ ptr, err := syscall.MapViewOfFile(mmap, syscall.FILE_MAP_WRITE, 0, 0, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.UnmapViewOfFile(ptr)
+
+ mmSlice := (*(*[MaxMessageLen]byte)(unsafe.Pointer(ptr)))[:]
+
+ copy(mmSlice, msg)
+
+ mapNameBytesZ := append([]byte(mapName), 0)
+
+ cds := copyData{
+ dwData: agentCopydataID,
+ cbData: uint32(len(mapNameBytesZ)),
+ lpData: unsafe.Pointer(&(mapNameBytesZ[0])),
+ }
+
+ resp, _, _ := winSendMessage(paWin, wmCopydata, 0, uintptr(unsafe.Pointer(&cds)))
+
+ if resp == 0 {
+ return nil, ErrSendMessage
+ }
+
+ respLen := binary.BigEndian.Uint32(mmSlice[:4])
+ if respLen > MaxMessageLen-4 {
+ return nil, ErrResponseTooLong
+ }
+
+ respData := make([]byte, respLen+4)
+ copy(respData, mmSlice)
+
+ return respData, nil
+}
+
+func pageantWindow() uintptr {
+ nameP, _ := syscall.UTF16PtrFromString("Pageant")
+ h, _, _ := winFindWindow(uintptr(unsafe.Pointer(nameP)), uintptr(unsafe.Pointer(nameP)))
+ return h
+}
diff --git a/vendor/github.com/xanzy/ssh-agent/sshagent.go b/vendor/github.com/xanzy/ssh-agent/sshagent.go
new file mode 100644
index 00000000..4a4ee30c
--- /dev/null
+++ b/vendor/github.com/xanzy/ssh-agent/sshagent.go
@@ -0,0 +1,50 @@
+//
+// Copyright 2015, Sander van Harmelen
+//
+// 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 !windows
+// +build !windows
+
+package sshagent
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "os"
+
+ "golang.org/x/crypto/ssh/agent"
+)
+
+// New returns a new agent.Agent that uses a unix socket
+func New() (agent.Agent, net.Conn, error) {
+ if !Available() {
+ return nil, nil, errors.New("SSH agent requested but SSH_AUTH_SOCK not-specified")
+ }
+
+ sshAuthSock := os.Getenv("SSH_AUTH_SOCK")
+
+ conn, err := net.Dial("unix", sshAuthSock)
+ if err != nil {
+ return nil, nil, fmt.Errorf("Error connecting to SSH_AUTH_SOCK: %v", err)
+ }
+
+ return agent.NewClient(conn), conn, nil
+}
+
+// Available returns true is a auth socket is defined
+func Available() bool {
+ return os.Getenv("SSH_AUTH_SOCK") != ""
+}
diff --git a/vendor/github.com/xanzy/ssh-agent/sshagent_windows.go b/vendor/github.com/xanzy/ssh-agent/sshagent_windows.go
new file mode 100644
index 00000000..175d1619
--- /dev/null
+++ b/vendor/github.com/xanzy/ssh-agent/sshagent_windows.go
@@ -0,0 +1,104 @@
+//
+// Copyright (c) 2014 David Mzareulyan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+// and associated documentation files (the "Software"), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge, publish, distribute,
+// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
+// is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+//go:build windows
+// +build windows
+
+package sshagent
+
+import (
+ "errors"
+ "io"
+ "net"
+ "sync"
+
+ "github.com/Microsoft/go-winio"
+ "golang.org/x/crypto/ssh/agent"
+)
+
+const (
+ sshAgentPipe = `\\.\pipe\openssh-ssh-agent`
+)
+
+// Available returns true if Pageant is running
+func Available() bool {
+ if pageantWindow() != 0 {
+ return true
+ }
+ conn, err := winio.DialPipe(sshAgentPipe, nil)
+ if err != nil {
+ return false
+ }
+ conn.Close()
+ return true
+}
+
+// New returns a new agent.Agent and the (custom) connection it uses
+// to communicate with a running pagent.exe instance (see README.md)
+func New() (agent.Agent, net.Conn, error) {
+ if pageantWindow() != 0 {
+ return agent.NewClient(&conn{}), nil, nil
+ }
+ conn, err := winio.DialPipe(sshAgentPipe, nil)
+ if err != nil {
+ return nil, nil, errors.New(
+ "SSH agent requested, but could not detect Pageant or Windows native SSH agent",
+ )
+ }
+ return agent.NewClient(conn), nil, nil
+}
+
+type conn struct {
+ sync.Mutex
+ buf []byte
+}
+
+func (c *conn) Close() {
+ c.Lock()
+ defer c.Unlock()
+ c.buf = nil
+}
+
+func (c *conn) Write(p []byte) (int, error) {
+ c.Lock()
+ defer c.Unlock()
+
+ resp, err := query(p)
+ if err != nil {
+ return 0, err
+ }
+
+ c.buf = append(c.buf, resp...)
+
+ return len(p), nil
+}
+
+func (c *conn) Read(p []byte) (int, error) {
+ c.Lock()
+ defer c.Unlock()
+
+ if len(c.buf) == 0 {
+ return 0, io.EOF
+ }
+
+ n := copy(p, c.buf)
+ c.buf = c.buf[n:]
+
+ return n, nil
+}
diff --git a/vendor/golang.org/x/crypto/argon2/argon2.go b/vendor/golang.org/x/crypto/argon2/argon2.go
new file mode 100644
index 00000000..29f0a2de
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/argon2.go
@@ -0,0 +1,283 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package argon2 implements the key derivation function Argon2.
+// Argon2 was selected as the winner of the Password Hashing Competition and can
+// be used to derive cryptographic keys from passwords.
+//
+// For a detailed specification of Argon2 see [1].
+//
+// If you aren't sure which function you need, use Argon2id (IDKey) and
+// the parameter recommendations for your scenario.
+//
+// # Argon2i
+//
+// Argon2i (implemented by Key) is the side-channel resistant version of Argon2.
+// It uses data-independent memory access, which is preferred for password
+// hashing and password-based key derivation. Argon2i requires more passes over
+// memory than Argon2id to protect from trade-off attacks. The recommended
+// parameters (taken from [2]) for non-interactive operations are time=3 and to
+// use the maximum available memory.
+//
+// # Argon2id
+//
+// Argon2id (implemented by IDKey) is a hybrid version of Argon2 combining
+// Argon2i and Argon2d. It uses data-independent memory access for the first
+// half of the first iteration over the memory and data-dependent memory access
+// for the rest. Argon2id is side-channel resistant and provides better brute-
+// force cost savings due to time-memory tradeoffs than Argon2i. The recommended
+// parameters for non-interactive operations (taken from [2]) are time=1 and to
+// use the maximum available memory.
+//
+// [1] https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf
+// [2] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-03#section-9.3
+package argon2
+
+import (
+ "encoding/binary"
+ "sync"
+
+ "golang.org/x/crypto/blake2b"
+)
+
+// The Argon2 version implemented by this package.
+const Version = 0x13
+
+const (
+ argon2d = iota
+ argon2i
+ argon2id
+)
+
+// Key derives a key from the password, salt, and cost parameters using Argon2i
+// returning a byte slice of length keyLen that can be used as cryptographic
+// key. The CPU cost and parallelism degree must be greater than zero.
+//
+// For example, you can get a derived key for e.g. AES-256 (which needs a
+// 32-byte key) by doing:
+//
+// key := argon2.Key([]byte("some password"), salt, 3, 32*1024, 4, 32)
+//
+// The draft RFC recommends[2] time=3, and memory=32*1024 is a sensible number.
+// If using that amount of memory (32 MB) is not possible in some contexts then
+// the time parameter can be increased to compensate.
+//
+// The time parameter specifies the number of passes over the memory and the
+// memory parameter specifies the size of the memory in KiB. For example
+// memory=32*1024 sets the memory cost to ~32 MB. The number of threads can be
+// adjusted to the number of available CPUs. The cost parameters should be
+// increased as memory latency and CPU parallelism increases. Remember to get a
+// good random salt.
+func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
+ return deriveKey(argon2i, password, salt, nil, nil, time, memory, threads, keyLen)
+}
+
+// IDKey derives a key from the password, salt, and cost parameters using
+// Argon2id returning a byte slice of length keyLen that can be used as
+// cryptographic key. The CPU cost and parallelism degree must be greater than
+// zero.
+//
+// For example, you can get a derived key for e.g. AES-256 (which needs a
+// 32-byte key) by doing:
+//
+// key := argon2.IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32)
+//
+// The draft RFC recommends[2] time=1, and memory=64*1024 is a sensible number.
+// If using that amount of memory (64 MB) is not possible in some contexts then
+// the time parameter can be increased to compensate.
+//
+// The time parameter specifies the number of passes over the memory and the
+// memory parameter specifies the size of the memory in KiB. For example
+// memory=64*1024 sets the memory cost to ~64 MB. The number of threads can be
+// adjusted to the numbers of available CPUs. The cost parameters should be
+// increased as memory latency and CPU parallelism increases. Remember to get a
+// good random salt.
+func IDKey(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
+ return deriveKey(argon2id, password, salt, nil, nil, time, memory, threads, keyLen)
+}
+
+func deriveKey(mode int, password, salt, secret, data []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
+ if time < 1 {
+ panic("argon2: number of rounds too small")
+ }
+ if threads < 1 {
+ panic("argon2: parallelism degree too low")
+ }
+ h0 := initHash(password, salt, secret, data, time, memory, uint32(threads), keyLen, mode)
+
+ memory = memory / (syncPoints * uint32(threads)) * (syncPoints * uint32(threads))
+ if memory < 2*syncPoints*uint32(threads) {
+ memory = 2 * syncPoints * uint32(threads)
+ }
+ B := initBlocks(&h0, memory, uint32(threads))
+ processBlocks(B, time, memory, uint32(threads), mode)
+ return extractKey(B, memory, uint32(threads), keyLen)
+}
+
+const (
+ blockLength = 128
+ syncPoints = 4
+)
+
+type block [blockLength]uint64
+
+func initHash(password, salt, key, data []byte, time, memory, threads, keyLen uint32, mode int) [blake2b.Size + 8]byte {
+ var (
+ h0 [blake2b.Size + 8]byte
+ params [24]byte
+ tmp [4]byte
+ )
+
+ b2, _ := blake2b.New512(nil)
+ binary.LittleEndian.PutUint32(params[0:4], threads)
+ binary.LittleEndian.PutUint32(params[4:8], keyLen)
+ binary.LittleEndian.PutUint32(params[8:12], memory)
+ binary.LittleEndian.PutUint32(params[12:16], time)
+ binary.LittleEndian.PutUint32(params[16:20], uint32(Version))
+ binary.LittleEndian.PutUint32(params[20:24], uint32(mode))
+ b2.Write(params[:])
+ binary.LittleEndian.PutUint32(tmp[:], uint32(len(password)))
+ b2.Write(tmp[:])
+ b2.Write(password)
+ binary.LittleEndian.PutUint32(tmp[:], uint32(len(salt)))
+ b2.Write(tmp[:])
+ b2.Write(salt)
+ binary.LittleEndian.PutUint32(tmp[:], uint32(len(key)))
+ b2.Write(tmp[:])
+ b2.Write(key)
+ binary.LittleEndian.PutUint32(tmp[:], uint32(len(data)))
+ b2.Write(tmp[:])
+ b2.Write(data)
+ b2.Sum(h0[:0])
+ return h0
+}
+
+func initBlocks(h0 *[blake2b.Size + 8]byte, memory, threads uint32) []block {
+ var block0 [1024]byte
+ B := make([]block, memory)
+ for lane := uint32(0); lane < threads; lane++ {
+ j := lane * (memory / threads)
+ binary.LittleEndian.PutUint32(h0[blake2b.Size+4:], lane)
+
+ binary.LittleEndian.PutUint32(h0[blake2b.Size:], 0)
+ blake2bHash(block0[:], h0[:])
+ for i := range B[j+0] {
+ B[j+0][i] = binary.LittleEndian.Uint64(block0[i*8:])
+ }
+
+ binary.LittleEndian.PutUint32(h0[blake2b.Size:], 1)
+ blake2bHash(block0[:], h0[:])
+ for i := range B[j+1] {
+ B[j+1][i] = binary.LittleEndian.Uint64(block0[i*8:])
+ }
+ }
+ return B
+}
+
+func processBlocks(B []block, time, memory, threads uint32, mode int) {
+ lanes := memory / threads
+ segments := lanes / syncPoints
+
+ processSegment := func(n, slice, lane uint32, wg *sync.WaitGroup) {
+ var addresses, in, zero block
+ if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) {
+ in[0] = uint64(n)
+ in[1] = uint64(lane)
+ in[2] = uint64(slice)
+ in[3] = uint64(memory)
+ in[4] = uint64(time)
+ in[5] = uint64(mode)
+ }
+
+ index := uint32(0)
+ if n == 0 && slice == 0 {
+ index = 2 // we have already generated the first two blocks
+ if mode == argon2i || mode == argon2id {
+ in[6]++
+ processBlock(&addresses, &in, &zero)
+ processBlock(&addresses, &addresses, &zero)
+ }
+ }
+
+ offset := lane*lanes + slice*segments + index
+ var random uint64
+ for index < segments {
+ prev := offset - 1
+ if index == 0 && slice == 0 {
+ prev += lanes // last block in lane
+ }
+ if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) {
+ if index%blockLength == 0 {
+ in[6]++
+ processBlock(&addresses, &in, &zero)
+ processBlock(&addresses, &addresses, &zero)
+ }
+ random = addresses[index%blockLength]
+ } else {
+ random = B[prev][0]
+ }
+ newOffset := indexAlpha(random, lanes, segments, threads, n, slice, lane, index)
+ processBlockXOR(&B[offset], &B[prev], &B[newOffset])
+ index, offset = index+1, offset+1
+ }
+ wg.Done()
+ }
+
+ for n := uint32(0); n < time; n++ {
+ for slice := uint32(0); slice < syncPoints; slice++ {
+ var wg sync.WaitGroup
+ for lane := uint32(0); lane < threads; lane++ {
+ wg.Add(1)
+ go processSegment(n, slice, lane, &wg)
+ }
+ wg.Wait()
+ }
+ }
+
+}
+
+func extractKey(B []block, memory, threads, keyLen uint32) []byte {
+ lanes := memory / threads
+ for lane := uint32(0); lane < threads-1; lane++ {
+ for i, v := range B[(lane*lanes)+lanes-1] {
+ B[memory-1][i] ^= v
+ }
+ }
+
+ var block [1024]byte
+ for i, v := range B[memory-1] {
+ binary.LittleEndian.PutUint64(block[i*8:], v)
+ }
+ key := make([]byte, keyLen)
+ blake2bHash(key, block[:])
+ return key
+}
+
+func indexAlpha(rand uint64, lanes, segments, threads, n, slice, lane, index uint32) uint32 {
+ refLane := uint32(rand>>32) % threads
+ if n == 0 && slice == 0 {
+ refLane = lane
+ }
+ m, s := 3*segments, ((slice+1)%syncPoints)*segments
+ if lane == refLane {
+ m += index
+ }
+ if n == 0 {
+ m, s = slice*segments, 0
+ if slice == 0 || lane == refLane {
+ m += index
+ }
+ }
+ if index == 0 || lane == refLane {
+ m--
+ }
+ return phi(rand, uint64(m), uint64(s), refLane, lanes)
+}
+
+func phi(rand, m, s uint64, lane, lanes uint32) uint32 {
+ p := rand & 0xFFFFFFFF
+ p = (p * p) >> 32
+ p = (p * m) >> 32
+ return lane*lanes + uint32((s+m-(p+1))%uint64(lanes))
+}
diff --git a/vendor/golang.org/x/crypto/argon2/blake2b.go b/vendor/golang.org/x/crypto/argon2/blake2b.go
new file mode 100644
index 00000000..10f46948
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blake2b.go
@@ -0,0 +1,53 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package argon2
+
+import (
+ "encoding/binary"
+ "hash"
+
+ "golang.org/x/crypto/blake2b"
+)
+
+// blake2bHash computes an arbitrary long hash value of in
+// and writes the hash to out.
+func blake2bHash(out []byte, in []byte) {
+ var b2 hash.Hash
+ if n := len(out); n < blake2b.Size {
+ b2, _ = blake2b.New(n, nil)
+ } else {
+ b2, _ = blake2b.New512(nil)
+ }
+
+ var buffer [blake2b.Size]byte
+ binary.LittleEndian.PutUint32(buffer[:4], uint32(len(out)))
+ b2.Write(buffer[:4])
+ b2.Write(in)
+
+ if len(out) <= blake2b.Size {
+ b2.Sum(out[:0])
+ return
+ }
+
+ outLen := len(out)
+ b2.Sum(buffer[:0])
+ b2.Reset()
+ copy(out, buffer[:32])
+ out = out[32:]
+ for len(out) > blake2b.Size {
+ b2.Write(buffer[:])
+ b2.Sum(buffer[:0])
+ copy(out, buffer[:32])
+ out = out[32:]
+ b2.Reset()
+ }
+
+ if outLen%blake2b.Size > 0 { // outLen > 64
+ r := ((outLen + 31) / 32) - 2 // ⌈τ /32⌉-2
+ b2, _ = blake2b.New(outLen-32*r, nil)
+ }
+ b2.Write(buffer[:])
+ b2.Sum(out[:0])
+}
diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.go b/vendor/golang.org/x/crypto/argon2/blamka_amd64.go
new file mode 100644
index 00000000..063e7784
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.go
@@ -0,0 +1,60 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+
+package argon2
+
+import "golang.org/x/sys/cpu"
+
+func init() {
+ useSSE4 = cpu.X86.HasSSE41
+}
+
+//go:noescape
+func mixBlocksSSE2(out, a, b, c *block)
+
+//go:noescape
+func xorBlocksSSE2(out, a, b, c *block)
+
+//go:noescape
+func blamkaSSE4(b *block)
+
+func processBlockSSE(out, in1, in2 *block, xor bool) {
+ var t block
+ mixBlocksSSE2(&t, in1, in2, &t)
+ if useSSE4 {
+ blamkaSSE4(&t)
+ } else {
+ for i := 0; i < blockLength; i += 16 {
+ blamkaGeneric(
+ &t[i+0], &t[i+1], &t[i+2], &t[i+3],
+ &t[i+4], &t[i+5], &t[i+6], &t[i+7],
+ &t[i+8], &t[i+9], &t[i+10], &t[i+11],
+ &t[i+12], &t[i+13], &t[i+14], &t[i+15],
+ )
+ }
+ for i := 0; i < blockLength/8; i += 2 {
+ blamkaGeneric(
+ &t[i], &t[i+1], &t[16+i], &t[16+i+1],
+ &t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1],
+ &t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1],
+ &t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1],
+ )
+ }
+ }
+ if xor {
+ xorBlocksSSE2(out, in1, in2, &t)
+ } else {
+ mixBlocksSSE2(out, in1, in2, &t)
+ }
+}
+
+func processBlock(out, in1, in2 *block) {
+ processBlockSSE(out, in1, in2, false)
+}
+
+func processBlockXOR(out, in1, in2 *block) {
+ processBlockSSE(out, in1, in2, true)
+}
diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s
new file mode 100644
index 00000000..6713acca
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s
@@ -0,0 +1,243 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+
+#include "textflag.h"
+
+DATA ·c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·c40<>(SB), (NOPTR+RODATA), $16
+
+DATA ·c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·c48<>(SB), (NOPTR+RODATA), $16
+
+#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \
+ MOVO v4, t1; \
+ MOVO v5, v4; \
+ MOVO t1, v5; \
+ MOVO v6, t1; \
+ PUNPCKLQDQ v6, t2; \
+ PUNPCKHQDQ v7, v6; \
+ PUNPCKHQDQ t2, v6; \
+ PUNPCKLQDQ v7, t2; \
+ MOVO t1, v7; \
+ MOVO v2, t1; \
+ PUNPCKHQDQ t2, v7; \
+ PUNPCKLQDQ v3, t2; \
+ PUNPCKHQDQ t2, v2; \
+ PUNPCKLQDQ t1, t2; \
+ PUNPCKHQDQ t2, v3
+
+#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \
+ MOVO v4, t1; \
+ MOVO v5, v4; \
+ MOVO t1, v5; \
+ MOVO v2, t1; \
+ PUNPCKLQDQ v2, t2; \
+ PUNPCKHQDQ v3, v2; \
+ PUNPCKHQDQ t2, v2; \
+ PUNPCKLQDQ v3, t2; \
+ MOVO t1, v3; \
+ MOVO v6, t1; \
+ PUNPCKHQDQ t2, v3; \
+ PUNPCKLQDQ v7, t2; \
+ PUNPCKHQDQ t2, v6; \
+ PUNPCKLQDQ t1, t2; \
+ PUNPCKHQDQ t2, v7
+
+#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, t0, c40, c48) \
+ MOVO v0, t0; \
+ PMULULQ v2, t0; \
+ PADDQ v2, v0; \
+ PADDQ t0, v0; \
+ PADDQ t0, v0; \
+ PXOR v0, v6; \
+ PSHUFD $0xB1, v6, v6; \
+ MOVO v4, t0; \
+ PMULULQ v6, t0; \
+ PADDQ v6, v4; \
+ PADDQ t0, v4; \
+ PADDQ t0, v4; \
+ PXOR v4, v2; \
+ PSHUFB c40, v2; \
+ MOVO v0, t0; \
+ PMULULQ v2, t0; \
+ PADDQ v2, v0; \
+ PADDQ t0, v0; \
+ PADDQ t0, v0; \
+ PXOR v0, v6; \
+ PSHUFB c48, v6; \
+ MOVO v4, t0; \
+ PMULULQ v6, t0; \
+ PADDQ v6, v4; \
+ PADDQ t0, v4; \
+ PADDQ t0, v4; \
+ PXOR v4, v2; \
+ MOVO v2, t0; \
+ PADDQ v2, t0; \
+ PSRLQ $63, v2; \
+ PXOR t0, v2; \
+ MOVO v1, t0; \
+ PMULULQ v3, t0; \
+ PADDQ v3, v1; \
+ PADDQ t0, v1; \
+ PADDQ t0, v1; \
+ PXOR v1, v7; \
+ PSHUFD $0xB1, v7, v7; \
+ MOVO v5, t0; \
+ PMULULQ v7, t0; \
+ PADDQ v7, v5; \
+ PADDQ t0, v5; \
+ PADDQ t0, v5; \
+ PXOR v5, v3; \
+ PSHUFB c40, v3; \
+ MOVO v1, t0; \
+ PMULULQ v3, t0; \
+ PADDQ v3, v1; \
+ PADDQ t0, v1; \
+ PADDQ t0, v1; \
+ PXOR v1, v7; \
+ PSHUFB c48, v7; \
+ MOVO v5, t0; \
+ PMULULQ v7, t0; \
+ PADDQ v7, v5; \
+ PADDQ t0, v5; \
+ PADDQ t0, v5; \
+ PXOR v5, v3; \
+ MOVO v3, t0; \
+ PADDQ v3, t0; \
+ PSRLQ $63, v3; \
+ PXOR t0, v3
+
+#define LOAD_MSG_0(block, off) \
+ MOVOU 8*(off+0)(block), X0; \
+ MOVOU 8*(off+2)(block), X1; \
+ MOVOU 8*(off+4)(block), X2; \
+ MOVOU 8*(off+6)(block), X3; \
+ MOVOU 8*(off+8)(block), X4; \
+ MOVOU 8*(off+10)(block), X5; \
+ MOVOU 8*(off+12)(block), X6; \
+ MOVOU 8*(off+14)(block), X7
+
+#define STORE_MSG_0(block, off) \
+ MOVOU X0, 8*(off+0)(block); \
+ MOVOU X1, 8*(off+2)(block); \
+ MOVOU X2, 8*(off+4)(block); \
+ MOVOU X3, 8*(off+6)(block); \
+ MOVOU X4, 8*(off+8)(block); \
+ MOVOU X5, 8*(off+10)(block); \
+ MOVOU X6, 8*(off+12)(block); \
+ MOVOU X7, 8*(off+14)(block)
+
+#define LOAD_MSG_1(block, off) \
+ MOVOU 8*off+0*8(block), X0; \
+ MOVOU 8*off+16*8(block), X1; \
+ MOVOU 8*off+32*8(block), X2; \
+ MOVOU 8*off+48*8(block), X3; \
+ MOVOU 8*off+64*8(block), X4; \
+ MOVOU 8*off+80*8(block), X5; \
+ MOVOU 8*off+96*8(block), X6; \
+ MOVOU 8*off+112*8(block), X7
+
+#define STORE_MSG_1(block, off) \
+ MOVOU X0, 8*off+0*8(block); \
+ MOVOU X1, 8*off+16*8(block); \
+ MOVOU X2, 8*off+32*8(block); \
+ MOVOU X3, 8*off+48*8(block); \
+ MOVOU X4, 8*off+64*8(block); \
+ MOVOU X5, 8*off+80*8(block); \
+ MOVOU X6, 8*off+96*8(block); \
+ MOVOU X7, 8*off+112*8(block)
+
+#define BLAMKA_ROUND_0(block, off, t0, t1, c40, c48) \
+ LOAD_MSG_0(block, off); \
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
+ SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \
+ STORE_MSG_0(block, off)
+
+#define BLAMKA_ROUND_1(block, off, t0, t1, c40, c48) \
+ LOAD_MSG_1(block, off); \
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
+ SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \
+ HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
+ SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \
+ STORE_MSG_1(block, off)
+
+// func blamkaSSE4(b *block)
+TEXT ·blamkaSSE4(SB), 4, $0-8
+ MOVQ b+0(FP), AX
+
+ MOVOU ·c40<>(SB), X10
+ MOVOU ·c48<>(SB), X11
+
+ BLAMKA_ROUND_0(AX, 0, X8, X9, X10, X11)
+ BLAMKA_ROUND_0(AX, 16, X8, X9, X10, X11)
+ BLAMKA_ROUND_0(AX, 32, X8, X9, X10, X11)
+ BLAMKA_ROUND_0(AX, 48, X8, X9, X10, X11)
+ BLAMKA_ROUND_0(AX, 64, X8, X9, X10, X11)
+ BLAMKA_ROUND_0(AX, 80, X8, X9, X10, X11)
+ BLAMKA_ROUND_0(AX, 96, X8, X9, X10, X11)
+ BLAMKA_ROUND_0(AX, 112, X8, X9, X10, X11)
+
+ BLAMKA_ROUND_1(AX, 0, X8, X9, X10, X11)
+ BLAMKA_ROUND_1(AX, 2, X8, X9, X10, X11)
+ BLAMKA_ROUND_1(AX, 4, X8, X9, X10, X11)
+ BLAMKA_ROUND_1(AX, 6, X8, X9, X10, X11)
+ BLAMKA_ROUND_1(AX, 8, X8, X9, X10, X11)
+ BLAMKA_ROUND_1(AX, 10, X8, X9, X10, X11)
+ BLAMKA_ROUND_1(AX, 12, X8, X9, X10, X11)
+ BLAMKA_ROUND_1(AX, 14, X8, X9, X10, X11)
+ RET
+
+// func mixBlocksSSE2(out, a, b, c *block)
+TEXT ·mixBlocksSSE2(SB), 4, $0-32
+ MOVQ out+0(FP), DX
+ MOVQ a+8(FP), AX
+ MOVQ b+16(FP), BX
+ MOVQ c+24(FP), CX
+ MOVQ $128, DI
+
+loop:
+ MOVOU 0(AX), X0
+ MOVOU 0(BX), X1
+ MOVOU 0(CX), X2
+ PXOR X1, X0
+ PXOR X2, X0
+ MOVOU X0, 0(DX)
+ ADDQ $16, AX
+ ADDQ $16, BX
+ ADDQ $16, CX
+ ADDQ $16, DX
+ SUBQ $2, DI
+ JA loop
+ RET
+
+// func xorBlocksSSE2(out, a, b, c *block)
+TEXT ·xorBlocksSSE2(SB), 4, $0-32
+ MOVQ out+0(FP), DX
+ MOVQ a+8(FP), AX
+ MOVQ b+16(FP), BX
+ MOVQ c+24(FP), CX
+ MOVQ $128, DI
+
+loop:
+ MOVOU 0(AX), X0
+ MOVOU 0(BX), X1
+ MOVOU 0(CX), X2
+ MOVOU 0(DX), X3
+ PXOR X1, X0
+ PXOR X2, X0
+ PXOR X3, X0
+ MOVOU X0, 0(DX)
+ ADDQ $16, AX
+ ADDQ $16, BX
+ ADDQ $16, CX
+ ADDQ $16, DX
+ SUBQ $2, DI
+ JA loop
+ RET
diff --git a/vendor/golang.org/x/crypto/argon2/blamka_generic.go b/vendor/golang.org/x/crypto/argon2/blamka_generic.go
new file mode 100644
index 00000000..a481b224
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blamka_generic.go
@@ -0,0 +1,163 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package argon2
+
+var useSSE4 bool
+
+func processBlockGeneric(out, in1, in2 *block, xor bool) {
+ var t block
+ for i := range t {
+ t[i] = in1[i] ^ in2[i]
+ }
+ for i := 0; i < blockLength; i += 16 {
+ blamkaGeneric(
+ &t[i+0], &t[i+1], &t[i+2], &t[i+3],
+ &t[i+4], &t[i+5], &t[i+6], &t[i+7],
+ &t[i+8], &t[i+9], &t[i+10], &t[i+11],
+ &t[i+12], &t[i+13], &t[i+14], &t[i+15],
+ )
+ }
+ for i := 0; i < blockLength/8; i += 2 {
+ blamkaGeneric(
+ &t[i], &t[i+1], &t[16+i], &t[16+i+1],
+ &t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1],
+ &t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1],
+ &t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1],
+ )
+ }
+ if xor {
+ for i := range t {
+ out[i] ^= in1[i] ^ in2[i] ^ t[i]
+ }
+ } else {
+ for i := range t {
+ out[i] = in1[i] ^ in2[i] ^ t[i]
+ }
+ }
+}
+
+func blamkaGeneric(t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15 *uint64) {
+ v00, v01, v02, v03 := *t00, *t01, *t02, *t03
+ v04, v05, v06, v07 := *t04, *t05, *t06, *t07
+ v08, v09, v10, v11 := *t08, *t09, *t10, *t11
+ v12, v13, v14, v15 := *t12, *t13, *t14, *t15
+
+ v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04))
+ v12 ^= v00
+ v12 = v12>>32 | v12<<32
+ v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12))
+ v04 ^= v08
+ v04 = v04>>24 | v04<<40
+
+ v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04))
+ v12 ^= v00
+ v12 = v12>>16 | v12<<48
+ v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12))
+ v04 ^= v08
+ v04 = v04>>63 | v04<<1
+
+ v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05))
+ v13 ^= v01
+ v13 = v13>>32 | v13<<32
+ v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13))
+ v05 ^= v09
+ v05 = v05>>24 | v05<<40
+
+ v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05))
+ v13 ^= v01
+ v13 = v13>>16 | v13<<48
+ v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13))
+ v05 ^= v09
+ v05 = v05>>63 | v05<<1
+
+ v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06))
+ v14 ^= v02
+ v14 = v14>>32 | v14<<32
+ v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14))
+ v06 ^= v10
+ v06 = v06>>24 | v06<<40
+
+ v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06))
+ v14 ^= v02
+ v14 = v14>>16 | v14<<48
+ v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14))
+ v06 ^= v10
+ v06 = v06>>63 | v06<<1
+
+ v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07))
+ v15 ^= v03
+ v15 = v15>>32 | v15<<32
+ v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15))
+ v07 ^= v11
+ v07 = v07>>24 | v07<<40
+
+ v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07))
+ v15 ^= v03
+ v15 = v15>>16 | v15<<48
+ v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15))
+ v07 ^= v11
+ v07 = v07>>63 | v07<<1
+
+ v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05))
+ v15 ^= v00
+ v15 = v15>>32 | v15<<32
+ v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15))
+ v05 ^= v10
+ v05 = v05>>24 | v05<<40
+
+ v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05))
+ v15 ^= v00
+ v15 = v15>>16 | v15<<48
+ v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15))
+ v05 ^= v10
+ v05 = v05>>63 | v05<<1
+
+ v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06))
+ v12 ^= v01
+ v12 = v12>>32 | v12<<32
+ v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12))
+ v06 ^= v11
+ v06 = v06>>24 | v06<<40
+
+ v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06))
+ v12 ^= v01
+ v12 = v12>>16 | v12<<48
+ v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12))
+ v06 ^= v11
+ v06 = v06>>63 | v06<<1
+
+ v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07))
+ v13 ^= v02
+ v13 = v13>>32 | v13<<32
+ v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13))
+ v07 ^= v08
+ v07 = v07>>24 | v07<<40
+
+ v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07))
+ v13 ^= v02
+ v13 = v13>>16 | v13<<48
+ v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13))
+ v07 ^= v08
+ v07 = v07>>63 | v07<<1
+
+ v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04))
+ v14 ^= v03
+ v14 = v14>>32 | v14<<32
+ v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14))
+ v04 ^= v09
+ v04 = v04>>24 | v04<<40
+
+ v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04))
+ v14 ^= v03
+ v14 = v14>>16 | v14<<48
+ v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14))
+ v04 ^= v09
+ v04 = v04>>63 | v04<<1
+
+ *t00, *t01, *t02, *t03 = v00, v01, v02, v03
+ *t04, *t05, *t06, *t07 = v04, v05, v06, v07
+ *t08, *t09, *t10, *t11 = v08, v09, v10, v11
+ *t12, *t13, *t14, *t15 = v12, v13, v14, v15
+}
diff --git a/vendor/golang.org/x/crypto/argon2/blamka_ref.go b/vendor/golang.org/x/crypto/argon2/blamka_ref.go
new file mode 100644
index 00000000..16d58c65
--- /dev/null
+++ b/vendor/golang.org/x/crypto/argon2/blamka_ref.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || purego || !gc
+
+package argon2
+
+func processBlock(out, in1, in2 *block) {
+ processBlockGeneric(out, in1, in2, false)
+}
+
+func processBlockXOR(out, in1, in2 *block) {
+ processBlockGeneric(out, in1, in2, true)
+}
diff --git a/vendor/golang.org/x/crypto/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/chacha20/chacha_arm64.go b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
new file mode 100644
index 00000000..661ea132
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
@@ -0,0 +1,16 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+package chacha20
+
+const bufSize = 256
+
+//go:noescape
+func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
+
+func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
+ xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)
+}
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
new file mode 100644
index 00000000..7dd2638e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
@@ -0,0 +1,307 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+#include "textflag.h"
+
+#define NUM_ROUNDS 10
+
+// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
+TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
+ MOVD dst+0(FP), R1
+ MOVD src+24(FP), R2
+ MOVD src_len+32(FP), R3
+ MOVD key+48(FP), R4
+ MOVD nonce+56(FP), R6
+ MOVD counter+64(FP), R7
+
+ MOVD $·constants(SB), R10
+ MOVD $·incRotMatrix(SB), R11
+
+ MOVW (R7), R20
+
+ AND $~255, R3, R13
+ ADD R2, R13, R12 // R12 for block end
+ AND $255, R3, R13
+loop:
+ MOVD $NUM_ROUNDS, R21
+ VLD1 (R11), [V30.S4, V31.S4]
+
+ // load contants
+ // VLD4R (R10), [V0.S4, V1.S4, V2.S4, V3.S4]
+ WORD $0x4D60E940
+
+ // load keys
+ // VLD4R 16(R4), [V4.S4, V5.S4, V6.S4, V7.S4]
+ WORD $0x4DFFE884
+ // VLD4R 16(R4), [V8.S4, V9.S4, V10.S4, V11.S4]
+ WORD $0x4DFFE888
+ SUB $32, R4
+
+ // load counter + nonce
+ // VLD1R (R7), [V12.S4]
+ WORD $0x4D40C8EC
+
+ // VLD3R (R6), [V13.S4, V14.S4, V15.S4]
+ WORD $0x4D40E8CD
+
+ // update counter
+ VADD V30.S4, V12.S4, V12.S4
+
+chacha:
+ // V0..V3 += V4..V7
+ // V12..V15 <<<= ((V12..V15 XOR V0..V3), 16)
+ VADD V0.S4, V4.S4, V0.S4
+ VADD V1.S4, V5.S4, V1.S4
+ VADD V2.S4, V6.S4, V2.S4
+ VADD V3.S4, V7.S4, V3.S4
+ VEOR V12.B16, V0.B16, V12.B16
+ VEOR V13.B16, V1.B16, V13.B16
+ VEOR V14.B16, V2.B16, V14.B16
+ VEOR V15.B16, V3.B16, V15.B16
+ VREV32 V12.H8, V12.H8
+ VREV32 V13.H8, V13.H8
+ VREV32 V14.H8, V14.H8
+ VREV32 V15.H8, V15.H8
+ // V8..V11 += V12..V15
+ // V4..V7 <<<= ((V4..V7 XOR V8..V11), 12)
+ VADD V8.S4, V12.S4, V8.S4
+ VADD V9.S4, V13.S4, V9.S4
+ VADD V10.S4, V14.S4, V10.S4
+ VADD V11.S4, V15.S4, V11.S4
+ VEOR V8.B16, V4.B16, V16.B16
+ VEOR V9.B16, V5.B16, V17.B16
+ VEOR V10.B16, V6.B16, V18.B16
+ VEOR V11.B16, V7.B16, V19.B16
+ VSHL $12, V16.S4, V4.S4
+ VSHL $12, V17.S4, V5.S4
+ VSHL $12, V18.S4, V6.S4
+ VSHL $12, V19.S4, V7.S4
+ VSRI $20, V16.S4, V4.S4
+ VSRI $20, V17.S4, V5.S4
+ VSRI $20, V18.S4, V6.S4
+ VSRI $20, V19.S4, V7.S4
+
+ // V0..V3 += V4..V7
+ // V12..V15 <<<= ((V12..V15 XOR V0..V3), 8)
+ VADD V0.S4, V4.S4, V0.S4
+ VADD V1.S4, V5.S4, V1.S4
+ VADD V2.S4, V6.S4, V2.S4
+ VADD V3.S4, V7.S4, V3.S4
+ VEOR V12.B16, V0.B16, V12.B16
+ VEOR V13.B16, V1.B16, V13.B16
+ VEOR V14.B16, V2.B16, V14.B16
+ VEOR V15.B16, V3.B16, V15.B16
+ VTBL V31.B16, [V12.B16], V12.B16
+ VTBL V31.B16, [V13.B16], V13.B16
+ VTBL V31.B16, [V14.B16], V14.B16
+ VTBL V31.B16, [V15.B16], V15.B16
+
+ // V8..V11 += V12..V15
+ // V4..V7 <<<= ((V4..V7 XOR V8..V11), 7)
+ VADD V12.S4, V8.S4, V8.S4
+ VADD V13.S4, V9.S4, V9.S4
+ VADD V14.S4, V10.S4, V10.S4
+ VADD V15.S4, V11.S4, V11.S4
+ VEOR V8.B16, V4.B16, V16.B16
+ VEOR V9.B16, V5.B16, V17.B16
+ VEOR V10.B16, V6.B16, V18.B16
+ VEOR V11.B16, V7.B16, V19.B16
+ VSHL $7, V16.S4, V4.S4
+ VSHL $7, V17.S4, V5.S4
+ VSHL $7, V18.S4, V6.S4
+ VSHL $7, V19.S4, V7.S4
+ VSRI $25, V16.S4, V4.S4
+ VSRI $25, V17.S4, V5.S4
+ VSRI $25, V18.S4, V6.S4
+ VSRI $25, V19.S4, V7.S4
+
+ // V0..V3 += V5..V7, V4
+ // V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 16)
+ VADD V0.S4, V5.S4, V0.S4
+ VADD V1.S4, V6.S4, V1.S4
+ VADD V2.S4, V7.S4, V2.S4
+ VADD V3.S4, V4.S4, V3.S4
+ VEOR V15.B16, V0.B16, V15.B16
+ VEOR V12.B16, V1.B16, V12.B16
+ VEOR V13.B16, V2.B16, V13.B16
+ VEOR V14.B16, V3.B16, V14.B16
+ VREV32 V12.H8, V12.H8
+ VREV32 V13.H8, V13.H8
+ VREV32 V14.H8, V14.H8
+ VREV32 V15.H8, V15.H8
+
+ // V10 += V15; V5 <<<= ((V10 XOR V5), 12)
+ // ...
+ VADD V15.S4, V10.S4, V10.S4
+ VADD V12.S4, V11.S4, V11.S4
+ VADD V13.S4, V8.S4, V8.S4
+ VADD V14.S4, V9.S4, V9.S4
+ VEOR V10.B16, V5.B16, V16.B16
+ VEOR V11.B16, V6.B16, V17.B16
+ VEOR V8.B16, V7.B16, V18.B16
+ VEOR V9.B16, V4.B16, V19.B16
+ VSHL $12, V16.S4, V5.S4
+ VSHL $12, V17.S4, V6.S4
+ VSHL $12, V18.S4, V7.S4
+ VSHL $12, V19.S4, V4.S4
+ VSRI $20, V16.S4, V5.S4
+ VSRI $20, V17.S4, V6.S4
+ VSRI $20, V18.S4, V7.S4
+ VSRI $20, V19.S4, V4.S4
+
+ // V0 += V5; V15 <<<= ((V0 XOR V15), 8)
+ // ...
+ VADD V5.S4, V0.S4, V0.S4
+ VADD V6.S4, V1.S4, V1.S4
+ VADD V7.S4, V2.S4, V2.S4
+ VADD V4.S4, V3.S4, V3.S4
+ VEOR V0.B16, V15.B16, V15.B16
+ VEOR V1.B16, V12.B16, V12.B16
+ VEOR V2.B16, V13.B16, V13.B16
+ VEOR V3.B16, V14.B16, V14.B16
+ VTBL V31.B16, [V12.B16], V12.B16
+ VTBL V31.B16, [V13.B16], V13.B16
+ VTBL V31.B16, [V14.B16], V14.B16
+ VTBL V31.B16, [V15.B16], V15.B16
+
+ // V10 += V15; V5 <<<= ((V10 XOR V5), 7)
+ // ...
+ VADD V15.S4, V10.S4, V10.S4
+ VADD V12.S4, V11.S4, V11.S4
+ VADD V13.S4, V8.S4, V8.S4
+ VADD V14.S4, V9.S4, V9.S4
+ VEOR V10.B16, V5.B16, V16.B16
+ VEOR V11.B16, V6.B16, V17.B16
+ VEOR V8.B16, V7.B16, V18.B16
+ VEOR V9.B16, V4.B16, V19.B16
+ VSHL $7, V16.S4, V5.S4
+ VSHL $7, V17.S4, V6.S4
+ VSHL $7, V18.S4, V7.S4
+ VSHL $7, V19.S4, V4.S4
+ VSRI $25, V16.S4, V5.S4
+ VSRI $25, V17.S4, V6.S4
+ VSRI $25, V18.S4, V7.S4
+ VSRI $25, V19.S4, V4.S4
+
+ SUB $1, R21
+ CBNZ R21, chacha
+
+ // VLD4R (R10), [V16.S4, V17.S4, V18.S4, V19.S4]
+ WORD $0x4D60E950
+
+ // VLD4R 16(R4), [V20.S4, V21.S4, V22.S4, V23.S4]
+ WORD $0x4DFFE894
+ VADD V30.S4, V12.S4, V12.S4
+ VADD V16.S4, V0.S4, V0.S4
+ VADD V17.S4, V1.S4, V1.S4
+ VADD V18.S4, V2.S4, V2.S4
+ VADD V19.S4, V3.S4, V3.S4
+ // VLD4R 16(R4), [V24.S4, V25.S4, V26.S4, V27.S4]
+ WORD $0x4DFFE898
+ // restore R4
+ SUB $32, R4
+
+ // load counter + nonce
+ // VLD1R (R7), [V28.S4]
+ WORD $0x4D40C8FC
+ // VLD3R (R6), [V29.S4, V30.S4, V31.S4]
+ WORD $0x4D40E8DD
+
+ VADD V20.S4, V4.S4, V4.S4
+ VADD V21.S4, V5.S4, V5.S4
+ VADD V22.S4, V6.S4, V6.S4
+ VADD V23.S4, V7.S4, V7.S4
+ VADD V24.S4, V8.S4, V8.S4
+ VADD V25.S4, V9.S4, V9.S4
+ VADD V26.S4, V10.S4, V10.S4
+ VADD V27.S4, V11.S4, V11.S4
+ VADD V28.S4, V12.S4, V12.S4
+ VADD V29.S4, V13.S4, V13.S4
+ VADD V30.S4, V14.S4, V14.S4
+ VADD V31.S4, V15.S4, V15.S4
+
+ VZIP1 V1.S4, V0.S4, V16.S4
+ VZIP2 V1.S4, V0.S4, V17.S4
+ VZIP1 V3.S4, V2.S4, V18.S4
+ VZIP2 V3.S4, V2.S4, V19.S4
+ VZIP1 V5.S4, V4.S4, V20.S4
+ VZIP2 V5.S4, V4.S4, V21.S4
+ VZIP1 V7.S4, V6.S4, V22.S4
+ VZIP2 V7.S4, V6.S4, V23.S4
+ VZIP1 V9.S4, V8.S4, V24.S4
+ VZIP2 V9.S4, V8.S4, V25.S4
+ VZIP1 V11.S4, V10.S4, V26.S4
+ VZIP2 V11.S4, V10.S4, V27.S4
+ VZIP1 V13.S4, V12.S4, V28.S4
+ VZIP2 V13.S4, V12.S4, V29.S4
+ VZIP1 V15.S4, V14.S4, V30.S4
+ VZIP2 V15.S4, V14.S4, V31.S4
+ VZIP1 V18.D2, V16.D2, V0.D2
+ VZIP2 V18.D2, V16.D2, V4.D2
+ VZIP1 V19.D2, V17.D2, V8.D2
+ VZIP2 V19.D2, V17.D2, V12.D2
+ VLD1.P 64(R2), [V16.B16, V17.B16, V18.B16, V19.B16]
+
+ VZIP1 V22.D2, V20.D2, V1.D2
+ VZIP2 V22.D2, V20.D2, V5.D2
+ VZIP1 V23.D2, V21.D2, V9.D2
+ VZIP2 V23.D2, V21.D2, V13.D2
+ VLD1.P 64(R2), [V20.B16, V21.B16, V22.B16, V23.B16]
+ VZIP1 V26.D2, V24.D2, V2.D2
+ VZIP2 V26.D2, V24.D2, V6.D2
+ VZIP1 V27.D2, V25.D2, V10.D2
+ VZIP2 V27.D2, V25.D2, V14.D2
+ VLD1.P 64(R2), [V24.B16, V25.B16, V26.B16, V27.B16]
+ VZIP1 V30.D2, V28.D2, V3.D2
+ VZIP2 V30.D2, V28.D2, V7.D2
+ VZIP1 V31.D2, V29.D2, V11.D2
+ VZIP2 V31.D2, V29.D2, V15.D2
+ VLD1.P 64(R2), [V28.B16, V29.B16, V30.B16, V31.B16]
+ VEOR V0.B16, V16.B16, V16.B16
+ VEOR V1.B16, V17.B16, V17.B16
+ VEOR V2.B16, V18.B16, V18.B16
+ VEOR V3.B16, V19.B16, V19.B16
+ VST1.P [V16.B16, V17.B16, V18.B16, V19.B16], 64(R1)
+ VEOR V4.B16, V20.B16, V20.B16
+ VEOR V5.B16, V21.B16, V21.B16
+ VEOR V6.B16, V22.B16, V22.B16
+ VEOR V7.B16, V23.B16, V23.B16
+ VST1.P [V20.B16, V21.B16, V22.B16, V23.B16], 64(R1)
+ VEOR V8.B16, V24.B16, V24.B16
+ VEOR V9.B16, V25.B16, V25.B16
+ VEOR V10.B16, V26.B16, V26.B16
+ VEOR V11.B16, V27.B16, V27.B16
+ VST1.P [V24.B16, V25.B16, V26.B16, V27.B16], 64(R1)
+ VEOR V12.B16, V28.B16, V28.B16
+ VEOR V13.B16, V29.B16, V29.B16
+ VEOR V14.B16, V30.B16, V30.B16
+ VEOR V15.B16, V31.B16, V31.B16
+ VST1.P [V28.B16, V29.B16, V30.B16, V31.B16], 64(R1)
+
+ ADD $4, R20
+ MOVW R20, (R7) // update counter
+
+ CMP R2, R12
+ BGT loop
+
+ RET
+
+
+DATA ·constants+0x00(SB)/4, $0x61707865
+DATA ·constants+0x04(SB)/4, $0x3320646e
+DATA ·constants+0x08(SB)/4, $0x79622d32
+DATA ·constants+0x0c(SB)/4, $0x6b206574
+GLOBL ·constants(SB), NOPTR|RODATA, $32
+
+DATA ·incRotMatrix+0x00(SB)/4, $0x00000000
+DATA ·incRotMatrix+0x04(SB)/4, $0x00000001
+DATA ·incRotMatrix+0x08(SB)/4, $0x00000002
+DATA ·incRotMatrix+0x0c(SB)/4, $0x00000003
+DATA ·incRotMatrix+0x10(SB)/4, $0x02010003
+DATA ·incRotMatrix+0x14(SB)/4, $0x06050407
+DATA ·incRotMatrix+0x18(SB)/4, $0x0A09080B
+DATA ·incRotMatrix+0x1c(SB)/4, $0x0E0D0C0F
+GLOBL ·incRotMatrix(SB), NOPTR|RODATA, $32
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_generic.go b/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
new file mode 100644
index 00000000..93eb5ae6
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
@@ -0,0 +1,398 @@
+// 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 chacha20 implements the ChaCha20 and XChaCha20 encryption algorithms
+// as specified in RFC 8439 and draft-irtf-cfrg-xchacha-01.
+package chacha20
+
+import (
+ "crypto/cipher"
+ "encoding/binary"
+ "errors"
+ "math/bits"
+
+ "golang.org/x/crypto/internal/alias"
+)
+
+const (
+ // KeySize is the size of the key used by this cipher, in bytes.
+ KeySize = 32
+
+ // NonceSize is the size of the nonce used with the standard variant of this
+ // cipher, in bytes.
+ //
+ // Note that this is too short to be safely generated at random if the same
+ // key is reused more than 2³² times.
+ NonceSize = 12
+
+ // NonceSizeX is the size of the nonce used with the XChaCha20 variant of
+ // this cipher, in bytes.
+ NonceSizeX = 24
+)
+
+// Cipher is a stateful instance of ChaCha20 or XChaCha20 using a particular key
+// and nonce. A *Cipher implements the cipher.Stream interface.
+type Cipher struct {
+ // The ChaCha20 state is 16 words: 4 constant, 8 of key, 1 of counter
+ // (incremented after each block), and 3 of nonce.
+ key [8]uint32
+ counter uint32
+ nonce [3]uint32
+
+ // The last len bytes of buf are leftover key stream bytes from the previous
+ // XORKeyStream invocation. The size of buf depends on how many blocks are
+ // computed at a time by xorKeyStreamBlocks.
+ buf [bufSize]byte
+ len int
+
+ // overflow is set when the counter overflowed, no more blocks can be
+ // generated, and the next XORKeyStream call should panic.
+ overflow bool
+
+ // The counter-independent results of the first round are cached after they
+ // are computed the first time.
+ precompDone bool
+ p1, p5, p9, p13 uint32
+ p2, p6, p10, p14 uint32
+ p3, p7, p11, p15 uint32
+}
+
+var _ cipher.Stream = (*Cipher)(nil)
+
+// NewUnauthenticatedCipher creates a new ChaCha20 stream cipher with the given
+// 32 bytes key and a 12 or 24 bytes nonce. If a nonce of 24 bytes is provided,
+// the XChaCha20 construction will be used. It returns an error if key or nonce
+// have any other length.
+//
+// Note that ChaCha20, like all stream ciphers, is not authenticated and allows
+// attackers to silently tamper with the plaintext. For this reason, it is more
+// appropriate as a building block than as a standalone encryption mechanism.
+// Instead, consider using package golang.org/x/crypto/chacha20poly1305.
+func NewUnauthenticatedCipher(key, nonce []byte) (*Cipher, error) {
+ // This function is split into a wrapper so that the Cipher allocation will
+ // be inlined, and depending on how the caller uses the return value, won't
+ // escape to the heap.
+ c := &Cipher{}
+ return newUnauthenticatedCipher(c, key, nonce)
+}
+
+func newUnauthenticatedCipher(c *Cipher, key, nonce []byte) (*Cipher, error) {
+ if len(key) != KeySize {
+ return nil, errors.New("chacha20: wrong key size")
+ }
+ if len(nonce) == NonceSizeX {
+ // XChaCha20 uses the ChaCha20 core to mix 16 bytes of the nonce into a
+ // derived key, allowing it to operate on a nonce of 24 bytes. See
+ // draft-irtf-cfrg-xchacha-01, Section 2.3.
+ key, _ = HChaCha20(key, nonce[0:16])
+ cNonce := make([]byte, NonceSize)
+ copy(cNonce[4:12], nonce[16:24])
+ nonce = cNonce
+ } else if len(nonce) != NonceSize {
+ return nil, errors.New("chacha20: wrong nonce size")
+ }
+
+ key, nonce = key[:KeySize], nonce[:NonceSize] // bounds check elimination hint
+ c.key = [8]uint32{
+ binary.LittleEndian.Uint32(key[0:4]),
+ binary.LittleEndian.Uint32(key[4:8]),
+ binary.LittleEndian.Uint32(key[8:12]),
+ binary.LittleEndian.Uint32(key[12:16]),
+ binary.LittleEndian.Uint32(key[16:20]),
+ binary.LittleEndian.Uint32(key[20:24]),
+ binary.LittleEndian.Uint32(key[24:28]),
+ binary.LittleEndian.Uint32(key[28:32]),
+ }
+ c.nonce = [3]uint32{
+ binary.LittleEndian.Uint32(nonce[0:4]),
+ binary.LittleEndian.Uint32(nonce[4:8]),
+ binary.LittleEndian.Uint32(nonce[8:12]),
+ }
+ return c, nil
+}
+
+// The constant first 4 words of the ChaCha20 state.
+const (
+ j0 uint32 = 0x61707865 // expa
+ j1 uint32 = 0x3320646e // nd 3
+ j2 uint32 = 0x79622d32 // 2-by
+ j3 uint32 = 0x6b206574 // te k
+)
+
+const blockSize = 64
+
+// quarterRound is the core of ChaCha20. It shuffles the bits of 4 state words.
+// It's executed 4 times for each of the 20 ChaCha20 rounds, operating on all 16
+// words each round, in columnar or diagonal groups of 4 at a time.
+func quarterRound(a, b, c, d uint32) (uint32, uint32, uint32, uint32) {
+ a += b
+ d ^= a
+ d = bits.RotateLeft32(d, 16)
+ c += d
+ b ^= c
+ b = bits.RotateLeft32(b, 12)
+ a += b
+ d ^= a
+ d = bits.RotateLeft32(d, 8)
+ c += d
+ b ^= c
+ b = bits.RotateLeft32(b, 7)
+ return a, b, c, d
+}
+
+// SetCounter sets the Cipher counter. The next invocation of XORKeyStream will
+// behave as if (64 * counter) bytes had been encrypted so far.
+//
+// To prevent accidental counter reuse, SetCounter panics if counter is less
+// than the current value.
+//
+// Note that the execution time of XORKeyStream is not independent of the
+// counter value.
+func (s *Cipher) SetCounter(counter uint32) {
+ // Internally, s may buffer multiple blocks, which complicates this
+ // implementation slightly. When checking whether the counter has rolled
+ // back, we must use both s.counter and s.len to determine how many blocks
+ // we have already output.
+ outputCounter := s.counter - uint32(s.len)/blockSize
+ if s.overflow || counter < outputCounter {
+ panic("chacha20: SetCounter attempted to rollback counter")
+ }
+
+ // In the general case, we set the new counter value and reset s.len to 0,
+ // causing the next call to XORKeyStream to refill the buffer. However, if
+ // we're advancing within the existing buffer, we can save work by simply
+ // setting s.len.
+ if counter < s.counter {
+ s.len = int(s.counter-counter) * blockSize
+ } else {
+ s.counter = counter
+ s.len = 0
+ }
+}
+
+// XORKeyStream XORs each byte in the given slice with a byte from the
+// cipher's key stream. Dst and src must overlap entirely or not at all.
+//
+// If len(dst) < len(src), XORKeyStream will panic. It is acceptable
+// to pass a dst bigger than src, and in that case, XORKeyStream will
+// only update dst[:len(src)] and will not touch the rest of dst.
+//
+// Multiple calls to XORKeyStream behave as if the concatenation of
+// the src buffers was passed in a single run. That is, Cipher
+// maintains state and does not reset at each XORKeyStream call.
+func (s *Cipher) XORKeyStream(dst, src []byte) {
+ if len(src) == 0 {
+ return
+ }
+ if len(dst) < len(src) {
+ panic("chacha20: output smaller than input")
+ }
+ dst = dst[:len(src)]
+ if alias.InexactOverlap(dst, src) {
+ panic("chacha20: invalid buffer overlap")
+ }
+
+ // First, drain any remaining key stream from a previous XORKeyStream.
+ if s.len != 0 {
+ keyStream := s.buf[bufSize-s.len:]
+ if len(src) < len(keyStream) {
+ keyStream = keyStream[:len(src)]
+ }
+ _ = src[len(keyStream)-1] // bounds check elimination hint
+ for i, b := range keyStream {
+ dst[i] = src[i] ^ b
+ }
+ s.len -= len(keyStream)
+ dst, src = dst[len(keyStream):], src[len(keyStream):]
+ }
+ if len(src) == 0 {
+ return
+ }
+
+ // If we'd need to let the counter overflow and keep generating output,
+ // panic immediately. If instead we'd only reach the last block, remember
+ // not to generate any more output after the buffer is drained.
+ numBlocks := (uint64(len(src)) + blockSize - 1) / blockSize
+ if s.overflow || uint64(s.counter)+numBlocks > 1<<32 {
+ panic("chacha20: counter overflow")
+ } else if uint64(s.counter)+numBlocks == 1<<32 {
+ s.overflow = true
+ }
+
+ // xorKeyStreamBlocks implementations expect input lengths that are a
+ // multiple of bufSize. Platform-specific ones process multiple blocks at a
+ // time, so have bufSizes that are a multiple of blockSize.
+
+ full := len(src) - len(src)%bufSize
+ if full > 0 {
+ s.xorKeyStreamBlocks(dst[:full], src[:full])
+ }
+ dst, src = dst[full:], src[full:]
+
+ // If using a multi-block xorKeyStreamBlocks would overflow, use the generic
+ // one that does one block at a time.
+ const blocksPerBuf = bufSize / blockSize
+ if uint64(s.counter)+blocksPerBuf > 1<<32 {
+ s.buf = [bufSize]byte{}
+ numBlocks := (len(src) + blockSize - 1) / blockSize
+ buf := s.buf[bufSize-numBlocks*blockSize:]
+ copy(buf, src)
+ s.xorKeyStreamBlocksGeneric(buf, buf)
+ s.len = len(buf) - copy(dst, buf)
+ return
+ }
+
+ // If we have a partial (multi-)block, pad it for xorKeyStreamBlocks, and
+ // keep the leftover keystream for the next XORKeyStream invocation.
+ if len(src) > 0 {
+ s.buf = [bufSize]byte{}
+ copy(s.buf[:], src)
+ s.xorKeyStreamBlocks(s.buf[:], s.buf[:])
+ s.len = bufSize - copy(dst, s.buf[:])
+ }
+}
+
+func (s *Cipher) xorKeyStreamBlocksGeneric(dst, src []byte) {
+ if len(dst) != len(src) || len(dst)%blockSize != 0 {
+ panic("chacha20: internal error: wrong dst and/or src length")
+ }
+
+ // To generate each block of key stream, the initial cipher state
+ // (represented below) is passed through 20 rounds of shuffling,
+ // alternatively applying quarterRounds by columns (like 1, 5, 9, 13)
+ // or by diagonals (like 1, 6, 11, 12).
+ //
+ // 0:cccccccc 1:cccccccc 2:cccccccc 3:cccccccc
+ // 4:kkkkkkkk 5:kkkkkkkk 6:kkkkkkkk 7:kkkkkkkk
+ // 8:kkkkkkkk 9:kkkkkkkk 10:kkkkkkkk 11:kkkkkkkk
+ // 12:bbbbbbbb 13:nnnnnnnn 14:nnnnnnnn 15:nnnnnnnn
+ //
+ // c=constant k=key b=blockcount n=nonce
+ var (
+ c0, c1, c2, c3 = j0, j1, j2, j3
+ c4, c5, c6, c7 = s.key[0], s.key[1], s.key[2], s.key[3]
+ c8, c9, c10, c11 = s.key[4], s.key[5], s.key[6], s.key[7]
+ _, c13, c14, c15 = s.counter, s.nonce[0], s.nonce[1], s.nonce[2]
+ )
+
+ // Three quarters of the first round don't depend on the counter, so we can
+ // calculate them here, and reuse them for multiple blocks in the loop, and
+ // for future XORKeyStream invocations.
+ if !s.precompDone {
+ s.p1, s.p5, s.p9, s.p13 = quarterRound(c1, c5, c9, c13)
+ s.p2, s.p6, s.p10, s.p14 = quarterRound(c2, c6, c10, c14)
+ s.p3, s.p7, s.p11, s.p15 = quarterRound(c3, c7, c11, c15)
+ s.precompDone = true
+ }
+
+ // A condition of len(src) > 0 would be sufficient, but this also
+ // acts as a bounds check elimination hint.
+ for len(src) >= 64 && len(dst) >= 64 {
+ // The remainder of the first column round.
+ fcr0, fcr4, fcr8, fcr12 := quarterRound(c0, c4, c8, s.counter)
+
+ // The second diagonal round.
+ x0, x5, x10, x15 := quarterRound(fcr0, s.p5, s.p10, s.p15)
+ x1, x6, x11, x12 := quarterRound(s.p1, s.p6, s.p11, fcr12)
+ x2, x7, x8, x13 := quarterRound(s.p2, s.p7, fcr8, s.p13)
+ x3, x4, x9, x14 := quarterRound(s.p3, fcr4, s.p9, s.p14)
+
+ // The remaining 18 rounds.
+ for i := 0; i < 9; i++ {
+ // Column round.
+ x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)
+ x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)
+ x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)
+ x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)
+
+ // Diagonal round.
+ x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)
+ x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)
+ x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)
+ x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)
+ }
+
+ // Add back the initial state to generate the key stream, then
+ // XOR the key stream with the source and write out the result.
+ addXor(dst[0:4], src[0:4], x0, c0)
+ addXor(dst[4:8], src[4:8], x1, c1)
+ addXor(dst[8:12], src[8:12], x2, c2)
+ addXor(dst[12:16], src[12:16], x3, c3)
+ addXor(dst[16:20], src[16:20], x4, c4)
+ addXor(dst[20:24], src[20:24], x5, c5)
+ addXor(dst[24:28], src[24:28], x6, c6)
+ addXor(dst[28:32], src[28:32], x7, c7)
+ addXor(dst[32:36], src[32:36], x8, c8)
+ addXor(dst[36:40], src[36:40], x9, c9)
+ addXor(dst[40:44], src[40:44], x10, c10)
+ addXor(dst[44:48], src[44:48], x11, c11)
+ addXor(dst[48:52], src[48:52], x12, s.counter)
+ addXor(dst[52:56], src[52:56], x13, c13)
+ addXor(dst[56:60], src[56:60], x14, c14)
+ addXor(dst[60:64], src[60:64], x15, c15)
+
+ s.counter += 1
+
+ src, dst = src[blockSize:], dst[blockSize:]
+ }
+}
+
+// HChaCha20 uses the ChaCha20 core to generate a derived key from a 32 bytes
+// key and a 16 bytes nonce. It returns an error if key or nonce have any other
+// length. It is used as part of the XChaCha20 construction.
+func HChaCha20(key, nonce []byte) ([]byte, error) {
+ // This function is split into a wrapper so that the slice allocation will
+ // be inlined, and depending on how the caller uses the return value, won't
+ // escape to the heap.
+ out := make([]byte, 32)
+ return hChaCha20(out, key, nonce)
+}
+
+func hChaCha20(out, key, nonce []byte) ([]byte, error) {
+ if len(key) != KeySize {
+ return nil, errors.New("chacha20: wrong HChaCha20 key size")
+ }
+ if len(nonce) != 16 {
+ return nil, errors.New("chacha20: wrong HChaCha20 nonce size")
+ }
+
+ x0, x1, x2, x3 := j0, j1, j2, j3
+ x4 := binary.LittleEndian.Uint32(key[0:4])
+ x5 := binary.LittleEndian.Uint32(key[4:8])
+ x6 := binary.LittleEndian.Uint32(key[8:12])
+ x7 := binary.LittleEndian.Uint32(key[12:16])
+ x8 := binary.LittleEndian.Uint32(key[16:20])
+ x9 := binary.LittleEndian.Uint32(key[20:24])
+ x10 := binary.LittleEndian.Uint32(key[24:28])
+ x11 := binary.LittleEndian.Uint32(key[28:32])
+ x12 := binary.LittleEndian.Uint32(nonce[0:4])
+ x13 := binary.LittleEndian.Uint32(nonce[4:8])
+ x14 := binary.LittleEndian.Uint32(nonce[8:12])
+ x15 := binary.LittleEndian.Uint32(nonce[12:16])
+
+ for i := 0; i < 10; i++ {
+ // Diagonal round.
+ x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)
+ x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)
+ x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)
+ x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)
+
+ // Column round.
+ x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)
+ x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)
+ x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)
+ x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)
+ }
+
+ _ = out[31] // bounds check elimination hint
+ binary.LittleEndian.PutUint32(out[0:4], x0)
+ binary.LittleEndian.PutUint32(out[4:8], x1)
+ binary.LittleEndian.PutUint32(out[8:12], x2)
+ binary.LittleEndian.PutUint32(out[12:16], x3)
+ binary.LittleEndian.PutUint32(out[16:20], x12)
+ binary.LittleEndian.PutUint32(out[20:24], x13)
+ binary.LittleEndian.PutUint32(out[24:28], x14)
+ binary.LittleEndian.PutUint32(out[28:32], x15)
+ return out, nil
+}
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
new file mode 100644
index 00000000..db42e667
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
@@ -0,0 +1,13 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (!arm64 && !s390x && !ppc64le) || !gc || purego
+
+package chacha20
+
+const bufSize = blockSize
+
+func (s *Cipher) xorKeyStreamBlocks(dst, src []byte) {
+ s.xorKeyStreamBlocksGeneric(dst, src)
+}
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
new file mode 100644
index 00000000..3a4287f9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
@@ -0,0 +1,16 @@
+// 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 gc && !purego
+
+package chacha20
+
+const bufSize = 256
+
+//go:noescape
+func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
+
+func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
+ chaCha20_ctr32_vsx(&dst[0], &src[0], len(src), &c.key, &c.counter)
+}
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
new file mode 100644
index 00000000..c672ccf6
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
@@ -0,0 +1,443 @@
+// 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.
+
+// Based on CRYPTOGAMS code with the following comment:
+// # ====================================================================
+// # Written by Andy Polyakov for the OpenSSL
+// # project. The module is, however, dual licensed under OpenSSL and
+// # CRYPTOGAMS licenses depending on where you obtain it. For further
+// # details see http://www.openssl.org/~appro/cryptogams/.
+// # ====================================================================
+
+// Code for the perl script that generates the ppc64 assembler
+// can be found in the cryptogams repository at the link below. It is based on
+// the original from openssl.
+
+// https://github.com/dot-asm/cryptogams/commit/a60f5b50ed908e91
+
+// The differences in this and the original implementation are
+// due to the calling conventions and initialization of constants.
+
+//go:build gc && !purego
+
+#include "textflag.h"
+
+#define OUT R3
+#define INP R4
+#define LEN R5
+#define KEY R6
+#define CNT R7
+#define TMP R15
+
+#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
+DATA consts<>+0x18(SB)/8, $0x0000000000000000
+DATA consts<>+0x20(SB)/8, $0x0000000000000004
+DATA consts<>+0x28(SB)/8, $0x0000000000000000
+DATA consts<>+0x30(SB)/8, $0x0a0b08090e0f0c0d
+DATA consts<>+0x38(SB)/8, $0x0203000106070405
+DATA consts<>+0x40(SB)/8, $0x090a0b080d0e0f0c
+DATA consts<>+0x48(SB)/8, $0x0102030005060704
+DATA consts<>+0x50(SB)/8, $0x6170786561707865
+DATA consts<>+0x58(SB)/8, $0x6170786561707865
+DATA consts<>+0x60(SB)/8, $0x3320646e3320646e
+DATA consts<>+0x68(SB)/8, $0x3320646e3320646e
+DATA consts<>+0x70(SB)/8, $0x79622d3279622d32
+DATA consts<>+0x78(SB)/8, $0x79622d3279622d32
+DATA consts<>+0x80(SB)/8, $0x6b2065746b206574
+DATA consts<>+0x88(SB)/8, $0x6b2065746b206574
+DATA consts<>+0x90(SB)/8, $0x0000000100000000
+DATA consts<>+0x98(SB)/8, $0x0000000300000002
+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
+ MOVD out+0(FP), OUT
+ MOVD inp+8(FP), INP
+ MOVD len+16(FP), LEN
+ MOVD key+24(FP), KEY
+ MOVD counter+32(FP), CNT
+
+ // Addressing for constants
+ MOVD $consts<>+0x00(SB), CONSTBASE
+ MOVD $16, R8
+ MOVD $32, R9
+ 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
+
+ // Load key into V17,V18
+ LXVW4X (KEY)(R0), VS49
+ LXVW4X (KEY)(R8), VS50
+
+ // Load CNT, NONCE into V19
+ LXVW4X (CNT)(R0), VS51
+
+ // Clear V27
+ VXOR V27, V27, V27
+
+ // 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
+
+ VSLDOI $4, V19, V27, V19
+ VSLDOI $12, V27, V19, V19
+
+ VADDUWM V26, V28, V26
+
+ MOVD $10, R14
+ MOVD R14, CTR
+ PCALIGN $16
+loop_outer_vsx:
+ // V0, V1, V2, V3
+ LXVW4X (R0)(CONSTBASE), VS32
+ LXVW4X (R8)(CONSTBASE), VS33
+ LXVW4X (R9)(CONSTBASE), VS34
+ LXVW4X (R10)(CONSTBASE), VS35
+
+ // splat values from V17, V18 into V4-V11
+ VSPLTW $0, V17, V4
+ VSPLTW $1, V17, V5
+ VSPLTW $2, V17, V6
+ VSPLTW $3, V17, V7
+ VSPLTW $0, V18, V8
+ VSPLTW $1, V18, V9
+ VSPLTW $2, V18, V10
+ VSPLTW $3, V18, V11
+
+ // VOR
+ VOR V26, V26, V12
+
+ // splat values from V19 -> V13, V14, V15
+ VSPLTW $1, V19, V13
+ VSPLTW $2, V19, V14
+ VSPLTW $3, V19, V15
+
+ // splat const values
+ VSPLTISW $-16, V27
+ 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
+
+ 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
+ VADDUWM V10, V14, V10
+ VADDUWM V11, V15, V11
+
+ VXOR V4, V8, V4
+ VXOR V5, V9, V5
+ VXOR V6, V10, V6
+ VXOR V7, V11, V7
+
+ VRLW V4, V28, V4
+ VRLW V5, V28, V5
+ VRLW V6, V28, V6
+ VRLW V7, V28, V7
+
+ VADDUWM V0, V4, V0
+ VADDUWM V1, V5, V1
+ VADDUWM V2, V6, V2
+ VADDUWM V3, V7, V3
+
+ 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
+ VADDUWM V10, V14, V10
+ VADDUWM V11, V15, V11
+
+ VXOR V4, V8, V4
+ VXOR V5, V9, V5
+ VXOR V6, V10, V6
+ VXOR V7, V11, V7
+
+ VRLW V4, V30, V4
+ VRLW V5, V30, V5
+ VRLW V6, V30, V6
+ VRLW V7, V30, V7
+
+ VADDUWM V0, V5, V0
+ VADDUWM V1, V6, V1
+ VADDUWM V2, V7, V2
+ VADDUWM V3, V4, V3
+
+ 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
+ VADDUWM V8, V13, V8
+ VADDUWM V9, V14, V9
+
+ VXOR V5, V10, V5
+ VXOR V6, V11, V6
+ VXOR V7, V8, V7
+ VXOR V4, V9, V4
+
+ VRLW V5, V28, V5
+ VRLW V6, V28, V6
+ VRLW V7, V28, V7
+ VRLW V4, V28, V4
+
+ VADDUWM V0, V5, V0
+ VADDUWM V1, V6, V1
+ VADDUWM V2, V7, V2
+ VADDUWM V3, V4, V3
+
+ 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
+ VADDUWM V8, V13, V8
+ VADDUWM V9, V14, V9
+
+ VXOR V5, V10, V5
+ VXOR V6, V11, V6
+ VXOR V7, V8, V7
+ VXOR V4, V9, V4
+
+ VRLW V5, V30, V5
+ VRLW V6, V30, V6
+ VRLW V7, V30, V7
+ VRLW V4, V30, V4
+ BDNZ loop_vsx
+
+ VADDUWM V12, V26, V12
+
+ VMRGEW V0, V1, V27
+ VMRGEW V2, V3, V28
+
+ VMRGOW V0, V1, V0
+ VMRGOW V2, V3, V2
+
+ 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
+
+ VMRGOW V4, V5, V4
+ VMRGOW V6, V7, V6
+
+ 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
+
+ VMRGOW V8, V9, V8
+ VMRGOW V10, V11, V10
+
+ 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
+
+ VMRGOW V12, V13, V12
+ VMRGOW V14, V15, V14
+
+ VSPLTISW $4, V27
+ VADDUWM V26, V27, V26
+
+ XXPERMDI VS44, VS46, $0, VS45
+ XXPERMDI VS44, VS46, $3, VS47
+ XXPERMDI VS61, VS62, $0, VS44
+ XXPERMDI VS61, VS62, $3, VS46
+
+ VADDUWM V0, V16, V0
+ VADDUWM V4, V17, V4
+ VADDUWM V8, V18, V8
+ VADDUWM V12, V19, V12
+
+ CMPU LEN, $64
+ BLT tail_vsx
+
+ // Bottom of loop
+ LXVW4X (INP)(R0), VS59
+ LXVW4X (INP)(R8), VS60
+ LXVW4X (INP)(R9), VS61
+ LXVW4X (INP)(R10), VS62
+
+ VXOR V27, V0, V27
+ VXOR V28, V4, V28
+ VXOR V29, V8, V29
+ VXOR V30, V12, V30
+
+ STXVW4X VS59, (OUT)(R0)
+ STXVW4X VS60, (OUT)(R8)
+ ADD $64, INP
+ STXVW4X VS61, (OUT)(R9)
+ ADD $-64, LEN
+ STXVW4X VS62, (OUT)(R10)
+ ADD $64, OUT
+ BEQ done_vsx
+
+ VADDUWM V1, V16, V0
+ VADDUWM V5, V17, V4
+ VADDUWM V9, V18, V8
+ VADDUWM V13, V19, V12
+
+ CMPU LEN, $64
+ BLT tail_vsx
+
+ LXVW4X (INP)(R0), VS59
+ LXVW4X (INP)(R8), VS60
+ LXVW4X (INP)(R9), VS61
+ LXVW4X (INP)(R10), VS62
+ VXOR V27, V0, V27
+
+ VXOR V28, V4, V28
+ VXOR V29, V8, V29
+ VXOR V30, V12, V30
+
+ STXVW4X VS59, (OUT)(R0)
+ STXVW4X VS60, (OUT)(R8)
+ ADD $64, INP
+ STXVW4X VS61, (OUT)(R9)
+ ADD $-64, LEN
+ STXVW4X VS62, (OUT)(V10)
+ ADD $64, OUT
+ BEQ done_vsx
+
+ VADDUWM V2, V16, V0
+ VADDUWM V6, V17, V4
+ VADDUWM V10, V18, V8
+ VADDUWM V14, V19, V12
+
+ CMPU LEN, $64
+ BLT tail_vsx
+
+ LXVW4X (INP)(R0), VS59
+ LXVW4X (INP)(R8), VS60
+ LXVW4X (INP)(R9), VS61
+ LXVW4X (INP)(R10), VS62
+
+ VXOR V27, V0, V27
+ VXOR V28, V4, V28
+ VXOR V29, V8, V29
+ VXOR V30, V12, V30
+
+ STXVW4X VS59, (OUT)(R0)
+ STXVW4X VS60, (OUT)(R8)
+ ADD $64, INP
+ STXVW4X VS61, (OUT)(R9)
+ ADD $-64, LEN
+ STXVW4X VS62, (OUT)(R10)
+ ADD $64, OUT
+ BEQ done_vsx
+
+ VADDUWM V3, V16, V0
+ VADDUWM V7, V17, V4
+ VADDUWM V11, V18, V8
+ VADDUWM V15, V19, V12
+
+ CMPU LEN, $64
+ BLT tail_vsx
+
+ LXVW4X (INP)(R0), VS59
+ LXVW4X (INP)(R8), VS60
+ LXVW4X (INP)(R9), VS61
+ LXVW4X (INP)(R10), VS62
+
+ VXOR V27, V0, V27
+ VXOR V28, V4, V28
+ VXOR V29, V8, V29
+ VXOR V30, V12, V30
+
+ STXVW4X VS59, (OUT)(R0)
+ STXVW4X VS60, (OUT)(R8)
+ ADD $64, INP
+ STXVW4X VS61, (OUT)(R9)
+ ADD $-64, LEN
+ STXVW4X VS62, (OUT)(R10)
+ ADD $64, OUT
+
+ MOVD $10, R14
+ MOVD R14, CTR
+ BNE loop_outer_vsx
+
+done_vsx:
+ // Increment counter by number of 64 byte blocks
+ MOVD (CNT), R14
+ ADD BLOCKS, R14
+ MOVD R14, (CNT)
+ RET
+
+tail_vsx:
+ ADD $32, R1, R11
+ MOVD LEN, CTR
+
+ // Save values on stack to copy from
+ STXVW4X VS32, (R11)(R0)
+ STXVW4X VS36, (R11)(R8)
+ STXVW4X VS40, (R11)(R9)
+ STXVW4X VS44, (R11)(R10)
+ ADD $-1, R11, R12
+ ADD $-1, INP
+ ADD $-1, OUT
+ PCALIGN $16
+looptail_vsx:
+ // Copying the result to OUT
+ // in bytes.
+ MOVBZU 1(R12), KEY
+ MOVBZU 1(INP), TMP
+ XOR KEY, TMP, KEY
+ MOVBU KEY, 1(OUT)
+ BDNZ looptail_vsx
+
+ // Clear the stack values
+ STXVW4X VS48, (R11)(R0)
+ STXVW4X VS48, (R11)(R8)
+ STXVW4X VS48, (R11)(R9)
+ STXVW4X VS48, (R11)(R10)
+ BR done_vsx
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
new file mode 100644
index 00000000..683ccfd1
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
@@ -0,0 +1,27 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+package chacha20
+
+import "golang.org/x/sys/cpu"
+
+var haveAsm = cpu.S390X.HasVX
+
+const bufSize = 256
+
+// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
+// be called when the vector facility is available. Implementation in asm_s390x.s.
+//
+//go:noescape
+func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
+
+func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
+ if cpu.S390X.HasVX {
+ xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)
+ } else {
+ c.xorKeyStreamBlocksGeneric(dst, src)
+ }
+}
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
new file mode 100644
index 00000000..1eda91a3
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
@@ -0,0 +1,224 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+#include "go_asm.h"
+#include "textflag.h"
+
+// This is an implementation of the ChaCha20 encryption algorithm as
+// specified in RFC 7539. It uses vector instructions to compute
+// 4 keystream blocks in parallel (256 bytes) which are then XORed
+// with the bytes in the input slice.
+
+GLOBL ·constants<>(SB), RODATA|NOPTR, $32
+// BSWAP: swap bytes in each 4-byte element
+DATA ·constants<>+0x00(SB)/4, $0x03020100
+DATA ·constants<>+0x04(SB)/4, $0x07060504
+DATA ·constants<>+0x08(SB)/4, $0x0b0a0908
+DATA ·constants<>+0x0c(SB)/4, $0x0f0e0d0c
+// J0: [j0, j1, j2, j3]
+DATA ·constants<>+0x10(SB)/4, $0x61707865
+DATA ·constants<>+0x14(SB)/4, $0x3320646e
+DATA ·constants<>+0x18(SB)/4, $0x79622d32
+DATA ·constants<>+0x1c(SB)/4, $0x6b206574
+
+#define BSWAP V5
+#define J0 V6
+#define KEY0 V7
+#define KEY1 V8
+#define NONCE V9
+#define CTR V10
+#define M0 V11
+#define M1 V12
+#define M2 V13
+#define M3 V14
+#define INC V15
+#define X0 V16
+#define X1 V17
+#define X2 V18
+#define X3 V19
+#define X4 V20
+#define X5 V21
+#define X6 V22
+#define X7 V23
+#define X8 V24
+#define X9 V25
+#define X10 V26
+#define X11 V27
+#define X12 V28
+#define X13 V29
+#define X14 V30
+#define X15 V31
+
+#define NUM_ROUNDS 20
+
+#define ROUND4(a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3, d0, d1, d2, d3) \
+ VAF a1, a0, a0 \
+ VAF b1, b0, b0 \
+ VAF c1, c0, c0 \
+ VAF d1, d0, d0 \
+ VX a0, a2, a2 \
+ VX b0, b2, b2 \
+ VX c0, c2, c2 \
+ VX d0, d2, d2 \
+ VERLLF $16, a2, a2 \
+ VERLLF $16, b2, b2 \
+ VERLLF $16, c2, c2 \
+ VERLLF $16, d2, d2 \
+ VAF a2, a3, a3 \
+ VAF b2, b3, b3 \
+ VAF c2, c3, c3 \
+ VAF d2, d3, d3 \
+ VX a3, a1, a1 \
+ VX b3, b1, b1 \
+ VX c3, c1, c1 \
+ VX d3, d1, d1 \
+ VERLLF $12, a1, a1 \
+ VERLLF $12, b1, b1 \
+ VERLLF $12, c1, c1 \
+ VERLLF $12, d1, d1 \
+ VAF a1, a0, a0 \
+ VAF b1, b0, b0 \
+ VAF c1, c0, c0 \
+ VAF d1, d0, d0 \
+ VX a0, a2, a2 \
+ VX b0, b2, b2 \
+ VX c0, c2, c2 \
+ VX d0, d2, d2 \
+ VERLLF $8, a2, a2 \
+ VERLLF $8, b2, b2 \
+ VERLLF $8, c2, c2 \
+ VERLLF $8, d2, d2 \
+ VAF a2, a3, a3 \
+ VAF b2, b3, b3 \
+ VAF c2, c3, c3 \
+ VAF d2, d3, d3 \
+ VX a3, a1, a1 \
+ VX b3, b1, b1 \
+ VX c3, c1, c1 \
+ VX d3, d1, d1 \
+ VERLLF $7, a1, a1 \
+ VERLLF $7, b1, b1 \
+ VERLLF $7, c1, c1 \
+ VERLLF $7, d1, d1
+
+#define PERMUTE(mask, v0, v1, v2, v3) \
+ VPERM v0, v0, mask, v0 \
+ VPERM v1, v1, mask, v1 \
+ VPERM v2, v2, mask, v2 \
+ VPERM v3, v3, mask, v3
+
+#define ADDV(x, v0, v1, v2, v3) \
+ VAF x, v0, v0 \
+ VAF x, v1, v1 \
+ VAF x, v2, v2 \
+ VAF x, v3, v3
+
+#define XORV(off, dst, src, v0, v1, v2, v3) \
+ VLM off(src), M0, M3 \
+ PERMUTE(BSWAP, v0, v1, v2, v3) \
+ VX v0, M0, M0 \
+ VX v1, M1, M1 \
+ VX v2, M2, M2 \
+ VX v3, M3, M3 \
+ VSTM M0, M3, off(dst)
+
+#define SHUFFLE(a, b, c, d, t, u, v, w) \
+ VMRHF a, c, t \ // t = {a[0], c[0], a[1], c[1]}
+ VMRHF b, d, u \ // u = {b[0], d[0], b[1], d[1]}
+ VMRLF a, c, v \ // v = {a[2], c[2], a[3], c[3]}
+ VMRLF b, d, w \ // w = {b[2], d[2], b[3], d[3]}
+ VMRHF t, u, a \ // a = {a[0], b[0], c[0], d[0]}
+ VMRLF t, u, b \ // b = {a[1], b[1], c[1], d[1]}
+ VMRHF v, w, c \ // c = {a[2], b[2], c[2], d[2]}
+ VMRLF v, w, d // d = {a[3], b[3], c[3], d[3]}
+
+// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
+TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
+ MOVD $·constants<>(SB), R1
+ MOVD dst+0(FP), R2 // R2=&dst[0]
+ LMG src+24(FP), R3, R4 // R3=&src[0] R4=len(src)
+ MOVD key+48(FP), R5 // R5=key
+ MOVD nonce+56(FP), R6 // R6=nonce
+ MOVD counter+64(FP), R7 // R7=counter
+
+ // load BSWAP and J0
+ VLM (R1), BSWAP, J0
+
+ // setup
+ MOVD $95, R0
+ VLM (R5), KEY0, KEY1
+ VLL R0, (R6), NONCE
+ VZERO M0
+ VLEIB $7, $32, M0
+ VSRLB M0, NONCE, NONCE
+
+ // initialize counter values
+ VLREPF (R7), CTR
+ VZERO INC
+ VLEIF $1, $1, INC
+ VLEIF $2, $2, INC
+ VLEIF $3, $3, INC
+ VAF INC, CTR, CTR
+ VREPIF $4, INC
+
+chacha:
+ VREPF $0, J0, X0
+ VREPF $1, J0, X1
+ VREPF $2, J0, X2
+ VREPF $3, J0, X3
+ VREPF $0, KEY0, X4
+ VREPF $1, KEY0, X5
+ VREPF $2, KEY0, X6
+ VREPF $3, KEY0, X7
+ VREPF $0, KEY1, X8
+ VREPF $1, KEY1, X9
+ VREPF $2, KEY1, X10
+ VREPF $3, KEY1, X11
+ VLR CTR, X12
+ VREPF $1, NONCE, X13
+ VREPF $2, NONCE, X14
+ VREPF $3, NONCE, X15
+
+ MOVD $(NUM_ROUNDS/2), R1
+
+loop:
+ ROUND4(X0, X4, X12, X8, X1, X5, X13, X9, X2, X6, X14, X10, X3, X7, X15, X11)
+ ROUND4(X0, X5, X15, X10, X1, X6, X12, X11, X2, X7, X13, X8, X3, X4, X14, X9)
+
+ ADD $-1, R1
+ BNE loop
+
+ // decrement length
+ ADD $-256, R4
+
+ // rearrange vectors
+ SHUFFLE(X0, X1, X2, X3, M0, M1, M2, M3)
+ ADDV(J0, X0, X1, X2, X3)
+ SHUFFLE(X4, X5, X6, X7, M0, M1, M2, M3)
+ ADDV(KEY0, X4, X5, X6, X7)
+ SHUFFLE(X8, X9, X10, X11, M0, M1, M2, M3)
+ ADDV(KEY1, X8, X9, X10, X11)
+ VAF CTR, X12, X12
+ SHUFFLE(X12, X13, X14, X15, M0, M1, M2, M3)
+ ADDV(NONCE, X12, X13, X14, X15)
+
+ // increment counters
+ VAF INC, CTR, CTR
+
+ // xor keystream with plaintext
+ XORV(0*64, R2, R3, X0, X4, X8, X12)
+ XORV(1*64, R2, R3, X1, X5, X9, X13)
+ XORV(2*64, R2, R3, X2, X6, X10, X14)
+ XORV(3*64, R2, R3, X3, X7, X11, X15)
+
+ // increment pointers
+ MOVD $256(R2), R2
+ MOVD $256(R3), R3
+
+ CMPBNE R4, $0, chacha
+
+ VSTEF $0, CTR, (R7)
+ RET
diff --git a/vendor/golang.org/x/crypto/chacha20/xor.go b/vendor/golang.org/x/crypto/chacha20/xor.go
new file mode 100644
index 00000000..c2d04851
--- /dev/null
+++ b/vendor/golang.org/x/crypto/chacha20/xor.go
@@ -0,0 +1,42 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found src the LICENSE file.
+
+package chacha20
+
+import "runtime"
+
+// Platforms that have fast unaligned 32-bit little endian accesses.
+const unaligned = runtime.GOARCH == "386" ||
+ runtime.GOARCH == "amd64" ||
+ runtime.GOARCH == "arm64" ||
+ runtime.GOARCH == "ppc64le" ||
+ runtime.GOARCH == "s390x"
+
+// addXor reads a little endian uint32 from src, XORs it with (a + b) and
+// places the result in little endian byte order in dst.
+func addXor(dst, src []byte, a, b uint32) {
+ _, _ = src[3], dst[3] // bounds check elimination hint
+ if unaligned {
+ // The compiler should optimize this code into
+ // 32-bit unaligned little endian loads and stores.
+ // TODO: delete once the compiler does a reliably
+ // good job with the generic code below.
+ // See issue #25111 for more details.
+ v := uint32(src[0])
+ v |= uint32(src[1]) << 8
+ v |= uint32(src[2]) << 16
+ v |= uint32(src[3]) << 24
+ v ^= a + b
+ dst[0] = byte(v)
+ dst[1] = byte(v >> 8)
+ dst[2] = byte(v >> 16)
+ dst[3] = byte(v >> 24)
+ } else {
+ a += b
+ dst[0] = src[0] ^ byte(a)
+ dst[1] = src[1] ^ byte(a>>8)
+ dst[2] = src[2] ^ byte(a>>16)
+ dst[3] = src[3] ^ byte(a>>24)
+ }
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go
new file mode 100644
index 00000000..21ca3b2e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go
@@ -0,0 +1,90 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package curve25519 provides an implementation of the X25519 function, which
+// performs scalar multiplication on the elliptic curve known as Curve25519.
+// See RFC 7748.
+//
+// This package is a wrapper for the X25519 implementation
+// in the crypto/ecdh package.
+package curve25519
+
+import "crypto/ecdh"
+
+// ScalarMult sets dst to the product scalar * point.
+//
+// Deprecated: when provided a low-order point, ScalarMult will set dst to all
+// zeroes, irrespective of the scalar. Instead, use the X25519 function, which
+// will return an error.
+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
+ }
+ }
+}
+
+// ScalarBaseMult sets dst to the product scalar * base where base is the
+// standard generator.
+//
+// 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) {
+ 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 (
+ // ScalarSize is the size of the scalar input to X25519.
+ ScalarSize = 32
+ // PointSize is the size of the point input to X25519.
+ PointSize = 32
+)
+
+// Basepoint is the canonical Curve25519 generator.
+var Basepoint []byte
+
+var basePoint = [32]byte{9}
+
+func init() { Basepoint = basePoint[:] }
+
+// X25519 returns the result of the scalar multiplication (scalar * point),
+// according to RFC 7748, Section 5. scalar, point and the return value are
+// slices of 32 bytes.
+//
+// scalar can be generated at random, for example with crypto/rand. point should
+// be either Basepoint or the output of another X25519 call.
+//
+// If point is Basepoint (but not if it's a different slice with the same
+// contents) a precomputed implementation might be used for performance.
+func X25519(scalar, point []byte) ([]byte, error) {
+ // Outline the body of function, to let the allocation be inlined in the
+ // caller, and possibly avoid escaping to the heap.
+ 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/hkdf/hkdf.go b/vendor/golang.org/x/crypto/hkdf/hkdf.go
new file mode 100644
index 00000000..3bee6629
--- /dev/null
+++ b/vendor/golang.org/x/crypto/hkdf/hkdf.go
@@ -0,0 +1,95 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation
+// Function (HKDF) as defined in RFC 5869.
+//
+// HKDF is a cryptographic key derivation function (KDF) with the goal of
+// expanding limited input keying material into one or more cryptographically
+// strong secret keys.
+package hkdf
+
+import (
+ "crypto/hmac"
+ "errors"
+ "hash"
+ "io"
+)
+
+// Extract generates a pseudorandom key for use with Expand from an input secret
+// and an optional independent salt.
+//
+// Only use this function if you need to reuse the extracted key with multiple
+// Expand invocations and different context values. Most common scenarios,
+// including the generation of multiple keys, should use New instead.
+func Extract(hash func() hash.Hash, secret, salt []byte) []byte {
+ if salt == nil {
+ salt = make([]byte, hash().Size())
+ }
+ extractor := hmac.New(hash, salt)
+ extractor.Write(secret)
+ return extractor.Sum(nil)
+}
+
+type hkdf struct {
+ expander hash.Hash
+ size int
+
+ info []byte
+ counter byte
+
+ prev []byte
+ buf []byte
+}
+
+func (f *hkdf) Read(p []byte) (int, error) {
+ // Check whether enough data can be generated
+ need := len(p)
+ remains := len(f.buf) + int(255-f.counter+1)*f.size
+ if remains < need {
+ return 0, errors.New("hkdf: entropy limit reached")
+ }
+ // Read any leftover from the buffer
+ n := copy(p, f.buf)
+ p = p[n:]
+
+ // Fill the rest of the buffer
+ for len(p) > 0 {
+ if f.counter > 1 {
+ f.expander.Reset()
+ }
+ f.expander.Write(f.prev)
+ f.expander.Write(f.info)
+ f.expander.Write([]byte{f.counter})
+ f.prev = f.expander.Sum(f.prev[:0])
+ f.counter++
+
+ // Copy the new batch into p
+ f.buf = f.prev
+ n = copy(p, f.buf)
+ p = p[n:]
+ }
+ // Save leftovers for next run
+ f.buf = f.buf[n:]
+
+ return need, nil
+}
+
+// Expand returns a Reader, from which keys can be read, using the given
+// pseudorandom key and optional context info, skipping the extraction step.
+//
+// The pseudorandomKey should have been generated by Extract, or be a uniformly
+// random or pseudorandom cryptographically strong key. See RFC 5869, Section
+// 3.3. Most common scenarios will want to use New instead.
+func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader {
+ expander := hmac.New(hash, pseudorandomKey)
+ return &hkdf{expander, expander.Size(), info, 1, nil, nil}
+}
+
+// New returns a Reader, from which keys can be read, using the given hash,
+// secret, salt and context info. Salt and info can be nil.
+func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader {
+ prk := Extract(hash, secret, salt)
+ return Expand(hash, prk, info)
+}
diff --git a/vendor/golang.org/x/crypto/internal/alias/alias.go b/vendor/golang.org/x/crypto/internal/alias/alias.go
new file mode 100644
index 00000000..551ff0c3
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/alias/alias.go
@@ -0,0 +1,31 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !purego
+
+// Package alias implements memory aliasing tests.
+package alias
+
+import "unsafe"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+ return len(x) > 0 && len(y) > 0 &&
+ uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
+ uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+ return false
+ }
+ return AnyOverlap(x, y)
+}
diff --git a/vendor/golang.org/x/crypto/internal/alias/alias_purego.go b/vendor/golang.org/x/crypto/internal/alias/alias_purego.go
new file mode 100644
index 00000000..6fe61b5c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/alias/alias_purego.go
@@ -0,0 +1,34 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build purego
+
+// Package alias implements memory aliasing tests.
+package alias
+
+// This is the Google App Engine standard variant based on reflect
+// because the unsafe package and cgo are disallowed.
+
+import "reflect"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+ return len(x) > 0 && len(y) > 0 &&
+ reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
+ reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+ return false
+ }
+ return AnyOverlap(x, y)
+}
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go
new file mode 100644
index 00000000..333da285
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go
@@ -0,0 +1,9 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (!amd64 && !ppc64le && !s390x) || !gc || purego
+
+package poly1305
+
+type mac struct{ macGeneric }
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go b/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go
new file mode 100644
index 00000000..4aaea810
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go
@@ -0,0 +1,99 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package poly1305 implements Poly1305 one-time message authentication code as
+// specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
+//
+// Poly1305 is a fast, one-time authentication function. It is infeasible for an
+// attacker to generate an authenticator for a message without the key. However, a
+// key must only be used for a single message. Authenticating two different
+// messages with the same key allows an attacker to forge authenticators for other
+// messages with the same key.
+//
+// Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
+// used with a fixed key in order to generate one-time keys from an nonce.
+// However, in this package AES isn't used and the one-time key is specified
+// directly.
+package poly1305
+
+import "crypto/subtle"
+
+// TagSize is the size, in bytes, of a poly1305 authenticator.
+const TagSize = 16
+
+// Sum generates an authenticator for msg using a one-time key and puts the
+// 16-byte result into out. Authenticating two different messages with the same
+// key allows an attacker to forge messages at will.
+func Sum(out *[16]byte, m []byte, key *[32]byte) {
+ h := New(key)
+ h.Write(m)
+ h.Sum(out[:0])
+}
+
+// Verify returns true if mac is a valid authenticator for m with the given key.
+func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
+ var tmp [16]byte
+ Sum(&tmp, m, key)
+ return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
+}
+
+// New returns a new MAC computing an authentication
+// tag of all data written to it with the given key.
+// This allows writing the message progressively instead
+// of passing it as a single slice. Common users should use
+// the Sum function instead.
+//
+// The key must be unique for each message, as authenticating
+// two different messages with the same key allows an attacker
+// to forge messages at will.
+func New(key *[32]byte) *MAC {
+ m := &MAC{}
+ initialize(key, &m.macState)
+ return m
+}
+
+// MAC is an io.Writer computing an authentication tag
+// of the data written to it.
+//
+// MAC cannot be used like common hash.Hash implementations,
+// because using a poly1305 key twice breaks its security.
+// Therefore writing data to a running MAC after calling
+// Sum or Verify causes it to panic.
+type MAC struct {
+ mac // platform-dependent implementation
+
+ finalized bool
+}
+
+// Size returns the number of bytes Sum will return.
+func (h *MAC) Size() int { return TagSize }
+
+// Write adds more data to the running message authentication code.
+// It never returns an error.
+//
+// It must not be called after the first call of Sum or Verify.
+func (h *MAC) Write(p []byte) (n int, err error) {
+ if h.finalized {
+ panic("poly1305: write to MAC after Sum or Verify")
+ }
+ return h.mac.Write(p)
+}
+
+// Sum computes the authenticator of all data written to the
+// message authentication code.
+func (h *MAC) Sum(b []byte) []byte {
+ var mac [TagSize]byte
+ h.mac.Sum(&mac)
+ h.finalized = true
+ return append(b, mac[:]...)
+}
+
+// Verify returns whether the authenticator of all data written to
+// the message authentication code matches the expected value.
+func (h *MAC) Verify(expected []byte) bool {
+ var mac [TagSize]byte
+ h.mac.Sum(&mac)
+ h.finalized = true
+ return subtle.ConstantTimeCompare(expected, mac[:]) == 1
+}
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go
new file mode 100644
index 00000000..164cd47d
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go
@@ -0,0 +1,47 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+package poly1305
+
+//go:noescape
+func update(state *macState, msg []byte)
+
+// mac is a wrapper for macGeneric that redirects calls that would have gone to
+// updateGeneric to update.
+//
+// Its Write and Sum methods are otherwise identical to the macGeneric ones, but
+// using function pointers would carry a major performance cost.
+type mac struct{ macGeneric }
+
+func (h *mac) Write(p []byte) (int, error) {
+ nn := len(p)
+ if h.offset > 0 {
+ n := copy(h.buffer[h.offset:], p)
+ if h.offset+n < TagSize {
+ h.offset += n
+ return nn, nil
+ }
+ p = p[n:]
+ h.offset = 0
+ update(&h.macState, h.buffer[:])
+ }
+ if n := len(p) - (len(p) % TagSize); n > 0 {
+ update(&h.macState, p[:n])
+ p = p[n:]
+ }
+ if len(p) > 0 {
+ h.offset += copy(h.buffer[h.offset:], p)
+ }
+ return nn, nil
+}
+
+func (h *mac) Sum(out *[16]byte) {
+ state := h.macState
+ if h.offset > 0 {
+ update(&state, h.buffer[:h.offset])
+ }
+ finalize(out, &state.h, &state.s)
+}
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s
new file mode 100644
index 00000000..e0d3c647
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s
@@ -0,0 +1,108 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+#include "textflag.h"
+
+#define POLY1305_ADD(msg, h0, h1, h2) \
+ ADDQ 0(msg), h0; \
+ ADCQ 8(msg), h1; \
+ ADCQ $1, h2; \
+ LEAQ 16(msg), msg
+
+#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3) \
+ MOVQ r0, AX; \
+ MULQ h0; \
+ MOVQ AX, t0; \
+ MOVQ DX, t1; \
+ MOVQ r0, AX; \
+ MULQ h1; \
+ ADDQ AX, t1; \
+ ADCQ $0, DX; \
+ MOVQ r0, t2; \
+ IMULQ h2, t2; \
+ ADDQ DX, t2; \
+ \
+ MOVQ r1, AX; \
+ MULQ h0; \
+ ADDQ AX, t1; \
+ ADCQ $0, DX; \
+ MOVQ DX, h0; \
+ MOVQ r1, t3; \
+ IMULQ h2, t3; \
+ MOVQ r1, AX; \
+ MULQ h1; \
+ ADDQ AX, t2; \
+ ADCQ DX, t3; \
+ ADDQ h0, t2; \
+ ADCQ $0, t3; \
+ \
+ MOVQ t0, h0; \
+ MOVQ t1, h1; \
+ MOVQ t2, h2; \
+ ANDQ $3, h2; \
+ MOVQ t2, t0; \
+ ANDQ $0xFFFFFFFFFFFFFFFC, t0; \
+ ADDQ t0, h0; \
+ ADCQ t3, h1; \
+ ADCQ $0, h2; \
+ SHRQ $2, t3, t2; \
+ SHRQ $2, t3; \
+ ADDQ t2, h0; \
+ ADCQ t3, h1; \
+ ADCQ $0, h2
+
+// func update(state *[7]uint64, msg []byte)
+TEXT ·update(SB), $0-32
+ MOVQ state+0(FP), DI
+ MOVQ msg_base+8(FP), SI
+ MOVQ msg_len+16(FP), R15
+
+ MOVQ 0(DI), R8 // h0
+ MOVQ 8(DI), R9 // h1
+ MOVQ 16(DI), R10 // h2
+ MOVQ 24(DI), R11 // r0
+ MOVQ 32(DI), R12 // r1
+
+ CMPQ R15, $16
+ JB bytes_between_0_and_15
+
+loop:
+ POLY1305_ADD(SI, R8, R9, R10)
+
+multiply:
+ POLY1305_MUL(R8, R9, R10, R11, R12, BX, CX, R13, R14)
+ SUBQ $16, R15
+ CMPQ R15, $16
+ JAE loop
+
+bytes_between_0_and_15:
+ TESTQ R15, R15
+ JZ done
+ MOVQ $1, BX
+ XORQ CX, CX
+ XORQ R13, R13
+ ADDQ R15, SI
+
+flush_buffer:
+ SHLQ $8, BX, CX
+ SHLQ $8, BX
+ MOVB -1(SI), R13
+ XORQ R13, BX
+ DECQ SI
+ DECQ R15
+ JNZ flush_buffer
+
+ ADDQ BX, R8
+ ADCQ CX, R9
+ ADCQ $0, R10
+ MOVQ $16, R15
+ JMP multiply
+
+done:
+ MOVQ R8, 0(DI)
+ MOVQ R9, 8(DI)
+ MOVQ R10, 16(DI)
+ RET
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go
new file mode 100644
index 00000000..ec2202bd
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go
@@ -0,0 +1,312 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file provides the generic implementation of Sum and MAC. Other files
+// might provide optimized assembly implementations of some of this code.
+
+package poly1305
+
+import (
+ "encoding/binary"
+ "math/bits"
+)
+
+// Poly1305 [RFC 7539] is a relatively simple algorithm: the authentication tag
+// for a 64 bytes message is approximately
+//
+// s + m[0:16] * r⁴ + m[16:32] * r³ + m[32:48] * r² + m[48:64] * r mod 2¹³⁰ - 5
+//
+// for some secret r and s. It can be computed sequentially like
+//
+// for len(msg) > 0:
+// h += read(msg, 16)
+// h *= r
+// h %= 2¹³⁰ - 5
+// return h + s
+//
+// All the complexity is about doing performant constant-time math on numbers
+// larger than any available numeric type.
+
+func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
+ h := newMACGeneric(key)
+ h.Write(msg)
+ h.Sum(out)
+}
+
+func newMACGeneric(key *[32]byte) macGeneric {
+ m := macGeneric{}
+ initialize(key, &m.macState)
+ return m
+}
+
+// macState holds numbers in saturated 64-bit little-endian limbs. That is,
+// the value of [x0, x1, x2] is x[0] + x[1] * 2⁶⁴ + x[2] * 2¹²⁸.
+type macState struct {
+ // h is the main accumulator. It is to be interpreted modulo 2¹³⁰ - 5, but
+ // can grow larger during and after rounds. It must, however, remain below
+ // 2 * (2¹³⁰ - 5).
+ h [3]uint64
+ // r and s are the private key components.
+ r [2]uint64
+ s [2]uint64
+}
+
+type macGeneric struct {
+ macState
+
+ buffer [TagSize]byte
+ offset int
+}
+
+// Write splits the incoming message into TagSize chunks, and passes them to
+// update. It buffers incomplete chunks.
+func (h *macGeneric) Write(p []byte) (int, error) {
+ nn := len(p)
+ if h.offset > 0 {
+ n := copy(h.buffer[h.offset:], p)
+ if h.offset+n < TagSize {
+ h.offset += n
+ return nn, nil
+ }
+ p = p[n:]
+ h.offset = 0
+ updateGeneric(&h.macState, h.buffer[:])
+ }
+ if n := len(p) - (len(p) % TagSize); n > 0 {
+ updateGeneric(&h.macState, p[:n])
+ p = p[n:]
+ }
+ if len(p) > 0 {
+ h.offset += copy(h.buffer[h.offset:], p)
+ }
+ return nn, nil
+}
+
+// Sum flushes the last incomplete chunk from the buffer, if any, and generates
+// the MAC output. It does not modify its state, in order to allow for multiple
+// calls to Sum, even if no Write is allowed after Sum.
+func (h *macGeneric) Sum(out *[TagSize]byte) {
+ state := h.macState
+ if h.offset > 0 {
+ updateGeneric(&state, h.buffer[:h.offset])
+ }
+ finalize(out, &state.h, &state.s)
+}
+
+// [rMask0, rMask1] is the specified Poly1305 clamping mask in little-endian. It
+// clears some bits of the secret coefficient to make it possible to implement
+// multiplication more efficiently.
+const (
+ rMask0 = 0x0FFFFFFC0FFFFFFF
+ rMask1 = 0x0FFFFFFC0FFFFFFC
+)
+
+// initialize loads the 256-bit key into the two 128-bit secret values r and s.
+func initialize(key *[32]byte, m *macState) {
+ m.r[0] = binary.LittleEndian.Uint64(key[0:8]) & rMask0
+ m.r[1] = binary.LittleEndian.Uint64(key[8:16]) & rMask1
+ m.s[0] = binary.LittleEndian.Uint64(key[16:24])
+ m.s[1] = binary.LittleEndian.Uint64(key[24:32])
+}
+
+// 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
+}
+
+func mul64(a, b uint64) uint128 {
+ hi, lo := bits.Mul64(a, b)
+ return uint128{lo, hi}
+}
+
+func add128(a, b uint128) uint128 {
+ lo, c := bits.Add64(a.lo, b.lo, 0)
+ hi, c := bits.Add64(a.hi, b.hi, c)
+ if c != 0 {
+ panic("poly1305: unexpected overflow")
+ }
+ return uint128{lo, hi}
+}
+
+func shiftRightBy2(a uint128) uint128 {
+ a.lo = a.lo>>2 | (a.hi&3)<<62
+ a.hi = a.hi >> 2
+ return a
+}
+
+// updateGeneric absorbs msg into the state.h accumulator. For each chunk m of
+// 128 bits of message, it computes
+//
+// h₊ = (h + m) * r mod 2¹³⁰ - 5
+//
+// If the msg length is not a multiple of TagSize, it assumes the last
+// incomplete chunk is the final one.
+func updateGeneric(state *macState, msg []byte) {
+ h0, h1, h2 := state.h[0], state.h[1], state.h[2]
+ r0, r1 := state.r[0], state.r[1]
+
+ for len(msg) > 0 {
+ var c uint64
+
+ // For the first step, h + m, we use a chain of bits.Add64 intrinsics.
+ // The resulting value of h might exceed 2¹³⁰ - 5, but will be partially
+ // reduced at the end of the multiplication below.
+ //
+ // The spec requires us to set a bit just above the message size, not to
+ // hide leading zeroes. For full chunks, that's 1 << 128, so we can just
+ // add 1 to the most significant (2¹²⁸) limb, h2.
+ if len(msg) >= TagSize {
+ h0, c = bits.Add64(h0, binary.LittleEndian.Uint64(msg[0:8]), 0)
+ h1, c = bits.Add64(h1, binary.LittleEndian.Uint64(msg[8:16]), c)
+ h2 += c + 1
+
+ msg = msg[TagSize:]
+ } else {
+ var buf [TagSize]byte
+ copy(buf[:], msg)
+ buf[len(msg)] = 1
+
+ h0, c = bits.Add64(h0, binary.LittleEndian.Uint64(buf[0:8]), 0)
+ h1, c = bits.Add64(h1, binary.LittleEndian.Uint64(buf[8:16]), c)
+ h2 += c
+
+ msg = nil
+ }
+
+ // Multiplication of big number limbs is similar to elementary school
+ // columnar multiplication. Instead of digits, there are 64-bit limbs.
+ //
+ // We are multiplying a 3 limbs number, h, by a 2 limbs number, r.
+ //
+ // h2 h1 h0 x
+ // r1 r0 =
+ // ----------------
+ // h2r0 h1r0 h0r0 <-- individual 128-bit products
+ // + h2r1 h1r1 h0r1
+ // ------------------------
+ // m3 m2 m1 m0 <-- result in 128-bit overlapping limbs
+ // ------------------------
+ // m3.hi m2.hi m1.hi m0.hi <-- carry propagation
+ // + m3.lo m2.lo m1.lo m0.lo
+ // -------------------------------
+ // t4 t3 t2 t1 t0 <-- final result in 64-bit limbs
+ //
+ // The main difference from pen-and-paper multiplication is that we do
+ // carry propagation in a separate step, as if we wrote two digit sums
+ // at first (the 128-bit limbs), and then carried the tens all at once.
+
+ h0r0 := mul64(h0, r0)
+ h1r0 := mul64(h1, r0)
+ h2r0 := mul64(h2, r0)
+ h0r1 := mul64(h0, r1)
+ h1r1 := mul64(h1, r1)
+ h2r1 := mul64(h2, r1)
+
+ // Since h2 is known to be at most 7 (5 + 1 + 1), and r0 and r1 have their
+ // top 4 bits cleared by rMask{0,1}, we know that their product is not going
+ // to overflow 64 bits, so we can ignore the high part of the products.
+ //
+ // This also means that the product doesn't have a fifth limb (t4).
+ if h2r0.hi != 0 {
+ panic("poly1305: unexpected overflow")
+ }
+ if h2r1.hi != 0 {
+ panic("poly1305: unexpected overflow")
+ }
+
+ m0 := h0r0
+ m1 := add128(h1r0, h0r1) // These two additions don't overflow thanks again
+ m2 := add128(h2r0, h1r1) // to the 4 masked bits at the top of r0 and r1.
+ m3 := h2r1
+
+ t0 := m0.lo
+ t1, c := bits.Add64(m1.lo, m0.hi, 0)
+ t2, c := bits.Add64(m2.lo, m1.hi, c)
+ t3, _ := bits.Add64(m3.lo, m2.hi, c)
+
+ // Now we have the result as 4 64-bit limbs, and we need to reduce it
+ // modulo 2¹³⁰ - 5. The special shape of this Crandall prime lets us do
+ // a cheap partial reduction according to the reduction identity
+ //
+ // c * 2¹³⁰ + n = c * 5 + n mod 2¹³⁰ - 5
+ //
+ // because 2¹³⁰ = 5 mod 2¹³⁰ - 5. Partial reduction since the result is
+ // likely to be larger than 2¹³⁰ - 5, but still small enough to fit the
+ // assumptions we make about h in the rest of the code.
+ //
+ // See also https://speakerdeck.com/gtank/engineering-prime-numbers?slide=23
+
+ // We split the final result at the 2¹³⁰ mark into h and cc, the carry.
+ // Note that the carry bits are effectively shifted left by 2, in other
+ // words, cc = c * 4 for the c in the reduction identity.
+ h0, h1, h2 = t0, t1, t2&maskLow2Bits
+ cc := uint128{t2 & maskNotLow2Bits, t3}
+
+ // To add c * 5 to h, we first add cc = c * 4, and then add (cc >> 2) = c.
+
+ h0, c = bits.Add64(h0, cc.lo, 0)
+ h1, c = bits.Add64(h1, cc.hi, c)
+ h2 += c
+
+ cc = shiftRightBy2(cc)
+
+ h0, c = bits.Add64(h0, cc.lo, 0)
+ h1, c = bits.Add64(h1, cc.hi, c)
+ h2 += c
+
+ // h2 is at most 3 + 1 + 1 = 5, making the whole of h at most
+ //
+ // 5 * 2¹²⁸ + (2¹²⁸ - 1) = 6 * 2¹²⁸ - 1
+ }
+
+ state.h[0], state.h[1], state.h[2] = h0, h1, h2
+}
+
+const (
+ maskLow2Bits uint64 = 0x0000000000000003
+ maskNotLow2Bits uint64 = ^maskLow2Bits
+)
+
+// select64 returns x if v == 1 and y if v == 0, in constant time.
+func select64(v, x, y uint64) uint64 { return ^(v-1)&x | (v-1)&y }
+
+// [p0, p1, p2] is 2¹³⁰ - 5 in little endian order.
+const (
+ p0 = 0xFFFFFFFFFFFFFFFB
+ p1 = 0xFFFFFFFFFFFFFFFF
+ p2 = 0x0000000000000003
+)
+
+// finalize completes the modular reduction of h and computes
+//
+// out = h + s mod 2¹²⁸
+func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) {
+ h0, h1, h2 := h[0], h[1], h[2]
+
+ // After the partial reduction in updateGeneric, h might be more than
+ // 2¹³⁰ - 5, but will be less than 2 * (2¹³⁰ - 5). To complete the reduction
+ // in constant time, we compute t = h - (2¹³⁰ - 5), and select h as the
+ // result if the subtraction underflows, and t otherwise.
+
+ hMinusP0, b := bits.Sub64(h0, p0, 0)
+ hMinusP1, b := bits.Sub64(h1, p1, b)
+ _, b = bits.Sub64(h2, p2, b)
+
+ // h = h if h < p else h - p
+ h0 = select64(b, h0, hMinusP0)
+ h1 = select64(b, h1, hMinusP1)
+
+ // Finally, we compute the last Poly1305 step
+ //
+ // tag = h + s mod 2¹²⁸
+ //
+ // by just doing a wide addition with the 128 low bits of h and discarding
+ // the overflow.
+ h0, c := bits.Add64(h0, s[0], 0)
+ h1, _ = bits.Add64(h1, s[1], c)
+
+ binary.LittleEndian.PutUint64(out[0:8], h0)
+ binary.LittleEndian.PutUint64(out[8:16], h1)
+}
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.go
new file mode 100644
index 00000000..4aec4874
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.go
@@ -0,0 +1,47 @@
+// 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 gc && !purego
+
+package poly1305
+
+//go:noescape
+func update(state *macState, msg []byte)
+
+// mac is a wrapper for macGeneric that redirects calls that would have gone to
+// updateGeneric to update.
+//
+// Its Write and Sum methods are otherwise identical to the macGeneric ones, but
+// using function pointers would carry a major performance cost.
+type mac struct{ macGeneric }
+
+func (h *mac) Write(p []byte) (int, error) {
+ nn := len(p)
+ if h.offset > 0 {
+ n := copy(h.buffer[h.offset:], p)
+ if h.offset+n < TagSize {
+ h.offset += n
+ return nn, nil
+ }
+ p = p[n:]
+ h.offset = 0
+ update(&h.macState, h.buffer[:])
+ }
+ if n := len(p) - (len(p) % TagSize); n > 0 {
+ update(&h.macState, p[:n])
+ p = p[n:]
+ }
+ if len(p) > 0 {
+ h.offset += copy(h.buffer[h.offset:], p)
+ }
+ return nn, nil
+}
+
+func (h *mac) Sum(out *[16]byte) {
+ state := h.macState
+ if h.offset > 0 {
+ update(&state, h.buffer[:h.offset])
+ }
+ finalize(out, &state.h, &state.s)
+}
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s
new file mode 100644
index 00000000..b3c1699b
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s
@@ -0,0 +1,179 @@
+// 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 gc && !purego
+
+#include "textflag.h"
+
+// This was ported from the amd64 implementation.
+
+#define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \
+ MOVD (msg), t0; \
+ MOVD 8(msg), t1; \
+ MOVD $1, t2; \
+ ADDC t0, h0, h0; \
+ ADDE t1, h1, h1; \
+ ADDE t2, h2; \
+ ADD $16, msg
+
+#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \
+ MULLD r0, h0, t0; \
+ MULHDU r0, h0, t1; \
+ MULLD r0, h1, t4; \
+ MULHDU r0, h1, t5; \
+ ADDC t4, t1, t1; \
+ MULLD r0, h2, t2; \
+ MULHDU r1, h0, t4; \
+ MULLD r1, h0, h0; \
+ ADDE t5, t2, t2; \
+ ADDC h0, t1, t1; \
+ MULLD h2, r1, t3; \
+ ADDZE t4, h0; \
+ MULHDU r1, h1, t5; \
+ MULLD r1, h1, t4; \
+ ADDC t4, t2, t2; \
+ ADDE t5, t3, t3; \
+ ADDC h0, t2, t2; \
+ MOVD $-4, t4; \
+ ADDZE t3; \
+ RLDICL $0, t2, $62, h2; \
+ AND t2, t4, h0; \
+ ADDC t0, h0, h0; \
+ ADDE t3, t1, h1; \
+ SLD $62, t3, t4; \
+ SRD $2, t2; \
+ ADDZE h2; \
+ OR t4, t2, t2; \
+ SRD $2, t3; \
+ ADDC t2, h0, h0; \
+ ADDE t3, h1, h1; \
+ ADDZE h2
+
+DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
+DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
+GLOBL ·poly1305Mask<>(SB), RODATA, $16
+
+// func update(state *[7]uint64, msg []byte)
+TEXT ·update(SB), $0-32
+ MOVD state+0(FP), R3
+ MOVD msg_base+8(FP), R4
+ MOVD msg_len+16(FP), R5
+
+ MOVD 0(R3), R8 // h0
+ MOVD 8(R3), R9 // h1
+ MOVD 16(R3), R10 // h2
+ MOVD 24(R3), R11 // r0
+ MOVD 32(R3), R12 // r1
+
+ CMP R5, $16
+ BLT bytes_between_0_and_15
+
+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
+ CMP R5, $16
+ BGE loop
+
+bytes_between_0_and_15:
+ CMP R5, $0
+ BEQ done
+ MOVD $0, R16 // h0
+ MOVD $0, R17 // h1
+
+flush_buffer:
+ CMP R5, $8
+ BLE just1
+
+ MOVD $8, R21
+ SUB R21, R5, R21
+
+ // Greater than 8 -- load the rightmost remaining bytes in msg
+ // and put into R17 (h1)
+ MOVD (R4)(R21), R17
+ MOVD $16, R22
+
+ // Find the offset to those bytes
+ SUB R5, R22, R22
+ SLD $3, R22
+
+ // Shift to get only the bytes in msg
+ SRD R22, R17, R17
+
+ // Put 1 at high end
+ MOVD $1, R23
+ SLD $3, R21
+ SLD R21, R23, R23
+ OR R23, R17, R17
+
+ // Remainder is 8
+ MOVD $8, R5
+
+just1:
+ CMP R5, $8
+ BLT less8
+
+ // Exactly 8
+ MOVD (R4), R16
+
+ CMP R17, $0
+
+ // Check if we've already set R17; if not
+ // set 1 to indicate end of msg.
+ BNE carry
+ MOVD $1, R17
+ BR carry
+
+less8:
+ MOVD $0, R16 // h0
+ MOVD $0, R22 // shift count
+ CMP R5, $4
+ BLT less4
+ MOVWZ (R4), R16
+ ADD $4, R4
+ ADD $-4, R5
+ MOVD $32, R22
+
+less4:
+ CMP R5, $2
+ BLT less2
+ MOVHZ (R4), R21
+ SLD R22, R21, R21
+ OR R16, R21, R16
+ ADD $16, R22
+ ADD $-2, R5
+ ADD $2, R4
+
+less2:
+ CMP R5, $0
+ BEQ insert1
+ MOVBZ (R4), R21
+ SLD R22, R21, R21
+ OR R16, R21, R16
+ ADD $8, R22
+
+insert1:
+ // Insert 1 at end of msg
+ MOVD $1, R21
+ SLD R22, R21, R21
+ OR R16, R21, R16
+
+carry:
+ // Add new values to h0, h1, h2
+ ADDC R16, R8
+ ADDE R17, R9
+ ADDZE R10, R10
+ MOVD $16, R5
+ ADD R5, R4
+ BR multiply
+
+done:
+ // Save h0, h1, h2 in state
+ MOVD R8, 0(R3)
+ MOVD R9, 8(R3)
+ MOVD R10, 16(R3)
+ RET
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go
new file mode 100644
index 00000000..e1d033a4
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go
@@ -0,0 +1,76 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+package poly1305
+
+import (
+ "golang.org/x/sys/cpu"
+)
+
+// updateVX is an assembly implementation of Poly1305 that uses vector
+// instructions. It must only be called if the vector facility (vx) is
+// available.
+//
+//go:noescape
+func updateVX(state *macState, msg []byte)
+
+// mac is a replacement for macGeneric that uses a larger buffer and redirects
+// calls that would have gone to updateGeneric to updateVX if the vector
+// facility is installed.
+//
+// A larger buffer is required for good performance because the vector
+// implementation has a higher fixed cost per call than the generic
+// implementation.
+type mac struct {
+ macState
+
+ buffer [16 * TagSize]byte // size must be a multiple of block size (16)
+ offset int
+}
+
+func (h *mac) Write(p []byte) (int, error) {
+ nn := len(p)
+ if h.offset > 0 {
+ n := copy(h.buffer[h.offset:], p)
+ if h.offset+n < len(h.buffer) {
+ h.offset += n
+ return nn, nil
+ }
+ p = p[n:]
+ h.offset = 0
+ if cpu.S390X.HasVX {
+ updateVX(&h.macState, h.buffer[:])
+ } else {
+ updateGeneric(&h.macState, h.buffer[:])
+ }
+ }
+
+ tail := len(p) % len(h.buffer) // number of bytes to copy into buffer
+ body := len(p) - tail // number of bytes to process now
+ if body > 0 {
+ if cpu.S390X.HasVX {
+ updateVX(&h.macState, p[:body])
+ } else {
+ updateGeneric(&h.macState, p[:body])
+ }
+ }
+ h.offset = copy(h.buffer[:], p[body:]) // copy tail bytes - can be 0
+ return nn, nil
+}
+
+func (h *mac) Sum(out *[TagSize]byte) {
+ state := h.macState
+ remainder := h.buffer[:h.offset]
+
+ // Use the generic implementation if we have 2 or fewer blocks left
+ // to sum. The vector implementation has a higher startup time.
+ if cpu.S390X.HasVX && len(remainder) > 2*TagSize {
+ updateVX(&state, remainder)
+ } else if len(remainder) > 0 {
+ updateGeneric(&state, remainder)
+ }
+ finalize(out, &state.h, &state.s)
+}
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s
new file mode 100644
index 00000000..0fe3a7c2
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s
@@ -0,0 +1,503 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+#include "textflag.h"
+
+// This implementation of Poly1305 uses the vector facility (vx)
+// to process up to 2 blocks (32 bytes) per iteration using an
+// algorithm based on the one described in:
+//
+// NEON crypto, Daniel J. Bernstein & Peter Schwabe
+// https://cryptojedi.org/papers/neoncrypto-20120320.pdf
+//
+// This algorithm uses 5 26-bit limbs to represent a 130-bit
+// value. These limbs are, for the most part, zero extended and
+// placed into 64-bit vector register elements. Each vector
+// register is 128-bits wide and so holds 2 of these elements.
+// Using 26-bit limbs allows us plenty of headroom to accommodate
+// accumulations before and after multiplication without
+// overflowing either 32-bits (before multiplication) or 64-bits
+// (after multiplication).
+//
+// In order to parallelise the operations required to calculate
+// the sum we use two separate accumulators and then sum those
+// in an extra final step. For compatibility with the generic
+// implementation we perform this summation at the end of every
+// updateVX call.
+//
+// To use two accumulators we must multiply the message blocks
+// by r² rather than r. Only the final message block should be
+// multiplied by r.
+//
+// Example:
+//
+// We want to calculate the sum (h) for a 64 byte message (m):
+//
+// h = m[0:16]r⁴ + m[16:32]r³ + m[32:48]r² + m[48:64]r
+//
+// To do this we split the calculation into the even indices
+// and odd indices of the message. These form our SIMD 'lanes':
+//
+// h = m[ 0:16]r⁴ + m[32:48]r² + <- lane 0
+// m[16:32]r³ + m[48:64]r <- lane 1
+//
+// To calculate this iteratively we refactor so that both lanes
+// are written in terms of r² and r:
+//
+// h = (m[ 0:16]r² + m[32:48])r² + <- lane 0
+// (m[16:32]r² + m[48:64])r <- lane 1
+// ^ ^
+// | coefficients for second iteration
+// coefficients for first iteration
+//
+// So in this case we would have two iterations. In the first
+// both lanes are multiplied by r². In the second only the
+// first lane is multiplied by r² and the second lane is
+// instead multiplied by r. This gives use the odd and even
+// powers of r that we need from the original equation.
+//
+// Notation:
+//
+// h - accumulator
+// r - key
+// m - message
+//
+// [a, b] - SIMD register holding two 64-bit values
+// [a, b, c, d] - SIMD register holding four 32-bit values
+// xᵢ[n] - limb n of variable x with bit width i
+//
+// Limbs are expressed in little endian order, so for 26-bit
+// limbs x₂₆[4] will be the most significant limb and x₂₆[0]
+// will be the least significant limb.
+
+// masking constants
+#define MOD24 V0 // [0x0000000000ffffff, 0x0000000000ffffff] - mask low 24-bits
+#define MOD26 V1 // [0x0000000003ffffff, 0x0000000003ffffff] - mask low 26-bits
+
+// expansion constants (see EXPAND macro)
+#define EX0 V2
+#define EX1 V3
+#define EX2 V4
+
+// key (r², r or 1 depending on context)
+#define R_0 V5
+#define R_1 V6
+#define R_2 V7
+#define R_3 V8
+#define R_4 V9
+
+// precalculated coefficients (5r², 5r or 0 depending on context)
+#define R5_1 V10
+#define R5_2 V11
+#define R5_3 V12
+#define R5_4 V13
+
+// message block (m)
+#define M_0 V14
+#define M_1 V15
+#define M_2 V16
+#define M_3 V17
+#define M_4 V18
+
+// accumulator (h)
+#define H_0 V19
+#define H_1 V20
+#define H_2 V21
+#define H_3 V22
+#define H_4 V23
+
+// temporary registers (for short-lived values)
+#define T_0 V24
+#define T_1 V25
+#define T_2 V26
+#define T_3 V27
+#define T_4 V28
+
+GLOBL ·constants<>(SB), RODATA, $0x30
+// EX0
+DATA ·constants<>+0x00(SB)/8, $0x0006050403020100
+DATA ·constants<>+0x08(SB)/8, $0x1016151413121110
+// EX1
+DATA ·constants<>+0x10(SB)/8, $0x060c0b0a09080706
+DATA ·constants<>+0x18(SB)/8, $0x161c1b1a19181716
+// EX2
+DATA ·constants<>+0x20(SB)/8, $0x0d0d0d0d0d0f0e0d
+DATA ·constants<>+0x28(SB)/8, $0x1d1d1d1d1d1f1e1d
+
+// MULTIPLY multiplies each lane of f and g, partially reduced
+// modulo 2¹³⁰ - 5. The result, h, consists of partial products
+// in each lane that need to be reduced further to produce the
+// final result.
+//
+// h₁₃₀ = (f₁₃₀g₁₃₀) % 2¹³⁰ + (5f₁₃₀g₁₃₀) / 2¹³⁰
+//
+// Note that the multiplication by 5 of the high bits is
+// achieved by precalculating the multiplication of four of the
+// g coefficients by 5. These are g51-g54.
+#define MULTIPLY(f0, f1, f2, f3, f4, g0, g1, g2, g3, g4, g51, g52, g53, g54, h0, h1, h2, h3, h4) \
+ VMLOF f0, g0, h0 \
+ VMLOF f0, g3, h3 \
+ VMLOF f0, g1, h1 \
+ VMLOF f0, g4, h4 \
+ VMLOF f0, g2, h2 \
+ VMLOF f1, g54, T_0 \
+ VMLOF f1, g2, T_3 \
+ VMLOF f1, g0, T_1 \
+ VMLOF f1, g3, T_4 \
+ VMLOF f1, g1, T_2 \
+ VMALOF f2, g53, h0, h0 \
+ VMALOF f2, g1, h3, h3 \
+ VMALOF f2, g54, h1, h1 \
+ VMALOF f2, g2, h4, h4 \
+ VMALOF f2, g0, h2, h2 \
+ VMALOF f3, g52, T_0, T_0 \
+ VMALOF f3, g0, T_3, T_3 \
+ VMALOF f3, g53, T_1, T_1 \
+ VMALOF f3, g1, T_4, T_4 \
+ VMALOF f3, g54, T_2, T_2 \
+ VMALOF f4, g51, h0, h0 \
+ VMALOF f4, g54, h3, h3 \
+ VMALOF f4, g52, h1, h1 \
+ VMALOF f4, g0, h4, h4 \
+ VMALOF f4, g53, h2, h2 \
+ VAG T_0, h0, h0 \
+ VAG T_3, h3, h3 \
+ VAG T_1, h1, h1 \
+ VAG T_4, h4, h4 \
+ VAG T_2, h2, h2
+
+// REDUCE performs the following carry operations in four
+// stages, as specified in Bernstein & Schwabe:
+//
+// 1: h₂₆[0]->h₂₆[1] h₂₆[3]->h₂₆[4]
+// 2: h₂₆[1]->h₂₆[2] h₂₆[4]->h₂₆[0]
+// 3: h₂₆[0]->h₂₆[1] h₂₆[2]->h₂₆[3]
+// 4: h₂₆[3]->h₂₆[4]
+//
+// The result is that all of the limbs are limited to 26-bits
+// except for h₂₆[1] and h₂₆[4] which are limited to 27-bits.
+//
+// Note that although each limb is aligned at 26-bit intervals
+// they may contain values that exceed 2²⁶ - 1, hence the need
+// to carry the excess bits in each limb.
+#define REDUCE(h0, h1, h2, h3, h4) \
+ VESRLG $26, h0, T_0 \
+ VESRLG $26, h3, T_1 \
+ VN MOD26, h0, h0 \
+ VN MOD26, h3, h3 \
+ VAG T_0, h1, h1 \
+ VAG T_1, h4, h4 \
+ VESRLG $26, h1, T_2 \
+ VESRLG $26, h4, T_3 \
+ VN MOD26, h1, h1 \
+ VN MOD26, h4, h4 \
+ VESLG $2, T_3, T_4 \
+ VAG T_3, T_4, T_4 \
+ VAG T_2, h2, h2 \
+ VAG T_4, h0, h0 \
+ VESRLG $26, h2, T_0 \
+ VESRLG $26, h0, T_1 \
+ VN MOD26, h2, h2 \
+ VN MOD26, h0, h0 \
+ VAG T_0, h3, h3 \
+ VAG T_1, h1, h1 \
+ VESRLG $26, h3, T_2 \
+ VN MOD26, h3, h3 \
+ VAG T_2, h4, h4
+
+// EXPAND splits the 128-bit little-endian values in0 and in1
+// into 26-bit big-endian limbs and places the results into
+// the first and second lane of d₂₆[0:4] respectively.
+//
+// The EX0, EX1 and EX2 constants are arrays of byte indices
+// for permutation. The permutation both reverses the bytes
+// in the input and ensures the bytes are copied into the
+// destination limb ready to be shifted into their final
+// position.
+#define EXPAND(in0, in1, d0, d1, d2, d3, d4) \
+ VPERM in0, in1, EX0, d0 \
+ VPERM in0, in1, EX1, d2 \
+ VPERM in0, in1, EX2, d4 \
+ VESRLG $26, d0, d1 \
+ VESRLG $30, d2, d3 \
+ VESRLG $4, d2, d2 \
+ VN MOD26, d0, d0 \ // [in0₂₆[0], in1₂₆[0]]
+ VN MOD26, d3, d3 \ // [in0₂₆[3], in1₂₆[3]]
+ VN MOD26, d1, d1 \ // [in0₂₆[1], in1₂₆[1]]
+ VN MOD24, d4, d4 \ // [in0₂₆[4], in1₂₆[4]]
+ VN MOD26, d2, d2 // [in0₂₆[2], in1₂₆[2]]
+
+// func updateVX(state *macState, msg []byte)
+TEXT ·updateVX(SB), NOSPLIT, $0
+ MOVD state+0(FP), R1
+ LMG msg+8(FP), R2, R3 // R2=msg_base, R3=msg_len
+
+ // load EX0, EX1 and EX2
+ MOVD $·constants<>(SB), R5
+ VLM (R5), EX0, EX2
+
+ // generate masks
+ VGMG $(64-24), $63, MOD24 // [0x00ffffff, 0x00ffffff]
+ VGMG $(64-26), $63, MOD26 // [0x03ffffff, 0x03ffffff]
+
+ // load h (accumulator) and r (key) from state
+ VZERO T_1 // [0, 0]
+ VL 0(R1), T_0 // [h₆₄[0], h₆₄[1]]
+ VLEG $0, 16(R1), T_1 // [h₆₄[2], 0]
+ VL 24(R1), T_2 // [r₆₄[0], r₆₄[1]]
+ VPDI $0, T_0, T_2, T_3 // [h₆₄[0], r₆₄[0]]
+ VPDI $5, T_0, T_2, T_4 // [h₆₄[1], r₆₄[1]]
+
+ // unpack h and r into 26-bit limbs
+ // note: h₆₄[2] may have the low 3 bits set, so h₂₆[4] is a 27-bit value
+ VN MOD26, T_3, H_0 // [h₂₆[0], r₂₆[0]]
+ VZERO H_1 // [0, 0]
+ VZERO H_3 // [0, 0]
+ VGMG $(64-12-14), $(63-12), T_0 // [0x03fff000, 0x03fff000] - 26-bit mask with low 12 bits masked out
+ VESLG $24, T_1, T_1 // [h₆₄[2]<<24, 0]
+ VERIMG $-26&63, T_3, MOD26, H_1 // [h₂₆[1], r₂₆[1]]
+ VESRLG $+52&63, T_3, H_2 // [h₂₆[2], r₂₆[2]] - low 12 bits only
+ VERIMG $-14&63, T_4, MOD26, H_3 // [h₂₆[1], r₂₆[1]]
+ VESRLG $40, T_4, H_4 // [h₂₆[4], r₂₆[4]] - low 24 bits only
+ VERIMG $+12&63, T_4, T_0, H_2 // [h₂₆[2], r₂₆[2]] - complete
+ VO T_1, H_4, H_4 // [h₂₆[4], r₂₆[4]] - complete
+
+ // replicate r across all 4 vector elements
+ VREPF $3, H_0, R_0 // [r₂₆[0], r₂₆[0], r₂₆[0], r₂₆[0]]
+ VREPF $3, H_1, R_1 // [r₂₆[1], r₂₆[1], r₂₆[1], r₂₆[1]]
+ VREPF $3, H_2, R_2 // [r₂₆[2], r₂₆[2], r₂₆[2], r₂₆[2]]
+ VREPF $3, H_3, R_3 // [r₂₆[3], r₂₆[3], r₂₆[3], r₂₆[3]]
+ VREPF $3, H_4, R_4 // [r₂₆[4], r₂₆[4], r₂₆[4], r₂₆[4]]
+
+ // zero out lane 1 of h
+ VLEIG $1, $0, H_0 // [h₂₆[0], 0]
+ VLEIG $1, $0, H_1 // [h₂₆[1], 0]
+ VLEIG $1, $0, H_2 // [h₂₆[2], 0]
+ VLEIG $1, $0, H_3 // [h₂₆[3], 0]
+ VLEIG $1, $0, H_4 // [h₂₆[4], 0]
+
+ // calculate 5r (ignore least significant limb)
+ VREPIF $5, T_0
+ VMLF T_0, R_1, R5_1 // [5r₂₆[1], 5r₂₆[1], 5r₂₆[1], 5r₂₆[1]]
+ VMLF T_0, R_2, R5_2 // [5r₂₆[2], 5r₂₆[2], 5r₂₆[2], 5r₂₆[2]]
+ VMLF T_0, R_3, R5_3 // [5r₂₆[3], 5r₂₆[3], 5r₂₆[3], 5r₂₆[3]]
+ VMLF T_0, R_4, R5_4 // [5r₂₆[4], 5r₂₆[4], 5r₂₆[4], 5r₂₆[4]]
+
+ // skip r² calculation if we are only calculating one block
+ CMPBLE R3, $16, skip
+
+ // calculate r²
+ MULTIPLY(R_0, R_1, R_2, R_3, R_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, M_0, M_1, M_2, M_3, M_4)
+ REDUCE(M_0, M_1, M_2, M_3, M_4)
+ VGBM $0x0f0f, T_0
+ VERIMG $0, M_0, T_0, R_0 // [r₂₆[0], r²₂₆[0], r₂₆[0], r²₂₆[0]]
+ VERIMG $0, M_1, T_0, R_1 // [r₂₆[1], r²₂₆[1], r₂₆[1], r²₂₆[1]]
+ VERIMG $0, M_2, T_0, R_2 // [r₂₆[2], r²₂₆[2], r₂₆[2], r²₂₆[2]]
+ VERIMG $0, M_3, T_0, R_3 // [r₂₆[3], r²₂₆[3], r₂₆[3], r²₂₆[3]]
+ VERIMG $0, M_4, T_0, R_4 // [r₂₆[4], r²₂₆[4], r₂₆[4], r²₂₆[4]]
+
+ // calculate 5r² (ignore least significant limb)
+ VREPIF $5, T_0
+ VMLF T_0, R_1, R5_1 // [5r₂₆[1], 5r²₂₆[1], 5r₂₆[1], 5r²₂₆[1]]
+ VMLF T_0, R_2, R5_2 // [5r₂₆[2], 5r²₂₆[2], 5r₂₆[2], 5r²₂₆[2]]
+ VMLF T_0, R_3, R5_3 // [5r₂₆[3], 5r²₂₆[3], 5r₂₆[3], 5r²₂₆[3]]
+ VMLF T_0, R_4, R5_4 // [5r₂₆[4], 5r²₂₆[4], 5r₂₆[4], 5r²₂₆[4]]
+
+loop:
+ CMPBLE R3, $32, b2 // 2 or fewer blocks remaining, need to change key coefficients
+
+ // load next 2 blocks from message
+ VLM (R2), T_0, T_1
+
+ // update message slice
+ SUB $32, R3
+ MOVD $32(R2), R2
+
+ // unpack message blocks into 26-bit big-endian limbs
+ EXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4)
+
+ // add 2¹²⁸ to each message block value
+ VLEIB $4, $1, M_4
+ VLEIB $12, $1, M_4
+
+multiply:
+ // accumulate the incoming message
+ VAG H_0, M_0, M_0
+ VAG H_3, M_3, M_3
+ VAG H_1, M_1, M_1
+ VAG H_4, M_4, M_4
+ VAG H_2, M_2, M_2
+
+ // multiply the accumulator by the key coefficient
+ MULTIPLY(M_0, M_1, M_2, M_3, M_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, H_0, H_1, H_2, H_3, H_4)
+
+ // carry and partially reduce the partial products
+ REDUCE(H_0, H_1, H_2, H_3, H_4)
+
+ CMPBNE R3, $0, loop
+
+finish:
+ // sum lane 0 and lane 1 and put the result in lane 1
+ VZERO T_0
+ VSUMQG H_0, T_0, H_0
+ VSUMQG H_3, T_0, H_3
+ VSUMQG H_1, T_0, H_1
+ VSUMQG H_4, T_0, H_4
+ VSUMQG H_2, T_0, H_2
+
+ // reduce again after summation
+ // TODO(mundaym): there might be a more efficient way to do this
+ // now that we only have 1 active lane. For example, we could
+ // simultaneously pack the values as we reduce them.
+ REDUCE(H_0, H_1, H_2, H_3, H_4)
+
+ // carry h[1] through to h[4] so that only h[4] can exceed 2²⁶ - 1
+ // TODO(mundaym): in testing this final carry was unnecessary.
+ // Needs a proof before it can be removed though.
+ VESRLG $26, H_1, T_1
+ VN MOD26, H_1, H_1
+ VAQ T_1, H_2, H_2
+ VESRLG $26, H_2, T_2
+ VN MOD26, H_2, H_2
+ VAQ T_2, H_3, H_3
+ VESRLG $26, H_3, T_3
+ VN MOD26, H_3, H_3
+ VAQ T_3, H_4, H_4
+
+ // h is now < 2(2¹³⁰ - 5)
+ // Pack each lane in h₂₆[0:4] into h₁₂₈[0:1].
+ VESLG $26, H_1, H_1
+ VESLG $26, H_3, H_3
+ VO H_0, H_1, H_0
+ VO H_2, H_3, H_2
+ VESLG $4, H_2, H_2
+ VLEIB $7, $48, H_1
+ VSLB H_1, H_2, H_2
+ VO H_0, H_2, H_0
+ VLEIB $7, $104, H_1
+ VSLB H_1, H_4, H_3
+ VO H_3, H_0, H_0
+ VLEIB $7, $24, H_1
+ VSRLB H_1, H_4, H_1
+
+ // update state
+ VSTEG $1, H_0, 0(R1)
+ VSTEG $0, H_0, 8(R1)
+ VSTEG $1, H_1, 16(R1)
+ RET
+
+b2: // 2 or fewer blocks remaining
+ CMPBLE R3, $16, b1
+
+ // Load the 2 remaining blocks (17-32 bytes remaining).
+ MOVD $-17(R3), R0 // index of final byte to load modulo 16
+ VL (R2), T_0 // load full 16 byte block
+ VLL R0, 16(R2), T_1 // load final (possibly partial) block and pad with zeros to 16 bytes
+
+ // The Poly1305 algorithm requires that a 1 bit be appended to
+ // each message block. If the final block is less than 16 bytes
+ // long then it is easiest to insert the 1 before the message
+ // block is split into 26-bit limbs. If, on the other hand, the
+ // final message block is 16 bytes long then we append the 1 bit
+ // after expansion as normal.
+ MOVBZ $1, R0
+ MOVD $-16(R3), R3 // index of byte in last block to insert 1 at (could be 16)
+ CMPBEQ R3, $16, 2(PC) // skip the insertion if the final block is 16 bytes long
+ VLVGB R3, R0, T_1 // insert 1 into the byte at index R3
+
+ // Split both blocks into 26-bit limbs in the appropriate lanes.
+ EXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4)
+
+ // Append a 1 byte to the end of the second to last block.
+ VLEIB $4, $1, M_4
+
+ // Append a 1 byte to the end of the last block only if it is a
+ // full 16 byte block.
+ CMPBNE R3, $16, 2(PC)
+ VLEIB $12, $1, M_4
+
+ // Finally, set up the coefficients for the final multiplication.
+ // We have previously saved r and 5r in the 32-bit even indexes
+ // of the R_[0-4] and R5_[1-4] coefficient registers.
+ //
+ // We want lane 0 to be multiplied by r² so that can be kept the
+ // same. We want lane 1 to be multiplied by r so we need to move
+ // the saved r value into the 32-bit odd index in lane 1 by
+ // rotating the 64-bit lane by 32.
+ VGBM $0x00ff, T_0 // [0, 0xffffffffffffffff] - mask lane 1 only
+ VERIMG $32, R_0, T_0, R_0 // [_, r²₂₆[0], _, r₂₆[0]]
+ VERIMG $32, R_1, T_0, R_1 // [_, r²₂₆[1], _, r₂₆[1]]
+ VERIMG $32, R_2, T_0, R_2 // [_, r²₂₆[2], _, r₂₆[2]]
+ VERIMG $32, R_3, T_0, R_3 // [_, r²₂₆[3], _, r₂₆[3]]
+ VERIMG $32, R_4, T_0, R_4 // [_, r²₂₆[4], _, r₂₆[4]]
+ VERIMG $32, R5_1, T_0, R5_1 // [_, 5r²₂₆[1], _, 5r₂₆[1]]
+ VERIMG $32, R5_2, T_0, R5_2 // [_, 5r²₂₆[2], _, 5r₂₆[2]]
+ VERIMG $32, R5_3, T_0, R5_3 // [_, 5r²₂₆[3], _, 5r₂₆[3]]
+ VERIMG $32, R5_4, T_0, R5_4 // [_, 5r²₂₆[4], _, 5r₂₆[4]]
+
+ MOVD $0, R3
+ BR multiply
+
+skip:
+ CMPBEQ R3, $0, finish
+
+b1: // 1 block remaining
+
+ // Load the final block (1-16 bytes). This will be placed into
+ // lane 0.
+ MOVD $-1(R3), R0
+ VLL R0, (R2), T_0 // pad to 16 bytes with zeros
+
+ // The Poly1305 algorithm requires that a 1 bit be appended to
+ // each message block. If the final block is less than 16 bytes
+ // long then it is easiest to insert the 1 before the message
+ // block is split into 26-bit limbs. If, on the other hand, the
+ // final message block is 16 bytes long then we append the 1 bit
+ // after expansion as normal.
+ MOVBZ $1, R0
+ CMPBEQ R3, $16, 2(PC)
+ VLVGB R3, R0, T_0
+
+ // Set the message block in lane 1 to the value 0 so that it
+ // can be accumulated without affecting the final result.
+ VZERO T_1
+
+ // Split the final message block into 26-bit limbs in lane 0.
+ // Lane 1 will be contain 0.
+ EXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4)
+
+ // Append a 1 byte to the end of the last block only if it is a
+ // full 16 byte block.
+ CMPBNE R3, $16, 2(PC)
+ VLEIB $4, $1, M_4
+
+ // We have previously saved r and 5r in the 32-bit even indexes
+ // of the R_[0-4] and R5_[1-4] coefficient registers.
+ //
+ // We want lane 0 to be multiplied by r so we need to move the
+ // saved r value into the 32-bit odd index in lane 0. We want
+ // lane 1 to be set to the value 1. This makes multiplication
+ // a no-op. We do this by setting lane 1 in every register to 0
+ // and then just setting the 32-bit index 3 in R_0 to 1.
+ VZERO T_0
+ MOVD $0, R0
+ MOVD $0x10111213, R12
+ VLVGP R12, R0, T_1 // [_, 0x10111213, _, 0x00000000]
+ VPERM T_0, R_0, T_1, R_0 // [_, r₂₆[0], _, 0]
+ VPERM T_0, R_1, T_1, R_1 // [_, r₂₆[1], _, 0]
+ VPERM T_0, R_2, T_1, R_2 // [_, r₂₆[2], _, 0]
+ VPERM T_0, R_3, T_1, R_3 // [_, r₂₆[3], _, 0]
+ VPERM T_0, R_4, T_1, R_4 // [_, r₂₆[4], _, 0]
+ VPERM T_0, R5_1, T_1, R5_1 // [_, 5r₂₆[1], _, 0]
+ VPERM T_0, R5_2, T_1, R5_2 // [_, 5r₂₆[2], _, 0]
+ VPERM T_0, R5_3, T_1, R5_3 // [_, 5r₂₆[3], _, 0]
+ VPERM T_0, R5_4, T_1, R5_4 // [_, 5r₂₆[4], _, 0]
+
+ // Set the value of lane 1 to be 1.
+ VLEIF $3, $1, R_0 // [_, r₂₆[0], _, 1]
+
+ MOVD $0, R3
+ BR multiply
diff --git a/vendor/golang.org/x/crypto/sha3/doc.go b/vendor/golang.org/x/crypto/sha3/doc.go
new file mode 100644
index 00000000..7e023090
--- /dev/null
+++ b/vendor/golang.org/x/crypto/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/golang.org/x/crypto/sha3/hashes.go b/vendor/golang.org/x/crypto/sha3/hashes.go
new file mode 100644
index 00000000..c544b29e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/hashes.go
@@ -0,0 +1,109 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file provides functions for creating instances of the SHA-3
+// and SHAKE hash functions, as well as utility functions for hashing
+// bytes.
+
+import (
+ "crypto"
+ "hash"
+)
+
+// New224 creates a new SHA3-224 hash.
+// Its generic security strength is 224 bits against preimage attacks,
+// and 112 bits against collision attacks.
+func New224() hash.Hash {
+ return 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 {
+ 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 {
+ 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 {
+ 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}
+}
+
+// NewLegacyKeccak256 creates a new Keccak-256 hash.
+//
+// Only use this function if you require compatibility with an existing cryptosystem
+// that uses non-standard padding. All other users should use New256 instead.
+func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} }
+
+// NewLegacyKeccak512 creates a new Keccak-512 hash.
+//
+// Only use this function if you require compatibility with an existing cryptosystem
+// that uses non-standard padding. All other users should use New512 instead.
+func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x01} }
+
+// Sum224 returns the SHA3-224 digest of the data.
+func Sum224(data []byte) (digest [28]byte) {
+ h := New224()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum256 returns the SHA3-256 digest of the data.
+func Sum256(data []byte) (digest [32]byte) {
+ h := New256()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum384 returns the SHA3-384 digest of the data.
+func Sum384(data []byte) (digest [48]byte) {
+ h := New384()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum512 returns the SHA3-512 digest of the data.
+func Sum512(data []byte) (digest [64]byte) {
+ h := New512()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
diff --git a/vendor/golang.org/x/crypto/sha3/hashes_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/keccakf.go b/vendor/golang.org/x/crypto/sha3/keccakf.go
new file mode 100644
index 00000000..ce48b1dd
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/keccakf.go
@@ -0,0 +1,414 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || purego || !gc
+
+package sha3
+
+import "math/bits"
+
+// rc stores the round constants for use in the ι step.
+var rc = [24]uint64{
+ 0x0000000000000001,
+ 0x0000000000008082,
+ 0x800000000000808A,
+ 0x8000000080008000,
+ 0x000000000000808B,
+ 0x0000000080000001,
+ 0x8000000080008081,
+ 0x8000000000008009,
+ 0x000000000000008A,
+ 0x0000000000000088,
+ 0x0000000080008009,
+ 0x000000008000000A,
+ 0x000000008000808B,
+ 0x800000000000008B,
+ 0x8000000000008089,
+ 0x8000000000008003,
+ 0x8000000000008002,
+ 0x8000000000000080,
+ 0x000000000000800A,
+ 0x800000008000000A,
+ 0x8000000080008081,
+ 0x8000000000008080,
+ 0x0000000080000001,
+ 0x8000000080008008,
+}
+
+// keccakF1600 applies the Keccak permutation to a 1600b-wide
+// state represented as a slice of 25 uint64s.
+func keccakF1600(a *[25]uint64) {
+ // Implementation translated from Keccak-inplace.c
+ // in the keccak reference code.
+ var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64
+
+ for i := 0; i < 24; i += 4 {
+ // Combines the 5 steps in each round into 2 steps.
+ // Unrolls 4 rounds per loop and spreads some steps across rounds.
+
+ // Round 1
+ bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+ bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+ bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+ bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+ bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+ d0 = bc4 ^ (bc1<<1 | bc1>>63)
+ d1 = bc0 ^ (bc2<<1 | bc2>>63)
+ d2 = bc1 ^ (bc3<<1 | bc3>>63)
+ d3 = bc2 ^ (bc4<<1 | bc4>>63)
+ d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+ bc0 = a[0] ^ d0
+ t = a[6] ^ d1
+ bc1 = bits.RotateLeft64(t, 44)
+ t = a[12] ^ d2
+ bc2 = bits.RotateLeft64(t, 43)
+ t = a[18] ^ d3
+ bc3 = bits.RotateLeft64(t, 21)
+ t = a[24] ^ d4
+ bc4 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 3)
+ t = a[16] ^ d1
+ bc3 = bits.RotateLeft64(t, 45)
+ t = a[22] ^ d2
+ bc4 = bits.RotateLeft64(t, 61)
+ t = a[3] ^ d3
+ bc0 = bits.RotateLeft64(t, 28)
+ t = a[9] ^ d4
+ bc1 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 18)
+ t = a[1] ^ d1
+ bc0 = bits.RotateLeft64(t, 1)
+ t = a[7] ^ d2
+ bc1 = bits.RotateLeft64(t, 6)
+ t = a[13] ^ d3
+ bc2 = bits.RotateLeft64(t, 25)
+ t = a[19] ^ d4
+ bc3 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 36)
+ t = a[11] ^ d1
+ bc2 = bits.RotateLeft64(t, 10)
+ t = a[17] ^ d2
+ bc3 = bits.RotateLeft64(t, 15)
+ t = a[23] ^ d3
+ bc4 = bits.RotateLeft64(t, 56)
+ t = a[4] ^ d4
+ bc0 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 41)
+ t = a[21] ^ d1
+ bc4 = bits.RotateLeft64(t, 2)
+ t = a[2] ^ d2
+ bc0 = bits.RotateLeft64(t, 62)
+ t = a[8] ^ d3
+ bc1 = bits.RotateLeft64(t, 55)
+ t = a[14] ^ d4
+ bc2 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 44)
+ t = a[7] ^ d2
+ bc2 = bits.RotateLeft64(t, 43)
+ t = a[23] ^ d3
+ bc3 = bits.RotateLeft64(t, 21)
+ t = a[14] ^ d4
+ bc4 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 3)
+ t = a[11] ^ d1
+ bc3 = bits.RotateLeft64(t, 45)
+ t = a[2] ^ d2
+ bc4 = bits.RotateLeft64(t, 61)
+ t = a[18] ^ d3
+ bc0 = bits.RotateLeft64(t, 28)
+ t = a[9] ^ d4
+ bc1 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 18)
+ t = a[6] ^ d1
+ bc0 = bits.RotateLeft64(t, 1)
+ t = a[22] ^ d2
+ bc1 = bits.RotateLeft64(t, 6)
+ t = a[13] ^ d3
+ bc2 = bits.RotateLeft64(t, 25)
+ t = a[4] ^ d4
+ bc3 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 36)
+ t = a[1] ^ d1
+ bc2 = bits.RotateLeft64(t, 10)
+ t = a[17] ^ d2
+ bc3 = bits.RotateLeft64(t, 15)
+ t = a[8] ^ d3
+ bc4 = bits.RotateLeft64(t, 56)
+ t = a[24] ^ d4
+ bc0 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 41)
+ t = a[21] ^ d1
+ bc4 = bits.RotateLeft64(t, 2)
+ t = a[12] ^ d2
+ bc0 = bits.RotateLeft64(t, 62)
+ t = a[3] ^ d3
+ bc1 = bits.RotateLeft64(t, 55)
+ t = a[19] ^ d4
+ bc2 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 44)
+ t = a[22] ^ d2
+ bc2 = bits.RotateLeft64(t, 43)
+ t = a[8] ^ d3
+ bc3 = bits.RotateLeft64(t, 21)
+ t = a[19] ^ d4
+ bc4 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 3)
+ t = a[1] ^ d1
+ bc3 = bits.RotateLeft64(t, 45)
+ t = a[12] ^ d2
+ bc4 = bits.RotateLeft64(t, 61)
+ t = a[23] ^ d3
+ bc0 = bits.RotateLeft64(t, 28)
+ t = a[9] ^ d4
+ bc1 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 18)
+ t = a[16] ^ d1
+ bc0 = bits.RotateLeft64(t, 1)
+ t = a[2] ^ d2
+ bc1 = bits.RotateLeft64(t, 6)
+ t = a[13] ^ d3
+ bc2 = bits.RotateLeft64(t, 25)
+ t = a[24] ^ d4
+ bc3 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 36)
+ t = a[6] ^ d1
+ bc2 = bits.RotateLeft64(t, 10)
+ t = a[17] ^ d2
+ bc3 = bits.RotateLeft64(t, 15)
+ t = a[3] ^ d3
+ bc4 = bits.RotateLeft64(t, 56)
+ t = a[14] ^ d4
+ bc0 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 41)
+ t = a[21] ^ d1
+ bc4 = bits.RotateLeft64(t, 2)
+ t = a[7] ^ d2
+ bc0 = bits.RotateLeft64(t, 62)
+ t = a[18] ^ d3
+ bc1 = bits.RotateLeft64(t, 55)
+ t = a[4] ^ d4
+ bc2 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 44)
+ t = a[2] ^ d2
+ bc2 = bits.RotateLeft64(t, 43)
+ t = a[3] ^ d3
+ bc3 = bits.RotateLeft64(t, 21)
+ t = a[4] ^ d4
+ bc4 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 3)
+ t = a[6] ^ d1
+ bc3 = bits.RotateLeft64(t, 45)
+ t = a[7] ^ d2
+ bc4 = bits.RotateLeft64(t, 61)
+ t = a[8] ^ d3
+ bc0 = bits.RotateLeft64(t, 28)
+ t = a[9] ^ d4
+ bc1 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 18)
+ t = a[11] ^ d1
+ bc0 = bits.RotateLeft64(t, 1)
+ t = a[12] ^ d2
+ bc1 = bits.RotateLeft64(t, 6)
+ t = a[13] ^ d3
+ bc2 = bits.RotateLeft64(t, 25)
+ t = a[14] ^ d4
+ bc3 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 36)
+ t = a[16] ^ d1
+ bc2 = bits.RotateLeft64(t, 10)
+ t = a[17] ^ d2
+ bc3 = bits.RotateLeft64(t, 15)
+ t = a[18] ^ d3
+ bc4 = bits.RotateLeft64(t, 56)
+ t = a[19] ^ d4
+ bc0 = bits.RotateLeft64(t, 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 = bits.RotateLeft64(t, 41)
+ t = a[21] ^ d1
+ bc4 = bits.RotateLeft64(t, 2)
+ t = a[22] ^ d2
+ bc0 = bits.RotateLeft64(t, 62)
+ t = a[23] ^ d3
+ bc1 = bits.RotateLeft64(t, 55)
+ t = a[24] ^ d4
+ bc2 = bits.RotateLeft64(t, 39)
+ a[20] = bc0 ^ (bc2 &^ bc1)
+ a[21] = bc1 ^ (bc3 &^ bc2)
+ a[22] = bc2 ^ (bc4 &^ bc3)
+ a[23] = bc3 ^ (bc0 &^ bc4)
+ a[24] = bc4 ^ (bc1 &^ bc0)
+ }
+}
diff --git a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
new file mode 100644
index 00000000..b908696b
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
@@ -0,0 +1,13 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && !purego && gc
+
+package sha3
+
+// This function is implemented in keccakf_amd64.s.
+
+//go:noescape
+
+func keccakF1600(a *[25]uint64)
diff --git a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s
new file mode 100644
index 00000000..1f539388
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s
@@ -0,0 +1,390 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && !purego && gc
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources at https://github.com/gvanas/KeccakCodePackage
+
+// Offsets in state
+#define _ba (0*8)
+#define _be (1*8)
+#define _bi (2*8)
+#define _bo (3*8)
+#define _bu (4*8)
+#define _ga (5*8)
+#define _ge (6*8)
+#define _gi (7*8)
+#define _go (8*8)
+#define _gu (9*8)
+#define _ka (10*8)
+#define _ke (11*8)
+#define _ki (12*8)
+#define _ko (13*8)
+#define _ku (14*8)
+#define _ma (15*8)
+#define _me (16*8)
+#define _mi (17*8)
+#define _mo (18*8)
+#define _mu (19*8)
+#define _sa (20*8)
+#define _se (21*8)
+#define _si (22*8)
+#define _so (23*8)
+#define _su (24*8)
+
+// Temporary registers
+#define rT1 AX
+
+// Round vars
+#define rpState DI
+#define rpStack SP
+
+#define rDa BX
+#define rDe CX
+#define rDi DX
+#define rDo R8
+#define rDu R9
+
+#define rBa R10
+#define rBe R11
+#define rBi R12
+#define rBo R13
+#define rBu R14
+
+#define rCa SI
+#define rCe BP
+#define rCi rBi
+#define rCo rBo
+#define rCu R15
+
+#define MOVQ_RBI_RCE MOVQ rBi, rCe
+#define XORQ_RT1_RCA XORQ rT1, rCa
+#define XORQ_RT1_RCE XORQ rT1, rCe
+#define XORQ_RBA_RCU XORQ rBa, rCu
+#define XORQ_RBE_RCU XORQ rBe, rCu
+#define XORQ_RDU_RCU XORQ rDu, rCu
+#define XORQ_RDA_RCA XORQ rDa, rCa
+#define XORQ_RDE_RCE XORQ rDe, rCe
+
+#define mKeccakRound(iState, oState, rc, B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU, K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA, M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA, S_RDE_RCE) \
+ /* Prepare round */ \
+ MOVQ rCe, rDa; \
+ ROLQ $1, rDa; \
+ \
+ MOVQ _bi(iState), rCi; \
+ XORQ _gi(iState), rDi; \
+ XORQ rCu, rDa; \
+ XORQ _ki(iState), rCi; \
+ XORQ _mi(iState), rDi; \
+ XORQ rDi, rCi; \
+ \
+ MOVQ rCi, rDe; \
+ ROLQ $1, rDe; \
+ \
+ MOVQ _bo(iState), rCo; \
+ XORQ _go(iState), rDo; \
+ XORQ rCa, rDe; \
+ XORQ _ko(iState), rCo; \
+ XORQ _mo(iState), rDo; \
+ XORQ rDo, rCo; \
+ \
+ MOVQ rCo, rDi; \
+ ROLQ $1, rDi; \
+ \
+ MOVQ rCu, rDo; \
+ XORQ rCe, rDi; \
+ ROLQ $1, rDo; \
+ \
+ MOVQ rCa, rDu; \
+ XORQ rCi, rDo; \
+ ROLQ $1, rDu; \
+ \
+ /* Result b */ \
+ MOVQ _ba(iState), rBa; \
+ MOVQ _ge(iState), rBe; \
+ XORQ rCo, rDu; \
+ MOVQ _ki(iState), rBi; \
+ MOVQ _mo(iState), rBo; \
+ MOVQ _su(iState), rBu; \
+ XORQ rDe, rBe; \
+ ROLQ $44, rBe; \
+ XORQ rDi, rBi; \
+ XORQ rDa, rBa; \
+ ROLQ $43, rBi; \
+ \
+ MOVQ rBe, rCa; \
+ MOVQ rc, rT1; \
+ ORQ rBi, rCa; \
+ XORQ rBa, rT1; \
+ XORQ rT1, rCa; \
+ MOVQ rCa, _ba(oState); \
+ \
+ XORQ rDu, rBu; \
+ ROLQ $14, rBu; \
+ MOVQ rBa, rCu; \
+ ANDQ rBe, rCu; \
+ XORQ rBu, rCu; \
+ MOVQ rCu, _bu(oState); \
+ \
+ XORQ rDo, rBo; \
+ ROLQ $21, rBo; \
+ MOVQ rBo, rT1; \
+ ANDQ rBu, rT1; \
+ XORQ rBi, rT1; \
+ MOVQ rT1, _bi(oState); \
+ \
+ NOTQ rBi; \
+ ORQ rBa, rBu; \
+ ORQ rBo, rBi; \
+ XORQ rBo, rBu; \
+ XORQ rBe, rBi; \
+ MOVQ rBu, _bo(oState); \
+ MOVQ rBi, _be(oState); \
+ B_RBI_RCE; \
+ \
+ /* Result g */ \
+ MOVQ _gu(iState), rBe; \
+ XORQ rDu, rBe; \
+ MOVQ _ka(iState), rBi; \
+ ROLQ $20, rBe; \
+ XORQ rDa, rBi; \
+ ROLQ $3, rBi; \
+ MOVQ _bo(iState), rBa; \
+ MOVQ rBe, rT1; \
+ ORQ rBi, rT1; \
+ XORQ rDo, rBa; \
+ MOVQ _me(iState), rBo; \
+ MOVQ _si(iState), rBu; \
+ ROLQ $28, rBa; \
+ XORQ rBa, rT1; \
+ MOVQ rT1, _ga(oState); \
+ G_RT1_RCA; \
+ \
+ XORQ rDe, rBo; \
+ ROLQ $45, rBo; \
+ MOVQ rBi, rT1; \
+ ANDQ rBo, rT1; \
+ XORQ rBe, rT1; \
+ MOVQ rT1, _ge(oState); \
+ G_RT1_RCE; \
+ \
+ XORQ rDi, rBu; \
+ ROLQ $61, rBu; \
+ MOVQ rBu, rT1; \
+ ORQ rBa, rT1; \
+ XORQ rBo, rT1; \
+ MOVQ rT1, _go(oState); \
+ \
+ ANDQ rBe, rBa; \
+ XORQ rBu, rBa; \
+ MOVQ rBa, _gu(oState); \
+ NOTQ rBu; \
+ G_RBA_RCU; \
+ \
+ ORQ rBu, rBo; \
+ XORQ rBi, rBo; \
+ MOVQ rBo, _gi(oState); \
+ \
+ /* Result k */ \
+ MOVQ _be(iState), rBa; \
+ MOVQ _gi(iState), rBe; \
+ MOVQ _ko(iState), rBi; \
+ MOVQ _mu(iState), rBo; \
+ MOVQ _sa(iState), rBu; \
+ XORQ rDi, rBe; \
+ ROLQ $6, rBe; \
+ XORQ rDo, rBi; \
+ ROLQ $25, rBi; \
+ MOVQ rBe, rT1; \
+ ORQ rBi, rT1; \
+ XORQ rDe, rBa; \
+ ROLQ $1, rBa; \
+ XORQ rBa, rT1; \
+ MOVQ rT1, _ka(oState); \
+ K_RT1_RCA; \
+ \
+ XORQ rDu, rBo; \
+ ROLQ $8, rBo; \
+ MOVQ rBi, rT1; \
+ ANDQ rBo, rT1; \
+ XORQ rBe, rT1; \
+ MOVQ rT1, _ke(oState); \
+ K_RT1_RCE; \
+ \
+ XORQ rDa, rBu; \
+ ROLQ $18, rBu; \
+ NOTQ rBo; \
+ MOVQ rBo, rT1; \
+ ANDQ rBu, rT1; \
+ XORQ rBi, rT1; \
+ MOVQ rT1, _ki(oState); \
+ \
+ MOVQ rBu, rT1; \
+ ORQ rBa, rT1; \
+ XORQ rBo, rT1; \
+ MOVQ rT1, _ko(oState); \
+ \
+ ANDQ rBe, rBa; \
+ XORQ rBu, rBa; \
+ MOVQ rBa, _ku(oState); \
+ K_RBA_RCU; \
+ \
+ /* Result m */ \
+ MOVQ _ga(iState), rBe; \
+ XORQ rDa, rBe; \
+ MOVQ _ke(iState), rBi; \
+ ROLQ $36, rBe; \
+ XORQ rDe, rBi; \
+ MOVQ _bu(iState), rBa; \
+ ROLQ $10, rBi; \
+ MOVQ rBe, rT1; \
+ MOVQ _mi(iState), rBo; \
+ ANDQ rBi, rT1; \
+ XORQ rDu, rBa; \
+ MOVQ _so(iState), rBu; \
+ ROLQ $27, rBa; \
+ XORQ rBa, rT1; \
+ MOVQ rT1, _ma(oState); \
+ M_RT1_RCA; \
+ \
+ XORQ rDi, rBo; \
+ ROLQ $15, rBo; \
+ MOVQ rBi, rT1; \
+ ORQ rBo, rT1; \
+ XORQ rBe, rT1; \
+ MOVQ rT1, _me(oState); \
+ M_RT1_RCE; \
+ \
+ XORQ rDo, rBu; \
+ ROLQ $56, rBu; \
+ NOTQ rBo; \
+ MOVQ rBo, rT1; \
+ ORQ rBu, rT1; \
+ XORQ rBi, rT1; \
+ MOVQ rT1, _mi(oState); \
+ \
+ ORQ rBa, rBe; \
+ XORQ rBu, rBe; \
+ MOVQ rBe, _mu(oState); \
+ \
+ ANDQ rBa, rBu; \
+ XORQ rBo, rBu; \
+ MOVQ rBu, _mo(oState); \
+ M_RBE_RCU; \
+ \
+ /* Result s */ \
+ MOVQ _bi(iState), rBa; \
+ MOVQ _go(iState), rBe; \
+ MOVQ _ku(iState), rBi; \
+ XORQ rDi, rBa; \
+ MOVQ _ma(iState), rBo; \
+ ROLQ $62, rBa; \
+ XORQ rDo, rBe; \
+ MOVQ _se(iState), rBu; \
+ ROLQ $55, rBe; \
+ \
+ XORQ rDu, rBi; \
+ MOVQ rBa, rDu; \
+ XORQ rDe, rBu; \
+ ROLQ $2, rBu; \
+ ANDQ rBe, rDu; \
+ XORQ rBu, rDu; \
+ MOVQ rDu, _su(oState); \
+ \
+ ROLQ $39, rBi; \
+ S_RDU_RCU; \
+ NOTQ rBe; \
+ XORQ rDa, rBo; \
+ MOVQ rBe, rDa; \
+ ANDQ rBi, rDa; \
+ XORQ rBa, rDa; \
+ MOVQ rDa, _sa(oState); \
+ S_RDA_RCA; \
+ \
+ ROLQ $41, rBo; \
+ MOVQ rBi, rDe; \
+ ORQ rBo, rDe; \
+ XORQ rBe, rDe; \
+ MOVQ rDe, _se(oState); \
+ S_RDE_RCE; \
+ \
+ MOVQ rBo, rDi; \
+ MOVQ rBu, rDo; \
+ ANDQ rBu, rDi; \
+ ORQ rBa, rDo; \
+ XORQ rBi, rDi; \
+ XORQ rBo, rDo; \
+ MOVQ rDi, _si(oState); \
+ MOVQ rDo, _so(oState) \
+
+// func keccakF1600(a *[25]uint64)
+TEXT ·keccakF1600(SB), 0, $200-8
+ MOVQ a+0(FP), rpState
+
+ // Convert the user state into an internal state
+ NOTQ _be(rpState)
+ NOTQ _bi(rpState)
+ NOTQ _go(rpState)
+ NOTQ _ki(rpState)
+ NOTQ _mi(rpState)
+ NOTQ _sa(rpState)
+
+ // Execute the KeccakF permutation
+ MOVQ _ba(rpState), rCa
+ MOVQ _be(rpState), rCe
+ MOVQ _bu(rpState), rCu
+
+ XORQ _ga(rpState), rCa
+ XORQ _ge(rpState), rCe
+ XORQ _gu(rpState), rCu
+
+ XORQ _ka(rpState), rCa
+ XORQ _ke(rpState), rCe
+ XORQ _ku(rpState), rCu
+
+ XORQ _ma(rpState), rCa
+ XORQ _me(rpState), rCe
+ XORQ _mu(rpState), rCu
+
+ XORQ _sa(rpState), rCa
+ XORQ _se(rpState), rCe
+ MOVQ _si(rpState), rDi
+ MOVQ _so(rpState), rDo
+ XORQ _su(rpState), rCu
+
+ mKeccakRound(rpState, rpStack, $0x0000000000000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x0000000000008082, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x800000000000808a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x8000000080008000, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x000000000000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x8000000000008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x000000000000008a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x0000000000000088, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x0000000080008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x000000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x000000008000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x800000000000008b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x8000000000008089, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x8000000000008003, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x8000000000008002, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x8000000000000080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x000000000000800a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x800000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x8000000000008080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpState, rpStack, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
+ mKeccakRound(rpStack, rpState, $0x8000000080008008, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP)
+
+ // Revert the internal state to the user state
+ NOTQ _be(rpState)
+ NOTQ _bi(rpState)
+ NOTQ _go(rpState)
+ NOTQ _ki(rpState)
+ NOTQ _mi(rpState)
+ NOTQ _sa(rpState)
+
+ RET
diff --git a/vendor/golang.org/x/crypto/sha3/sha3.go b/vendor/golang.org/x/crypto/sha3/sha3.go
new file mode 100644
index 00000000..afedde5a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/sha3.go
@@ -0,0 +1,185 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// spongeDirection indicates the direction bytes are flowing through the sponge.
+type spongeDirection int
+
+const (
+ // spongeAbsorbing indicates that the sponge is absorbing input.
+ spongeAbsorbing spongeDirection = iota
+ // spongeSqueezing indicates that the sponge is being squeezed.
+ spongeSqueezing
+)
+
+const (
+ // maxRate is the maximum size of the internal buffer. SHAKE-256
+ // currently needs the largest buffer.
+ maxRate = 168
+)
+
+type state struct {
+ // Generic sponge components.
+ a [25]uint64 // main state of the hash
+ rate int // the number of bytes of state to use
+
+ // dsbyte contains the "domain separation" bits and the first bit of
+ // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
+ // SHA-3 and SHAKE functions by appending bitstrings to the message.
+ // Using a little-endian bit-ordering convention, these are "01" for SHA-3
+ // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
+ // padding rule from section 5.1 is applied to pad the message to a multiple
+ // of the rate, which involves adding a "1" bit, zero or more "0" bits, and
+ // a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
+ // giving 00000110b (0x06) and 00011111b (0x1f).
+ // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
+ // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
+ // Extendable-Output Functions (May 2014)"
+ dsbyte byte
+
+ 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
+ state spongeDirection // whether the sponge is absorbing or squeezing
+}
+
+// BlockSize returns the rate of sponge underlying this hash function.
+func (d *state) BlockSize() int { return d.rate }
+
+// Size returns the output size of the hash function in bytes.
+func (d *state) Size() int { return d.outputLen }
+
+// Reset clears the internal state by zeroing the sponge state and
+// the 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.i, d.n = 0, 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.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.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() {
+ // 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.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.storage[d.rate-1] ^= 0x80
+ // Apply the permutation
+ d.permute()
+ d.state = spongeSqueezing
+ d.n = d.rate
+ copyOut(d, d.storage[:d.rate])
+}
+
+// Write absorbs more data into the hash's state. It panics if any
+// output has already been read.
+func (d *state) Write(p []byte) (written int, err error) {
+ if d.state != spongeAbsorbing {
+ panic("sha3: Write after Read")
+ }
+ written = len(p)
+
+ for len(p) > 0 {
+ 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 - d.n
+ if todo > len(p) {
+ todo = len(p)
+ }
+ d.n += copy(d.storage[d.n:], p[:todo])
+ p = p[todo:]
+
+ // If the sponge is full, apply the permutation.
+ if d.n == d.rate {
+ d.permute()
+ }
+ }
+ }
+
+ return
+}
+
+// Read squeezes an arbitrary number of bytes from the sponge.
+func (d *state) Read(out []byte) (n int, err error) {
+ // If we're still absorbing, pad and apply the permutation.
+ if d.state == spongeAbsorbing {
+ d.padAndPermute()
+ }
+
+ n = len(out)
+
+ // Now, do the squeezing.
+ for len(out) > 0 {
+ 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 d.i == d.rate {
+ d.permute()
+ }
+ }
+
+ return
+}
+
+// Sum applies padding to the hash state and then squeezes out the desired
+// number of output bytes. It panics if any output has already been read.
+func (d *state) Sum(in []byte) []byte {
+ if d.state != spongeAbsorbing {
+ panic("sha3: Sum after Read")
+ }
+
+ // Make a copy of the original hash so that caller can keep writing
+ // and summing.
+ dup := d.clone()
+ hash := make([]byte, dup.outputLen, 64) // explicit cap to allow stack allocation
+ dup.Read(hash)
+ return append(in, hash...)
+}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
new file mode 100644
index 00000000..00d8034a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
@@ -0,0 +1,303 @@
+// 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
+
+package sha3
+
+// This file contains code for using the 'compute intermediate
+// message digest' (KIMD) and 'compute last message digest' (KLMD)
+// instructions to compute SHA-3 and SHAKE hashes on IBM Z.
+
+import (
+ "hash"
+
+ "golang.org/x/sys/cpu"
+)
+
+// codes represent 7-bit KIMD/KLMD function codes as defined in
+// the Principles of Operation.
+type code uint64
+
+const (
+ // function codes for KIMD/KLMD
+ sha3_224 code = 32
+ sha3_256 = 33
+ sha3_384 = 34
+ sha3_512 = 35
+ shake_128 = 36
+ shake_256 = 37
+ nopad = 0x100
+)
+
+// kimd is a wrapper for the 'compute intermediate message digest' instruction.
+// src must be a multiple of the rate for the given function code.
+//
+//go:noescape
+func kimd(function code, chain *[200]byte, src []byte)
+
+// klmd is a wrapper for the 'compute last message digest' instruction.
+// src padding is handled by the instruction.
+//
+//go:noescape
+func klmd(function code, chain *[200]byte, dst, src []byte)
+
+type asmState struct {
+ a [200]byte // 1600 bit state
+ buf []byte // care must be taken to ensure cap(buf) is a multiple of rate
+ rate int // equivalent to block size
+ storage [3072]byte // underlying storage for buf
+ outputLen int // output length for full security
+ function code // KIMD/KLMD function code
+ state spongeDirection // whether the sponge is absorbing or squeezing
+}
+
+func newAsmState(function code) *asmState {
+ var s asmState
+ s.function = function
+ switch function {
+ case sha3_224:
+ s.rate = 144
+ s.outputLen = 28
+ case sha3_256:
+ s.rate = 136
+ s.outputLen = 32
+ case sha3_384:
+ s.rate = 104
+ s.outputLen = 48
+ case sha3_512:
+ s.rate = 72
+ s.outputLen = 64
+ case shake_128:
+ s.rate = 168
+ s.outputLen = 32
+ case shake_256:
+ s.rate = 136
+ s.outputLen = 64
+ default:
+ panic("sha3: unrecognized function code")
+ }
+
+ // limit s.buf size to a multiple of s.rate
+ s.resetBuf()
+ return &s
+}
+
+func (s *asmState) clone() *asmState {
+ c := *s
+ c.buf = c.storage[:len(s.buf):cap(s.buf)]
+ return &c
+}
+
+// copyIntoBuf copies b into buf. It will panic if there is not enough space to
+// store all of b.
+func (s *asmState) copyIntoBuf(b []byte) {
+ bufLen := len(s.buf)
+ s.buf = s.buf[:len(s.buf)+len(b)]
+ copy(s.buf[bufLen:], b)
+}
+
+// resetBuf points buf at storage, sets the length to 0 and sets cap to be a
+// multiple of the rate.
+func (s *asmState) resetBuf() {
+ max := (cap(s.storage) / s.rate) * s.rate
+ s.buf = s.storage[:0:max]
+}
+
+// Write (via the embedded io.Writer interface) adds more data to the running hash.
+// It never returns an error.
+func (s *asmState) Write(b []byte) (int, error) {
+ if s.state != spongeAbsorbing {
+ panic("sha3: Write after Read")
+ }
+ length := len(b)
+ for len(b) > 0 {
+ if len(s.buf) == 0 && len(b) >= cap(s.buf) {
+ // Hash the data directly and push any remaining bytes
+ // into the buffer.
+ remainder := len(b) % s.rate
+ kimd(s.function, &s.a, b[:len(b)-remainder])
+ if remainder != 0 {
+ s.copyIntoBuf(b[len(b)-remainder:])
+ }
+ return length, nil
+ }
+
+ if len(s.buf) == cap(s.buf) {
+ // flush the buffer
+ kimd(s.function, &s.a, s.buf)
+ s.buf = s.buf[:0]
+ }
+
+ // copy as much as we can into the buffer
+ n := len(b)
+ if len(b) > cap(s.buf)-len(s.buf) {
+ n = cap(s.buf) - len(s.buf)
+ }
+ s.copyIntoBuf(b[:n])
+ b = b[n:]
+ }
+ return length, nil
+}
+
+// Read squeezes an arbitrary number of bytes from the sponge.
+func (s *asmState) Read(out []byte) (n int, err error) {
+ // 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
+ if s.state == spongeAbsorbing {
+ s.state = spongeSqueezing
+
+ // write hash directly into out if possible
+ if len(out)%s.rate == 0 {
+ klmd(s.function, &s.a, out, s.buf) // len(out) may be 0
+ s.buf = s.buf[:0]
+ return
+ }
+
+ // write hash into buffer
+ max := cap(s.buf)
+ if max > len(out) {
+ max = (len(out)/s.rate)*s.rate + s.rate
+ }
+ klmd(s.function, &s.a, s.buf[:max], s.buf)
+ s.buf = s.buf[:max]
+ }
+
+ for len(out) > 0 {
+ // flush the buffer
+ if len(s.buf) != 0 {
+ c := copy(out, s.buf)
+ out = out[c:]
+ s.buf = s.buf[c:]
+ continue
+ }
+
+ // write hash directly into out if possible
+ if len(out)%s.rate == 0 {
+ klmd(s.function|nopad, &s.a, out, nil)
+ return
+ }
+
+ // write hash into buffer
+ s.resetBuf()
+ if cap(s.buf) > len(out) {
+ s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate]
+ }
+ klmd(s.function|nopad, &s.a, s.buf, nil)
+ }
+ return
+}
+
+// Sum appends the current hash to b and returns the resulting slice.
+// It does not change the underlying hash state.
+func (s *asmState) Sum(b []byte) []byte {
+ if s.state != spongeAbsorbing {
+ panic("sha3: Sum after Read")
+ }
+
+ // Copy the state to preserve the original.
+ a := s.a
+
+ // Hash the buffer. Note that we don't clear it because we
+ // aren't updating the state.
+ 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.
+func (s *asmState) Reset() {
+ for i := range s.a {
+ s.a[i] = 0
+ }
+ s.resetBuf()
+ s.state = spongeAbsorbing
+}
+
+// Size returns the number of bytes Sum will return.
+func (s *asmState) Size() int {
+ return s.outputLen
+}
+
+// BlockSize returns the hash's underlying block size.
+// The Write method must be able to accept any amount
+// of data, but it may operate more efficiently if all writes
+// are a multiple of the block size.
+func (s *asmState) BlockSize() int {
+ return s.rate
+}
+
+// Clone returns a copy of the ShakeHash in its current state.
+func (s *asmState) Clone() ShakeHash {
+ return s.clone()
+}
+
+// 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 new224Generic()
+}
+
+// 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 new256Generic()
+}
+
+// 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 new384Generic()
+}
+
+// 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 new512Generic()
+}
+
+// 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 newShake128Generic()
+}
+
+// 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 newShake256Generic()
+}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.s b/vendor/golang.org/x/crypto/sha3/sha3_s390x.s
new file mode 100644
index 00000000..826b862c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/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.
+
+//go:build gc && !purego
+
+#include "textflag.h"
+
+// func kimd(function code, chain *[200]byte, src []byte)
+TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40
+ MOVD function+0(FP), R0
+ MOVD chain+8(FP), R1
+ LMG src+16(FP), R2, R3 // R2=base, R3=len
+
+continue:
+ WORD $0xB93E0002 // KIMD --, R2
+ BVS continue // continue if interrupted
+ MOVD $0, R0 // reset R0 for pre-go1.8 compilers
+ RET
+
+// func klmd(function code, chain *[200]byte, dst, src []byte)
+TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64
+ // TODO: SHAKE support
+ MOVD function+0(FP), R0
+ MOVD chain+8(FP), R1
+ LMG dst+16(FP), R2, R3 // R2=base, R3=len
+ LMG src+40(FP), R4, R5 // R4=base, R5=len
+
+continue:
+ WORD $0xB93F0024 // KLMD R2, R4
+ BVS continue // continue if interrupted
+ MOVD $0, R0 // reset R0 for pre-go1.8 compilers
+ RET
diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go
new file mode 100644
index 00000000..1ea9275b
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/shake.go
@@ -0,0 +1,174 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file defines the ShakeHash interface, and provides
+// functions for creating SHAKE and cSHAKE instances, as well as utility
+// functions for hashing bytes to arbitrary-length output.
+//
+//
+// SHAKE implementation is based on FIPS PUB 202 [1]
+// cSHAKE implementations is based on NIST SP 800-185 [2]
+//
+// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
+// [2] https://doi.org/10.6028/NIST.SP.800-185
+
+import (
+ "encoding/binary"
+ "hash"
+ "io"
+)
+
+// ShakeHash defines the interface to hash functions that support
+// arbitrary-length output. When used as a plain [hash.Hash], it
+// produces minimum-length outputs that provide full-strength generic
+// security.
+type ShakeHash interface {
+ hash.Hash
+
+ // 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, but subsequent calls to Write or Sum
+ // will panic.
+ io.Reader
+
+ // Clone returns a copy of the ShakeHash in its current state.
+ Clone() ShakeHash
+}
+
+// cSHAKE specific context
+type cshakeState struct {
+ *state // SHA-3 state context and Read/Write operations
+
+ // initBlock is the cSHAKE specific initialization set of bytes. It is initialized
+ // by newCShake function and stores concatenation of N followed by S, encoded
+ // by the method specified in 3.3 of [1].
+ // It is stored here in order for Reset() to be able to put context into
+ // initial state.
+ initBlock []byte
+}
+
+// Consts for configuring initial SHA-3 state
+const (
+ dsbyteShake = 0x1f
+ dsbyteCShake = 0x04
+ rate128 = 168
+ rate256 = 136
+)
+
+func bytepad(input []byte, w int) []byte {
+ // leftEncode always returns max 9 bytes
+ buf := make([]byte, 0, 9+len(input)+w)
+ buf = append(buf, leftEncode(uint64(w))...)
+ buf = append(buf, input...)
+ padlen := w - (len(buf) % w)
+ return append(buf, make([]byte, padlen)...)
+}
+
+func leftEncode(value uint64) []byte {
+ var b [9]byte
+ binary.BigEndian.PutUint64(b[1:], value)
+ // Trim all but last leading zero bytes
+ i := byte(1)
+ for i < 8 && b[i] == 0 {
+ i++
+ }
+ // Prepend number of encoded bytes
+ b[i-1] = 9 - i
+ return b[i-1:]
+}
+
+func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash {
+ c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}}
+
+ // leftEncode returns max 9 bytes
+ c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
+ c.initBlock = append(c.initBlock, leftEncode(uint64(len(N)*8))...)
+ c.initBlock = append(c.initBlock, N...)
+ c.initBlock = append(c.initBlock, leftEncode(uint64(len(S)*8))...)
+ c.initBlock = append(c.initBlock, S...)
+ c.Write(bytepad(c.initBlock, c.rate))
+ return &c
+}
+
+// Reset resets the hash to initial state.
+func (c *cshakeState) Reset() {
+ c.state.Reset()
+ c.Write(bytepad(c.initBlock, c.rate))
+}
+
+// Clone returns copy of a cSHAKE context within its current state.
+func (c *cshakeState) Clone() ShakeHash {
+ b := make([]byte, len(c.initBlock))
+ copy(b, c.initBlock)
+ return &cshakeState{state: c.clone(), initBlock: b}
+}
+
+// Clone returns copy of SHAKE context within its current state.
+func (c *state) Clone() ShakeHash {
+ return c.clone()
+}
+
+// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
+// Its generic security strength is 128 bits against all attacks if at
+// least 32 bytes of its output are used.
+func NewShake128() ShakeHash {
+ 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 {
+ return newShake256()
+}
+
+func newShake128Generic() *state {
+ return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
+}
+
+func newShake256Generic() *state {
+ return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake}
+}
+
+// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
+// a customizable variant of SHAKE128.
+// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
+// desired. S is a customization byte string used for domain separation - two cSHAKE
+// computations on same input with different S yield unrelated outputs.
+// When N and S are both empty, this is equivalent to NewShake128.
+func NewCShake128(N, S []byte) ShakeHash {
+ if len(N) == 0 && len(S) == 0 {
+ return NewShake128()
+ }
+ return newCShake(N, S, rate128, 32, dsbyteCShake)
+}
+
+// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
+// a customizable variant of SHAKE256.
+// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
+// desired. S is a customization byte string used for domain separation - two cSHAKE
+// computations on same input with different S yield unrelated outputs.
+// When N and S are both empty, this is equivalent to NewShake256.
+func NewCShake256(N, S []byte) ShakeHash {
+ if len(N) == 0 && len(S) == 0 {
+ return NewShake256()
+ }
+ return newCShake(N, S, rate256, 64, dsbyteCShake)
+}
+
+// ShakeSum128 writes an arbitrary-length digest of data into hash.
+func ShakeSum128(hash, data []byte) {
+ h := NewShake128()
+ h.Write(data)
+ h.Read(hash)
+}
+
+// ShakeSum256 writes an arbitrary-length digest of data into hash.
+func ShakeSum256(hash, data []byte) {
+ h := NewShake256()
+ h.Write(data)
+ h.Read(hash)
+}
diff --git a/vendor/golang.org/x/crypto/sha3/shake_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
new file mode 100644
index 00000000..6ada5c95
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/xor.go
@@ -0,0 +1,40 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+import (
+ "crypto/subtle"
+ "encoding/binary"
+ "unsafe"
+
+ "golang.org/x/sys/cpu"
+)
+
+// 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/ssh/agent/client.go b/vendor/golang.org/x/crypto/ssh/agent/client.go
new file mode 100644
index 00000000..106708d2
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/agent/client.go
@@ -0,0 +1,854 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package agent implements the ssh-agent protocol, and provides both
+// a client and a server. The client can talk to a standard ssh-agent
+// that uses UNIX sockets, and one could implement an alternative
+// ssh-agent process using the sample server.
+//
+// References:
+//
+// [PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00
+package agent
+
+import (
+ "bytes"
+ "crypto/dsa"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rsa"
+ "encoding/base64"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "math/big"
+ "sync"
+
+ "golang.org/x/crypto/ssh"
+)
+
+// SignatureFlags represent additional flags that can be passed to the signature
+// requests an defined in [PROTOCOL.agent] section 4.5.1.
+type SignatureFlags uint32
+
+// SignatureFlag values as defined in [PROTOCOL.agent] section 5.3.
+const (
+ SignatureFlagReserved SignatureFlags = 1 << iota
+ SignatureFlagRsaSha256
+ SignatureFlagRsaSha512
+)
+
+// Agent represents the capabilities of an ssh-agent.
+type Agent interface {
+ // List returns the identities known to the agent.
+ List() ([]*Key, error)
+
+ // Sign has the agent sign the data using a protocol 2 key as defined
+ // in [PROTOCOL.agent] section 2.6.2.
+ Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error)
+
+ // Add adds a private key to the agent.
+ Add(key AddedKey) error
+
+ // Remove removes all identities with the given public key.
+ Remove(key ssh.PublicKey) error
+
+ // RemoveAll removes all identities.
+ RemoveAll() error
+
+ // Lock locks the agent. Sign and Remove will fail, and List will empty an empty list.
+ Lock(passphrase []byte) error
+
+ // Unlock undoes the effect of Lock
+ Unlock(passphrase []byte) error
+
+ // Signers returns signers for all the known keys.
+ Signers() ([]ssh.Signer, error)
+}
+
+type ExtendedAgent interface {
+ Agent
+
+ // SignWithFlags signs like Sign, but allows for additional flags to be sent/received
+ SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error)
+
+ // Extension processes a custom extension request. Standard-compliant agents are not
+ // required to support any extensions, but this method allows agents to implement
+ // vendor-specific methods or add experimental features. See [PROTOCOL.agent] section 4.7.
+ // If agent extensions are unsupported entirely this method MUST return an
+ // ErrExtensionUnsupported error. Similarly, if just the specific extensionType in
+ // the request is unsupported by the agent then ErrExtensionUnsupported MUST be
+ // returned.
+ //
+ // In the case of success, since [PROTOCOL.agent] section 4.7 specifies that the contents
+ // of the response are unspecified (including the type of the message), the complete
+ // response will be returned as a []byte slice, including the "type" byte of the message.
+ Extension(extensionType string, contents []byte) ([]byte, error)
+}
+
+// ConstraintExtension describes an optional constraint defined by users.
+type ConstraintExtension struct {
+ // ExtensionName consist of a UTF-8 string suffixed by the
+ // implementation domain following the naming scheme defined
+ // in Section 4.2 of RFC 4251, e.g. "foo@example.com".
+ ExtensionName string
+ // ExtensionDetails contains the actual content of the extended
+ // constraint.
+ ExtensionDetails []byte
+}
+
+// AddedKey describes an SSH key to be added to an Agent.
+type AddedKey struct {
+ // PrivateKey must be a *rsa.PrivateKey, *dsa.PrivateKey,
+ // ed25519.PrivateKey or *ecdsa.PrivateKey, which will be inserted into the
+ // agent.
+ PrivateKey interface{}
+ // Certificate, if not nil, is communicated to the agent and will be
+ // stored with the key.
+ Certificate *ssh.Certificate
+ // Comment is an optional, free-form string.
+ Comment string
+ // LifetimeSecs, if not zero, is the number of seconds that the
+ // agent will store the key for.
+ LifetimeSecs uint32
+ // ConfirmBeforeUse, if true, requests that the agent confirm with the
+ // user before each use of this key.
+ ConfirmBeforeUse bool
+ // ConstraintExtensions are the experimental or private-use constraints
+ // defined by users.
+ ConstraintExtensions []ConstraintExtension
+}
+
+// See [PROTOCOL.agent], section 3.
+const (
+ agentRequestV1Identities = 1
+ agentRemoveAllV1Identities = 9
+
+ // 3.2 Requests from client to agent for protocol 2 key operations
+ agentAddIdentity = 17
+ agentRemoveIdentity = 18
+ agentRemoveAllIdentities = 19
+ agentAddIDConstrained = 25
+
+ // 3.3 Key-type independent requests from client to agent
+ agentAddSmartcardKey = 20
+ agentRemoveSmartcardKey = 21
+ agentLock = 22
+ agentUnlock = 23
+ agentAddSmartcardKeyConstrained = 26
+
+ // 3.7 Key constraint identifiers
+ agentConstrainLifetime = 1
+ agentConstrainConfirm = 2
+ // Constraint extension identifier up to version 2 of the protocol. A
+ // backward incompatible change will be required if we want to add support
+ // for SSH_AGENT_CONSTRAIN_MAXSIGN which uses the same ID.
+ agentConstrainExtensionV00 = 3
+ // Constraint extension identifier in version 3 and later of the protocol.
+ agentConstrainExtension = 255
+)
+
+// maxAgentResponseBytes is the maximum agent reply size that is accepted. This
+// is a sanity check, not a limit in the spec.
+const maxAgentResponseBytes = 16 << 20
+
+// Agent messages:
+// These structures mirror the wire format of the corresponding ssh agent
+// messages found in [PROTOCOL.agent].
+
+// 3.4 Generic replies from agent to client
+const agentFailure = 5
+
+type failureAgentMsg struct{}
+
+const agentSuccess = 6
+
+type successAgentMsg struct{}
+
+// See [PROTOCOL.agent], section 2.5.2.
+const agentRequestIdentities = 11
+
+type requestIdentitiesAgentMsg struct{}
+
+// See [PROTOCOL.agent], section 2.5.2.
+const agentIdentitiesAnswer = 12
+
+type identitiesAnswerAgentMsg struct {
+ NumKeys uint32 `sshtype:"12"`
+ Keys []byte `ssh:"rest"`
+}
+
+// See [PROTOCOL.agent], section 2.6.2.
+const agentSignRequest = 13
+
+type signRequestAgentMsg struct {
+ KeyBlob []byte `sshtype:"13"`
+ Data []byte
+ Flags uint32
+}
+
+// See [PROTOCOL.agent], section 2.6.2.
+
+// 3.6 Replies from agent to client for protocol 2 key operations
+const agentSignResponse = 14
+
+type signResponseAgentMsg struct {
+ SigBlob []byte `sshtype:"14"`
+}
+
+type publicKey struct {
+ Format string
+ Rest []byte `ssh:"rest"`
+}
+
+// 3.7 Key constraint identifiers
+type constrainLifetimeAgentMsg struct {
+ LifetimeSecs uint32 `sshtype:"1"`
+}
+
+type constrainExtensionAgentMsg struct {
+ ExtensionName string `sshtype:"255|3"`
+ ExtensionDetails []byte
+
+ // Rest is a field used for parsing, not part of message
+ Rest []byte `ssh:"rest"`
+}
+
+// See [PROTOCOL.agent], section 4.7
+const agentExtension = 27
+const agentExtensionFailure = 28
+
+// ErrExtensionUnsupported indicates that an extension defined in
+// [PROTOCOL.agent] section 4.7 is unsupported by the agent. Specifically this
+// error indicates that the agent returned a standard SSH_AGENT_FAILURE message
+// as the result of a SSH_AGENTC_EXTENSION request. Note that the protocol
+// specification (and therefore this error) does not distinguish between a
+// specific extension being unsupported and extensions being unsupported entirely.
+var ErrExtensionUnsupported = errors.New("agent: extension unsupported")
+
+type extensionAgentMsg struct {
+ ExtensionType string `sshtype:"27"`
+ // NOTE: this matches OpenSSH's PROTOCOL.agent, not the IETF draft [PROTOCOL.agent],
+ // so that it matches what OpenSSH actually implements in the wild.
+ Contents []byte `ssh:"rest"`
+}
+
+// Key represents a protocol 2 public key as defined in
+// [PROTOCOL.agent], section 2.5.2.
+type Key struct {
+ Format string
+ Blob []byte
+ Comment string
+}
+
+func clientErr(err error) error {
+ return fmt.Errorf("agent: client error: %v", err)
+}
+
+// String returns the storage form of an agent key with the format, base64
+// encoded serialized key, and the comment if it is not empty.
+func (k *Key) String() string {
+ s := string(k.Format) + " " + base64.StdEncoding.EncodeToString(k.Blob)
+
+ if k.Comment != "" {
+ s += " " + k.Comment
+ }
+
+ return s
+}
+
+// Type returns the public key type.
+func (k *Key) Type() string {
+ return k.Format
+}
+
+// Marshal returns key blob to satisfy the ssh.PublicKey interface.
+func (k *Key) Marshal() []byte {
+ return k.Blob
+}
+
+// Verify satisfies the ssh.PublicKey interface.
+func (k *Key) Verify(data []byte, sig *ssh.Signature) error {
+ pubKey, err := ssh.ParsePublicKey(k.Blob)
+ if err != nil {
+ return fmt.Errorf("agent: bad public key: %v", err)
+ }
+ return pubKey.Verify(data, sig)
+}
+
+type wireKey struct {
+ Format string
+ Rest []byte `ssh:"rest"`
+}
+
+func parseKey(in []byte) (out *Key, rest []byte, err error) {
+ var record struct {
+ Blob []byte
+ Comment string
+ Rest []byte `ssh:"rest"`
+ }
+
+ if err := ssh.Unmarshal(in, &record); err != nil {
+ return nil, nil, err
+ }
+
+ var wk wireKey
+ if err := ssh.Unmarshal(record.Blob, &wk); err != nil {
+ return nil, nil, err
+ }
+
+ return &Key{
+ Format: wk.Format,
+ Blob: record.Blob,
+ Comment: record.Comment,
+ }, record.Rest, nil
+}
+
+// client is a client for an ssh-agent process.
+type client struct {
+ // conn is typically a *net.UnixConn
+ conn io.ReadWriter
+ // mu is used to prevent concurrent access to the agent
+ mu sync.Mutex
+}
+
+// NewClient returns an Agent that talks to an ssh-agent process over
+// the given connection.
+func NewClient(rw io.ReadWriter) ExtendedAgent {
+ return &client{conn: rw}
+}
+
+// call sends an RPC to the agent. On success, the reply is
+// unmarshaled into reply and replyType is set to the first byte of
+// the reply, which contains the type of the message.
+func (c *client) call(req []byte) (reply interface{}, err error) {
+ buf, err := c.callRaw(req)
+ if err != nil {
+ return nil, err
+ }
+ reply, err = unmarshal(buf)
+ if err != nil {
+ return nil, clientErr(err)
+ }
+ return reply, nil
+}
+
+// callRaw sends an RPC to the agent. On success, the raw
+// bytes of the response are returned; no unmarshalling is
+// performed on the response.
+func (c *client) callRaw(req []byte) (reply []byte, err error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
+ msg := make([]byte, 4+len(req))
+ binary.BigEndian.PutUint32(msg, uint32(len(req)))
+ copy(msg[4:], req)
+ if _, err = c.conn.Write(msg); err != nil {
+ return nil, clientErr(err)
+ }
+
+ var respSizeBuf [4]byte
+ if _, err = io.ReadFull(c.conn, respSizeBuf[:]); err != nil {
+ return nil, clientErr(err)
+ }
+ respSize := binary.BigEndian.Uint32(respSizeBuf[:])
+ if respSize > maxAgentResponseBytes {
+ return nil, clientErr(errors.New("response too large"))
+ }
+
+ buf := make([]byte, respSize)
+ if _, err = io.ReadFull(c.conn, buf); err != nil {
+ return nil, clientErr(err)
+ }
+ return buf, nil
+}
+
+func (c *client) simpleCall(req []byte) error {
+ resp, err := c.call(req)
+ if err != nil {
+ return err
+ }
+ if _, ok := resp.(*successAgentMsg); ok {
+ return nil
+ }
+ return errors.New("agent: failure")
+}
+
+func (c *client) RemoveAll() error {
+ return c.simpleCall([]byte{agentRemoveAllIdentities})
+}
+
+func (c *client) Remove(key ssh.PublicKey) error {
+ req := ssh.Marshal(&agentRemoveIdentityMsg{
+ KeyBlob: key.Marshal(),
+ })
+ return c.simpleCall(req)
+}
+
+func (c *client) Lock(passphrase []byte) error {
+ req := ssh.Marshal(&agentLockMsg{
+ Passphrase: passphrase,
+ })
+ return c.simpleCall(req)
+}
+
+func (c *client) Unlock(passphrase []byte) error {
+ req := ssh.Marshal(&agentUnlockMsg{
+ Passphrase: passphrase,
+ })
+ return c.simpleCall(req)
+}
+
+// List returns the identities known to the agent.
+func (c *client) List() ([]*Key, error) {
+ // see [PROTOCOL.agent] section 2.5.2.
+ req := []byte{agentRequestIdentities}
+
+ msg, err := c.call(req)
+ if err != nil {
+ return nil, err
+ }
+
+ switch msg := msg.(type) {
+ case *identitiesAnswerAgentMsg:
+ if msg.NumKeys > maxAgentResponseBytes/8 {
+ return nil, errors.New("agent: too many keys in agent reply")
+ }
+ keys := make([]*Key, msg.NumKeys)
+ data := msg.Keys
+ for i := uint32(0); i < msg.NumKeys; i++ {
+ var key *Key
+ var err error
+ if key, data, err = parseKey(data); err != nil {
+ return nil, err
+ }
+ keys[i] = key
+ }
+ return keys, nil
+ case *failureAgentMsg:
+ return nil, errors.New("agent: failed to list keys")
+ }
+ panic("unreachable")
+}
+
+// Sign has the agent sign the data using a protocol 2 key as defined
+// in [PROTOCOL.agent] section 2.6.2.
+func (c *client) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
+ return c.SignWithFlags(key, data, 0)
+}
+
+func (c *client) SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error) {
+ req := ssh.Marshal(signRequestAgentMsg{
+ KeyBlob: key.Marshal(),
+ Data: data,
+ Flags: uint32(flags),
+ })
+
+ msg, err := c.call(req)
+ if err != nil {
+ return nil, err
+ }
+
+ switch msg := msg.(type) {
+ case *signResponseAgentMsg:
+ var sig ssh.Signature
+ if err := ssh.Unmarshal(msg.SigBlob, &sig); err != nil {
+ return nil, err
+ }
+
+ return &sig, nil
+ case *failureAgentMsg:
+ return nil, errors.New("agent: failed to sign challenge")
+ }
+ panic("unreachable")
+}
+
+// unmarshal parses an agent message in packet, returning the parsed
+// form and the message type of packet.
+func unmarshal(packet []byte) (interface{}, error) {
+ if len(packet) < 1 {
+ return nil, errors.New("agent: empty packet")
+ }
+ var msg interface{}
+ switch packet[0] {
+ case agentFailure:
+ return new(failureAgentMsg), nil
+ case agentSuccess:
+ return new(successAgentMsg), nil
+ case agentIdentitiesAnswer:
+ msg = new(identitiesAnswerAgentMsg)
+ case agentSignResponse:
+ msg = new(signResponseAgentMsg)
+ case agentV1IdentitiesAnswer:
+ msg = new(agentV1IdentityMsg)
+ default:
+ return nil, fmt.Errorf("agent: unknown type tag %d", packet[0])
+ }
+ if err := ssh.Unmarshal(packet, msg); err != nil {
+ return nil, err
+ }
+ return msg, nil
+}
+
+type rsaKeyMsg struct {
+ Type string `sshtype:"17|25"`
+ N *big.Int
+ E *big.Int
+ D *big.Int
+ Iqmp *big.Int // IQMP = Inverse Q Mod P
+ P *big.Int
+ Q *big.Int
+ Comments string
+ Constraints []byte `ssh:"rest"`
+}
+
+type dsaKeyMsg struct {
+ Type string `sshtype:"17|25"`
+ P *big.Int
+ Q *big.Int
+ G *big.Int
+ Y *big.Int
+ X *big.Int
+ Comments string
+ Constraints []byte `ssh:"rest"`
+}
+
+type ecdsaKeyMsg struct {
+ Type string `sshtype:"17|25"`
+ Curve string
+ KeyBytes []byte
+ D *big.Int
+ Comments string
+ Constraints []byte `ssh:"rest"`
+}
+
+type ed25519KeyMsg struct {
+ Type string `sshtype:"17|25"`
+ Pub []byte
+ Priv []byte
+ Comments string
+ Constraints []byte `ssh:"rest"`
+}
+
+// Insert adds a private key to the agent.
+func (c *client) insertKey(s interface{}, comment string, constraints []byte) error {
+ var req []byte
+ switch k := s.(type) {
+ case *rsa.PrivateKey:
+ if len(k.Primes) != 2 {
+ return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes))
+ }
+ k.Precompute()
+ req = ssh.Marshal(rsaKeyMsg{
+ Type: ssh.KeyAlgoRSA,
+ N: k.N,
+ E: big.NewInt(int64(k.E)),
+ D: k.D,
+ Iqmp: k.Precomputed.Qinv,
+ P: k.Primes[0],
+ Q: k.Primes[1],
+ Comments: comment,
+ Constraints: constraints,
+ })
+ case *dsa.PrivateKey:
+ req = ssh.Marshal(dsaKeyMsg{
+ Type: ssh.KeyAlgoDSA,
+ P: k.P,
+ Q: k.Q,
+ G: k.G,
+ Y: k.Y,
+ X: k.X,
+ Comments: comment,
+ Constraints: constraints,
+ })
+ case *ecdsa.PrivateKey:
+ nistID := fmt.Sprintf("nistp%d", k.Params().BitSize)
+ req = ssh.Marshal(ecdsaKeyMsg{
+ Type: "ecdsa-sha2-" + nistID,
+ Curve: nistID,
+ KeyBytes: elliptic.Marshal(k.Curve, k.X, k.Y),
+ D: k.D,
+ Comments: comment,
+ Constraints: constraints,
+ })
+ case ed25519.PrivateKey:
+ req = ssh.Marshal(ed25519KeyMsg{
+ Type: ssh.KeyAlgoED25519,
+ Pub: []byte(k)[32:],
+ Priv: []byte(k),
+ Comments: comment,
+ Constraints: constraints,
+ })
+ // This function originally supported only *ed25519.PrivateKey, however the
+ // general idiom is to pass ed25519.PrivateKey by value, not by pointer.
+ // We still support the pointer variant for backwards compatibility.
+ case *ed25519.PrivateKey:
+ req = ssh.Marshal(ed25519KeyMsg{
+ Type: ssh.KeyAlgoED25519,
+ Pub: []byte(*k)[32:],
+ Priv: []byte(*k),
+ Comments: comment,
+ Constraints: constraints,
+ })
+ default:
+ return fmt.Errorf("agent: unsupported key type %T", s)
+ }
+
+ // if constraints are present then the message type needs to be changed.
+ if len(constraints) != 0 {
+ req[0] = agentAddIDConstrained
+ }
+
+ resp, err := c.call(req)
+ if err != nil {
+ return err
+ }
+ if _, ok := resp.(*successAgentMsg); ok {
+ return nil
+ }
+ return errors.New("agent: failure")
+}
+
+type rsaCertMsg struct {
+ Type string `sshtype:"17|25"`
+ CertBytes []byte
+ D *big.Int
+ Iqmp *big.Int // IQMP = Inverse Q Mod P
+ P *big.Int
+ Q *big.Int
+ Comments string
+ Constraints []byte `ssh:"rest"`
+}
+
+type dsaCertMsg struct {
+ Type string `sshtype:"17|25"`
+ CertBytes []byte
+ X *big.Int
+ Comments string
+ Constraints []byte `ssh:"rest"`
+}
+
+type ecdsaCertMsg struct {
+ Type string `sshtype:"17|25"`
+ CertBytes []byte
+ D *big.Int
+ Comments string
+ Constraints []byte `ssh:"rest"`
+}
+
+type ed25519CertMsg struct {
+ Type string `sshtype:"17|25"`
+ CertBytes []byte
+ Pub []byte
+ Priv []byte
+ Comments string
+ Constraints []byte `ssh:"rest"`
+}
+
+// Add adds a private key to the agent. If a certificate is given,
+// that certificate is added instead as public key.
+func (c *client) Add(key AddedKey) error {
+ var constraints []byte
+
+ if secs := key.LifetimeSecs; secs != 0 {
+ constraints = append(constraints, ssh.Marshal(constrainLifetimeAgentMsg{secs})...)
+ }
+
+ if key.ConfirmBeforeUse {
+ constraints = append(constraints, agentConstrainConfirm)
+ }
+
+ cert := key.Certificate
+ if cert == nil {
+ return c.insertKey(key.PrivateKey, key.Comment, constraints)
+ }
+ return c.insertCert(key.PrivateKey, cert, key.Comment, constraints)
+}
+
+func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string, constraints []byte) error {
+ var req []byte
+ switch k := s.(type) {
+ case *rsa.PrivateKey:
+ if len(k.Primes) != 2 {
+ return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes))
+ }
+ k.Precompute()
+ req = ssh.Marshal(rsaCertMsg{
+ Type: cert.Type(),
+ CertBytes: cert.Marshal(),
+ D: k.D,
+ Iqmp: k.Precomputed.Qinv,
+ P: k.Primes[0],
+ Q: k.Primes[1],
+ Comments: comment,
+ Constraints: constraints,
+ })
+ case *dsa.PrivateKey:
+ req = ssh.Marshal(dsaCertMsg{
+ Type: cert.Type(),
+ CertBytes: cert.Marshal(),
+ X: k.X,
+ Comments: comment,
+ Constraints: constraints,
+ })
+ case *ecdsa.PrivateKey:
+ req = ssh.Marshal(ecdsaCertMsg{
+ Type: cert.Type(),
+ CertBytes: cert.Marshal(),
+ D: k.D,
+ Comments: comment,
+ Constraints: constraints,
+ })
+ case ed25519.PrivateKey:
+ req = ssh.Marshal(ed25519CertMsg{
+ Type: cert.Type(),
+ CertBytes: cert.Marshal(),
+ Pub: []byte(k)[32:],
+ Priv: []byte(k),
+ Comments: comment,
+ Constraints: constraints,
+ })
+ // This function originally supported only *ed25519.PrivateKey, however the
+ // general idiom is to pass ed25519.PrivateKey by value, not by pointer.
+ // We still support the pointer variant for backwards compatibility.
+ case *ed25519.PrivateKey:
+ req = ssh.Marshal(ed25519CertMsg{
+ Type: cert.Type(),
+ CertBytes: cert.Marshal(),
+ Pub: []byte(*k)[32:],
+ Priv: []byte(*k),
+ Comments: comment,
+ Constraints: constraints,
+ })
+ default:
+ return fmt.Errorf("agent: unsupported key type %T", s)
+ }
+
+ // if constraints are present then the message type needs to be changed.
+ if len(constraints) != 0 {
+ req[0] = agentAddIDConstrained
+ }
+
+ signer, err := ssh.NewSignerFromKey(s)
+ if err != nil {
+ return err
+ }
+ if !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) {
+ return errors.New("agent: signer and cert have different public key")
+ }
+
+ resp, err := c.call(req)
+ if err != nil {
+ return err
+ }
+ if _, ok := resp.(*successAgentMsg); ok {
+ return nil
+ }
+ return errors.New("agent: failure")
+}
+
+// Signers provides a callback for client authentication.
+func (c *client) Signers() ([]ssh.Signer, error) {
+ keys, err := c.List()
+ if err != nil {
+ return nil, err
+ }
+
+ var result []ssh.Signer
+ for _, k := range keys {
+ result = append(result, &agentKeyringSigner{c, k})
+ }
+ return result, nil
+}
+
+type agentKeyringSigner struct {
+ agent *client
+ pub ssh.PublicKey
+}
+
+func (s *agentKeyringSigner) PublicKey() ssh.PublicKey {
+ return s.pub
+}
+
+func (s *agentKeyringSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature, error) {
+ // The agent has its own entropy source, so the rand argument is ignored.
+ return s.agent.Sign(s.pub, data)
+}
+
+func (s *agentKeyringSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*ssh.Signature, error) {
+ if algorithm == "" || algorithm == underlyingAlgo(s.pub.Type()) {
+ return s.Sign(rand, data)
+ }
+
+ var flags SignatureFlags
+ switch algorithm {
+ case ssh.KeyAlgoRSASHA256:
+ flags = SignatureFlagRsaSha256
+ case ssh.KeyAlgoRSASHA512:
+ flags = SignatureFlagRsaSha512
+ default:
+ return nil, fmt.Errorf("agent: unsupported algorithm %q", algorithm)
+ }
+
+ return s.agent.SignWithFlags(s.pub, data, flags)
+}
+
+var _ ssh.AlgorithmSigner = &agentKeyringSigner{}
+
+// certKeyAlgoNames is a mapping from known certificate algorithm names to the
+// corresponding public key signature algorithm.
+//
+// This map must be kept in sync with the one in certs.go.
+var certKeyAlgoNames = map[string]string{
+ ssh.CertAlgoRSAv01: ssh.KeyAlgoRSA,
+ ssh.CertAlgoRSASHA256v01: ssh.KeyAlgoRSASHA256,
+ ssh.CertAlgoRSASHA512v01: ssh.KeyAlgoRSASHA512,
+ ssh.CertAlgoDSAv01: ssh.KeyAlgoDSA,
+ ssh.CertAlgoECDSA256v01: ssh.KeyAlgoECDSA256,
+ ssh.CertAlgoECDSA384v01: ssh.KeyAlgoECDSA384,
+ ssh.CertAlgoECDSA521v01: ssh.KeyAlgoECDSA521,
+ ssh.CertAlgoSKECDSA256v01: ssh.KeyAlgoSKECDSA256,
+ ssh.CertAlgoED25519v01: ssh.KeyAlgoED25519,
+ ssh.CertAlgoSKED25519v01: ssh.KeyAlgoSKED25519,
+}
+
+// underlyingAlgo returns the signature algorithm associated with algo (which is
+// an advertised or negotiated public key or host key algorithm). These are
+// usually the same, except for certificate algorithms.
+func underlyingAlgo(algo string) string {
+ if a, ok := certKeyAlgoNames[algo]; ok {
+ return a
+ }
+ return algo
+}
+
+// Calls an extension method. It is up to the agent implementation as to whether or not
+// any particular extension is supported and may always return an error. Because the
+// type of the response is up to the implementation, this returns the bytes of the
+// response and does not attempt any type of unmarshalling.
+func (c *client) Extension(extensionType string, contents []byte) ([]byte, error) {
+ req := ssh.Marshal(extensionAgentMsg{
+ ExtensionType: extensionType,
+ Contents: contents,
+ })
+ buf, err := c.callRaw(req)
+ if err != nil {
+ return nil, err
+ }
+ if len(buf) == 0 {
+ return nil, errors.New("agent: failure; empty response")
+ }
+ // [PROTOCOL.agent] section 4.7 indicates that an SSH_AGENT_FAILURE message
+ // represents an agent that does not support the extension
+ if buf[0] == agentFailure {
+ return nil, ErrExtensionUnsupported
+ }
+ if buf[0] == agentExtensionFailure {
+ return nil, errors.New("agent: generic extension failure")
+ }
+
+ return buf, nil
+}
diff --git a/vendor/golang.org/x/crypto/ssh/agent/forward.go b/vendor/golang.org/x/crypto/ssh/agent/forward.go
new file mode 100644
index 00000000..fd24ba90
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/agent/forward.go
@@ -0,0 +1,103 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package agent
+
+import (
+ "errors"
+ "io"
+ "net"
+ "sync"
+
+ "golang.org/x/crypto/ssh"
+)
+
+// RequestAgentForwarding sets up agent forwarding for the session.
+// ForwardToAgent or ForwardToRemote should be called to route
+// the authentication requests.
+func RequestAgentForwarding(session *ssh.Session) error {
+ ok, err := session.SendRequest("auth-agent-req@openssh.com", true, nil)
+ if err != nil {
+ return err
+ }
+ if !ok {
+ return errors.New("forwarding request denied")
+ }
+ return nil
+}
+
+// ForwardToAgent routes authentication requests to the given keyring.
+func ForwardToAgent(client *ssh.Client, keyring Agent) error {
+ channels := client.HandleChannelOpen(channelType)
+ if channels == nil {
+ return errors.New("agent: already have handler for " + channelType)
+ }
+
+ go func() {
+ for ch := range channels {
+ channel, reqs, err := ch.Accept()
+ if err != nil {
+ continue
+ }
+ go ssh.DiscardRequests(reqs)
+ go func() {
+ ServeAgent(keyring, channel)
+ channel.Close()
+ }()
+ }
+ }()
+ return nil
+}
+
+const channelType = "auth-agent@openssh.com"
+
+// ForwardToRemote routes authentication requests to the ssh-agent
+// process serving on the given unix socket.
+func ForwardToRemote(client *ssh.Client, addr string) error {
+ channels := client.HandleChannelOpen(channelType)
+ if channels == nil {
+ return errors.New("agent: already have handler for " + channelType)
+ }
+ conn, err := net.Dial("unix", addr)
+ if err != nil {
+ return err
+ }
+ conn.Close()
+
+ go func() {
+ for ch := range channels {
+ channel, reqs, err := ch.Accept()
+ if err != nil {
+ continue
+ }
+ go ssh.DiscardRequests(reqs)
+ go forwardUnixSocket(channel, addr)
+ }
+ }()
+ return nil
+}
+
+func forwardUnixSocket(channel ssh.Channel, addr string) {
+ conn, err := net.Dial("unix", addr)
+ if err != nil {
+ return
+ }
+
+ var wg sync.WaitGroup
+ wg.Add(2)
+ go func() {
+ io.Copy(conn, channel)
+ conn.(*net.UnixConn).CloseWrite()
+ wg.Done()
+ }()
+ go func() {
+ io.Copy(channel, conn)
+ channel.CloseWrite()
+ wg.Done()
+ }()
+
+ wg.Wait()
+ conn.Close()
+ channel.Close()
+}
diff --git a/vendor/golang.org/x/crypto/ssh/agent/keyring.go b/vendor/golang.org/x/crypto/ssh/agent/keyring.go
new file mode 100644
index 00000000..21bfa870
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/agent/keyring.go
@@ -0,0 +1,241 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package agent
+
+import (
+ "bytes"
+ "crypto/rand"
+ "crypto/subtle"
+ "errors"
+ "fmt"
+ "sync"
+ "time"
+
+ "golang.org/x/crypto/ssh"
+)
+
+type privKey struct {
+ signer ssh.Signer
+ comment string
+ expire *time.Time
+}
+
+type keyring struct {
+ mu sync.Mutex
+ keys []privKey
+
+ locked bool
+ passphrase []byte
+}
+
+var errLocked = errors.New("agent: locked")
+
+// NewKeyring returns an Agent that holds keys in memory. It is safe
+// for concurrent use by multiple goroutines.
+func NewKeyring() Agent {
+ return &keyring{}
+}
+
+// RemoveAll removes all identities.
+func (r *keyring) RemoveAll() error {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if r.locked {
+ return errLocked
+ }
+
+ r.keys = nil
+ return nil
+}
+
+// removeLocked does the actual key removal. The caller must already be holding the
+// keyring mutex.
+func (r *keyring) removeLocked(want []byte) error {
+ found := false
+ for i := 0; i < len(r.keys); {
+ if bytes.Equal(r.keys[i].signer.PublicKey().Marshal(), want) {
+ found = true
+ r.keys[i] = r.keys[len(r.keys)-1]
+ r.keys = r.keys[:len(r.keys)-1]
+ continue
+ } else {
+ i++
+ }
+ }
+
+ if !found {
+ return errors.New("agent: key not found")
+ }
+ return nil
+}
+
+// Remove removes all identities with the given public key.
+func (r *keyring) Remove(key ssh.PublicKey) error {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if r.locked {
+ return errLocked
+ }
+
+ return r.removeLocked(key.Marshal())
+}
+
+// Lock locks the agent. Sign and Remove will fail, and List will return an empty list.
+func (r *keyring) Lock(passphrase []byte) error {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if r.locked {
+ return errLocked
+ }
+
+ r.locked = true
+ r.passphrase = passphrase
+ return nil
+}
+
+// Unlock undoes the effect of Lock
+func (r *keyring) Unlock(passphrase []byte) error {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if !r.locked {
+ return errors.New("agent: not locked")
+ }
+ if 1 != subtle.ConstantTimeCompare(passphrase, r.passphrase) {
+ return fmt.Errorf("agent: incorrect passphrase")
+ }
+
+ r.locked = false
+ r.passphrase = nil
+ return nil
+}
+
+// expireKeysLocked removes expired keys from the keyring. If a key was added
+// with a lifetimesecs contraint and seconds >= lifetimesecs seconds have
+// elapsed, it is removed. The caller *must* be holding the keyring mutex.
+func (r *keyring) expireKeysLocked() {
+ for _, k := range r.keys {
+ if k.expire != nil && time.Now().After(*k.expire) {
+ r.removeLocked(k.signer.PublicKey().Marshal())
+ }
+ }
+}
+
+// List returns the identities known to the agent.
+func (r *keyring) List() ([]*Key, error) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if r.locked {
+ // section 2.7: locked agents return empty.
+ return nil, nil
+ }
+
+ r.expireKeysLocked()
+ var ids []*Key
+ for _, k := range r.keys {
+ pub := k.signer.PublicKey()
+ ids = append(ids, &Key{
+ Format: pub.Type(),
+ Blob: pub.Marshal(),
+ Comment: k.comment})
+ }
+ return ids, nil
+}
+
+// Insert adds a private key to the keyring. If a certificate
+// is given, that certificate is added as public key. Note that
+// any constraints given are ignored.
+func (r *keyring) Add(key AddedKey) error {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if r.locked {
+ return errLocked
+ }
+ signer, err := ssh.NewSignerFromKey(key.PrivateKey)
+
+ if err != nil {
+ return err
+ }
+
+ if cert := key.Certificate; cert != nil {
+ signer, err = ssh.NewCertSigner(cert, signer)
+ if err != nil {
+ return err
+ }
+ }
+
+ p := privKey{
+ signer: signer,
+ comment: key.Comment,
+ }
+
+ if key.LifetimeSecs > 0 {
+ t := time.Now().Add(time.Duration(key.LifetimeSecs) * time.Second)
+ p.expire = &t
+ }
+
+ r.keys = append(r.keys, p)
+
+ return nil
+}
+
+// Sign returns a signature for the data.
+func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
+ return r.SignWithFlags(key, data, 0)
+}
+
+func (r *keyring) SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if r.locked {
+ return nil, errLocked
+ }
+
+ r.expireKeysLocked()
+ wanted := key.Marshal()
+ for _, k := range r.keys {
+ if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) {
+ if flags == 0 {
+ return k.signer.Sign(rand.Reader, data)
+ } else {
+ if algorithmSigner, ok := k.signer.(ssh.AlgorithmSigner); !ok {
+ return nil, fmt.Errorf("agent: signature does not support non-default signature algorithm: %T", k.signer)
+ } else {
+ var algorithm string
+ switch flags {
+ case SignatureFlagRsaSha256:
+ algorithm = ssh.KeyAlgoRSASHA256
+ case SignatureFlagRsaSha512:
+ algorithm = ssh.KeyAlgoRSASHA512
+ default:
+ return nil, fmt.Errorf("agent: unsupported signature flags: %d", flags)
+ }
+ return algorithmSigner.SignWithAlgorithm(rand.Reader, data, algorithm)
+ }
+ }
+ }
+ }
+ return nil, errors.New("not found")
+}
+
+// Signers returns signers for all the known keys.
+func (r *keyring) Signers() ([]ssh.Signer, error) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if r.locked {
+ return nil, errLocked
+ }
+
+ r.expireKeysLocked()
+ s := make([]ssh.Signer, 0, len(r.keys))
+ for _, k := range r.keys {
+ s = append(s, k.signer)
+ }
+ return s, nil
+}
+
+// The keyring does not support any extensions
+func (r *keyring) Extension(extensionType string, contents []byte) ([]byte, error) {
+ return nil, ErrExtensionUnsupported
+}
diff --git a/vendor/golang.org/x/crypto/ssh/agent/server.go b/vendor/golang.org/x/crypto/ssh/agent/server.go
new file mode 100644
index 00000000..e35ca7ce
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/agent/server.go
@@ -0,0 +1,570 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package agent
+
+import (
+ "crypto/dsa"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rsa"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "math/big"
+
+ "golang.org/x/crypto/ssh"
+)
+
+// server wraps an Agent and uses it to implement the agent side of
+// the SSH-agent, wire protocol.
+type server struct {
+ agent Agent
+}
+
+func (s *server) processRequestBytes(reqData []byte) []byte {
+ rep, err := s.processRequest(reqData)
+ if err != nil {
+ if err != errLocked {
+ // TODO(hanwen): provide better logging interface?
+ log.Printf("agent %d: %v", reqData[0], err)
+ }
+ return []byte{agentFailure}
+ }
+
+ if err == nil && rep == nil {
+ return []byte{agentSuccess}
+ }
+
+ return ssh.Marshal(rep)
+}
+
+func marshalKey(k *Key) []byte {
+ var record struct {
+ Blob []byte
+ Comment string
+ }
+ record.Blob = k.Marshal()
+ record.Comment = k.Comment
+
+ return ssh.Marshal(&record)
+}
+
+// See [PROTOCOL.agent], section 2.5.1.
+const agentV1IdentitiesAnswer = 2
+
+type agentV1IdentityMsg struct {
+ Numkeys uint32 `sshtype:"2"`
+}
+
+type agentRemoveIdentityMsg struct {
+ KeyBlob []byte `sshtype:"18"`
+}
+
+type agentLockMsg struct {
+ Passphrase []byte `sshtype:"22"`
+}
+
+type agentUnlockMsg struct {
+ Passphrase []byte `sshtype:"23"`
+}
+
+func (s *server) processRequest(data []byte) (interface{}, error) {
+ switch data[0] {
+ case agentRequestV1Identities:
+ return &agentV1IdentityMsg{0}, nil
+
+ case agentRemoveAllV1Identities:
+ return nil, nil
+
+ case agentRemoveIdentity:
+ var req agentRemoveIdentityMsg
+ if err := ssh.Unmarshal(data, &req); err != nil {
+ return nil, err
+ }
+
+ var wk wireKey
+ if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
+ return nil, err
+ }
+
+ return nil, s.agent.Remove(&Key{Format: wk.Format, Blob: req.KeyBlob})
+
+ case agentRemoveAllIdentities:
+ return nil, s.agent.RemoveAll()
+
+ case agentLock:
+ var req agentLockMsg
+ if err := ssh.Unmarshal(data, &req); err != nil {
+ return nil, err
+ }
+
+ return nil, s.agent.Lock(req.Passphrase)
+
+ case agentUnlock:
+ var req agentUnlockMsg
+ if err := ssh.Unmarshal(data, &req); err != nil {
+ return nil, err
+ }
+ return nil, s.agent.Unlock(req.Passphrase)
+
+ case agentSignRequest:
+ var req signRequestAgentMsg
+ if err := ssh.Unmarshal(data, &req); err != nil {
+ return nil, err
+ }
+
+ var wk wireKey
+ if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
+ return nil, err
+ }
+
+ k := &Key{
+ Format: wk.Format,
+ Blob: req.KeyBlob,
+ }
+
+ var sig *ssh.Signature
+ var err error
+ if extendedAgent, ok := s.agent.(ExtendedAgent); ok {
+ sig, err = extendedAgent.SignWithFlags(k, req.Data, SignatureFlags(req.Flags))
+ } else {
+ sig, err = s.agent.Sign(k, req.Data)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+ return &signResponseAgentMsg{SigBlob: ssh.Marshal(sig)}, nil
+
+ case agentRequestIdentities:
+ keys, err := s.agent.List()
+ if err != nil {
+ return nil, err
+ }
+
+ rep := identitiesAnswerAgentMsg{
+ NumKeys: uint32(len(keys)),
+ }
+ for _, k := range keys {
+ rep.Keys = append(rep.Keys, marshalKey(k)...)
+ }
+ return rep, nil
+
+ case agentAddIDConstrained, agentAddIdentity:
+ return nil, s.insertIdentity(data)
+
+ case agentExtension:
+ // Return a stub object where the whole contents of the response gets marshaled.
+ var responseStub struct {
+ Rest []byte `ssh:"rest"`
+ }
+
+ if extendedAgent, ok := s.agent.(ExtendedAgent); !ok {
+ // If this agent doesn't implement extensions, [PROTOCOL.agent] section 4.7
+ // requires that we return a standard SSH_AGENT_FAILURE message.
+ responseStub.Rest = []byte{agentFailure}
+ } else {
+ var req extensionAgentMsg
+ if err := ssh.Unmarshal(data, &req); err != nil {
+ return nil, err
+ }
+ res, err := extendedAgent.Extension(req.ExtensionType, req.Contents)
+ if err != nil {
+ // If agent extensions are unsupported, return a standard SSH_AGENT_FAILURE
+ // message as required by [PROTOCOL.agent] section 4.7.
+ if err == ErrExtensionUnsupported {
+ responseStub.Rest = []byte{agentFailure}
+ } else {
+ // As the result of any other error processing an extension request,
+ // [PROTOCOL.agent] section 4.7 requires that we return a
+ // SSH_AGENT_EXTENSION_FAILURE code.
+ responseStub.Rest = []byte{agentExtensionFailure}
+ }
+ } else {
+ if len(res) == 0 {
+ return nil, nil
+ }
+ responseStub.Rest = res
+ }
+ }
+
+ return responseStub, nil
+ }
+
+ return nil, fmt.Errorf("unknown opcode %d", data[0])
+}
+
+func parseConstraints(constraints []byte) (lifetimeSecs uint32, confirmBeforeUse bool, extensions []ConstraintExtension, err error) {
+ for len(constraints) != 0 {
+ switch constraints[0] {
+ case agentConstrainLifetime:
+ lifetimeSecs = binary.BigEndian.Uint32(constraints[1:5])
+ constraints = constraints[5:]
+ case agentConstrainConfirm:
+ confirmBeforeUse = true
+ constraints = constraints[1:]
+ case agentConstrainExtension, agentConstrainExtensionV00:
+ var msg constrainExtensionAgentMsg
+ if err = ssh.Unmarshal(constraints, &msg); err != nil {
+ return 0, false, nil, err
+ }
+ extensions = append(extensions, ConstraintExtension{
+ ExtensionName: msg.ExtensionName,
+ ExtensionDetails: msg.ExtensionDetails,
+ })
+ constraints = msg.Rest
+ default:
+ return 0, false, nil, fmt.Errorf("unknown constraint type: %d", constraints[0])
+ }
+ }
+ return
+}
+
+func setConstraints(key *AddedKey, constraintBytes []byte) error {
+ lifetimeSecs, confirmBeforeUse, constraintExtensions, err := parseConstraints(constraintBytes)
+ if err != nil {
+ return err
+ }
+
+ key.LifetimeSecs = lifetimeSecs
+ key.ConfirmBeforeUse = confirmBeforeUse
+ key.ConstraintExtensions = constraintExtensions
+ return nil
+}
+
+func parseRSAKey(req []byte) (*AddedKey, error) {
+ var k rsaKeyMsg
+ if err := ssh.Unmarshal(req, &k); err != nil {
+ return nil, err
+ }
+ if k.E.BitLen() > 30 {
+ return nil, errors.New("agent: RSA public exponent too large")
+ }
+ priv := &rsa.PrivateKey{
+ PublicKey: rsa.PublicKey{
+ E: int(k.E.Int64()),
+ N: k.N,
+ },
+ D: k.D,
+ Primes: []*big.Int{k.P, k.Q},
+ }
+ priv.Precompute()
+
+ addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
+ return nil, err
+ }
+ return addedKey, nil
+}
+
+func parseEd25519Key(req []byte) (*AddedKey, error) {
+ var k ed25519KeyMsg
+ if err := ssh.Unmarshal(req, &k); err != nil {
+ return nil, err
+ }
+ priv := ed25519.PrivateKey(k.Priv)
+
+ addedKey := &AddedKey{PrivateKey: &priv, Comment: k.Comments}
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
+ return nil, err
+ }
+ return addedKey, nil
+}
+
+func parseDSAKey(req []byte) (*AddedKey, error) {
+ var k dsaKeyMsg
+ if err := ssh.Unmarshal(req, &k); err != nil {
+ return nil, err
+ }
+ priv := &dsa.PrivateKey{
+ PublicKey: dsa.PublicKey{
+ Parameters: dsa.Parameters{
+ P: k.P,
+ Q: k.Q,
+ G: k.G,
+ },
+ Y: k.Y,
+ },
+ X: k.X,
+ }
+
+ addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
+ return nil, err
+ }
+ return addedKey, nil
+}
+
+func unmarshalECDSA(curveName string, keyBytes []byte, privScalar *big.Int) (priv *ecdsa.PrivateKey, err error) {
+ priv = &ecdsa.PrivateKey{
+ D: privScalar,
+ }
+
+ switch curveName {
+ case "nistp256":
+ priv.Curve = elliptic.P256()
+ case "nistp384":
+ priv.Curve = elliptic.P384()
+ case "nistp521":
+ priv.Curve = elliptic.P521()
+ default:
+ return nil, fmt.Errorf("agent: unknown curve %q", curveName)
+ }
+
+ priv.X, priv.Y = elliptic.Unmarshal(priv.Curve, keyBytes)
+ if priv.X == nil || priv.Y == nil {
+ return nil, errors.New("agent: point not on curve")
+ }
+
+ return priv, nil
+}
+
+func parseEd25519Cert(req []byte) (*AddedKey, error) {
+ var k ed25519CertMsg
+ if err := ssh.Unmarshal(req, &k); err != nil {
+ return nil, err
+ }
+ pubKey, err := ssh.ParsePublicKey(k.CertBytes)
+ if err != nil {
+ return nil, err
+ }
+ priv := ed25519.PrivateKey(k.Priv)
+ cert, ok := pubKey.(*ssh.Certificate)
+ if !ok {
+ return nil, errors.New("agent: bad ED25519 certificate")
+ }
+
+ addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
+ return nil, err
+ }
+ return addedKey, nil
+}
+
+func parseECDSAKey(req []byte) (*AddedKey, error) {
+ var k ecdsaKeyMsg
+ if err := ssh.Unmarshal(req, &k); err != nil {
+ return nil, err
+ }
+
+ priv, err := unmarshalECDSA(k.Curve, k.KeyBytes, k.D)
+ if err != nil {
+ return nil, err
+ }
+
+ addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
+ return nil, err
+ }
+ return addedKey, nil
+}
+
+func parseRSACert(req []byte) (*AddedKey, error) {
+ var k rsaCertMsg
+ if err := ssh.Unmarshal(req, &k); err != nil {
+ return nil, err
+ }
+
+ pubKey, err := ssh.ParsePublicKey(k.CertBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ cert, ok := pubKey.(*ssh.Certificate)
+ if !ok {
+ return nil, errors.New("agent: bad RSA certificate")
+ }
+
+ // An RSA publickey as marshaled by rsaPublicKey.Marshal() in keys.go
+ var rsaPub struct {
+ Name string
+ E *big.Int
+ N *big.Int
+ }
+ if err := ssh.Unmarshal(cert.Key.Marshal(), &rsaPub); err != nil {
+ return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
+ }
+
+ if rsaPub.E.BitLen() > 30 {
+ return nil, errors.New("agent: RSA public exponent too large")
+ }
+
+ priv := rsa.PrivateKey{
+ PublicKey: rsa.PublicKey{
+ E: int(rsaPub.E.Int64()),
+ N: rsaPub.N,
+ },
+ D: k.D,
+ Primes: []*big.Int{k.Q, k.P},
+ }
+ priv.Precompute()
+
+ addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
+ return nil, err
+ }
+ return addedKey, nil
+}
+
+func parseDSACert(req []byte) (*AddedKey, error) {
+ var k dsaCertMsg
+ if err := ssh.Unmarshal(req, &k); err != nil {
+ return nil, err
+ }
+ pubKey, err := ssh.ParsePublicKey(k.CertBytes)
+ if err != nil {
+ return nil, err
+ }
+ cert, ok := pubKey.(*ssh.Certificate)
+ if !ok {
+ return nil, errors.New("agent: bad DSA certificate")
+ }
+
+ // A DSA publickey as marshaled by dsaPublicKey.Marshal() in keys.go
+ var w struct {
+ Name string
+ P, Q, G, Y *big.Int
+ }
+ if err := ssh.Unmarshal(cert.Key.Marshal(), &w); err != nil {
+ return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
+ }
+
+ priv := &dsa.PrivateKey{
+ PublicKey: dsa.PublicKey{
+ Parameters: dsa.Parameters{
+ P: w.P,
+ Q: w.Q,
+ G: w.G,
+ },
+ Y: w.Y,
+ },
+ X: k.X,
+ }
+
+ addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
+ return nil, err
+ }
+ return addedKey, nil
+}
+
+func parseECDSACert(req []byte) (*AddedKey, error) {
+ var k ecdsaCertMsg
+ if err := ssh.Unmarshal(req, &k); err != nil {
+ return nil, err
+ }
+
+ pubKey, err := ssh.ParsePublicKey(k.CertBytes)
+ if err != nil {
+ return nil, err
+ }
+ cert, ok := pubKey.(*ssh.Certificate)
+ if !ok {
+ return nil, errors.New("agent: bad ECDSA certificate")
+ }
+
+ // An ECDSA publickey as marshaled by ecdsaPublicKey.Marshal() in keys.go
+ var ecdsaPub struct {
+ Name string
+ ID string
+ Key []byte
+ }
+ if err := ssh.Unmarshal(cert.Key.Marshal(), &ecdsaPub); err != nil {
+ return nil, err
+ }
+
+ priv, err := unmarshalECDSA(ecdsaPub.ID, ecdsaPub.Key, k.D)
+ if err != nil {
+ return nil, err
+ }
+
+ addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
+ return nil, err
+ }
+ return addedKey, nil
+}
+
+func (s *server) insertIdentity(req []byte) error {
+ var record struct {
+ Type string `sshtype:"17|25"`
+ Rest []byte `ssh:"rest"`
+ }
+
+ if err := ssh.Unmarshal(req, &record); err != nil {
+ return err
+ }
+
+ var addedKey *AddedKey
+ var err error
+
+ switch record.Type {
+ case ssh.KeyAlgoRSA:
+ addedKey, err = parseRSAKey(req)
+ case ssh.KeyAlgoDSA:
+ addedKey, err = parseDSAKey(req)
+ case ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521:
+ addedKey, err = parseECDSAKey(req)
+ case ssh.KeyAlgoED25519:
+ addedKey, err = parseEd25519Key(req)
+ case ssh.CertAlgoRSAv01:
+ addedKey, err = parseRSACert(req)
+ case ssh.CertAlgoDSAv01:
+ addedKey, err = parseDSACert(req)
+ case ssh.CertAlgoECDSA256v01, ssh.CertAlgoECDSA384v01, ssh.CertAlgoECDSA521v01:
+ addedKey, err = parseECDSACert(req)
+ case ssh.CertAlgoED25519v01:
+ addedKey, err = parseEd25519Cert(req)
+ default:
+ return fmt.Errorf("agent: not implemented: %q", record.Type)
+ }
+
+ if err != nil {
+ return err
+ }
+ return s.agent.Add(*addedKey)
+}
+
+// ServeAgent serves the agent protocol on the given connection. It
+// returns when an I/O error occurs.
+func ServeAgent(agent Agent, c io.ReadWriter) error {
+ s := &server{agent}
+
+ var length [4]byte
+ for {
+ if _, err := io.ReadFull(c, length[:]); err != nil {
+ return err
+ }
+ l := binary.BigEndian.Uint32(length[:])
+ if l == 0 {
+ return fmt.Errorf("agent: request size is 0")
+ }
+ if l > maxAgentResponseBytes {
+ // We also cap requests.
+ return fmt.Errorf("agent: request too large: %d", l)
+ }
+
+ req := make([]byte, l)
+ if _, err := io.ReadFull(c, req); err != nil {
+ return err
+ }
+
+ repData := s.processRequestBytes(req)
+ if len(repData) > maxAgentResponseBytes {
+ return fmt.Errorf("agent: reply too large: %d bytes", len(repData))
+ }
+
+ binary.BigEndian.PutUint32(length[:], uint32(len(repData)))
+ if _, err := c.Write(length[:]); err != nil {
+ return err
+ }
+ if _, err := c.Write(repData); err != nil {
+ return err
+ }
+ }
+}
diff --git a/vendor/golang.org/x/crypto/ssh/buffer.go b/vendor/golang.org/x/crypto/ssh/buffer.go
new file mode 100644
index 00000000..1ab07d07
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/buffer.go
@@ -0,0 +1,97 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "io"
+ "sync"
+)
+
+// buffer provides a linked list buffer for data exchange
+// between producer and consumer. Theoretically the buffer is
+// of unlimited capacity as it does no allocation of its own.
+type buffer struct {
+ // protects concurrent access to head, tail and closed
+ *sync.Cond
+
+ head *element // the buffer that will be read first
+ tail *element // the buffer that will be read last
+
+ closed bool
+}
+
+// An element represents a single link in a linked list.
+type element struct {
+ buf []byte
+ next *element
+}
+
+// newBuffer returns an empty buffer that is not closed.
+func newBuffer() *buffer {
+ e := new(element)
+ b := &buffer{
+ Cond: newCond(),
+ head: e,
+ tail: e,
+ }
+ return b
+}
+
+// write makes buf available for Read to receive.
+// buf must not be modified after the call to write.
+func (b *buffer) write(buf []byte) {
+ b.Cond.L.Lock()
+ e := &element{buf: buf}
+ b.tail.next = e
+ b.tail = e
+ b.Cond.Signal()
+ b.Cond.L.Unlock()
+}
+
+// eof closes the buffer. Reads from the buffer once all
+// the data has been consumed will receive io.EOF.
+func (b *buffer) eof() {
+ b.Cond.L.Lock()
+ b.closed = true
+ b.Cond.Signal()
+ b.Cond.L.Unlock()
+}
+
+// Read reads data from the internal buffer in buf. Reads will block
+// if no data is available, or until the buffer is closed.
+func (b *buffer) Read(buf []byte) (n int, err error) {
+ b.Cond.L.Lock()
+ defer b.Cond.L.Unlock()
+
+ for len(buf) > 0 {
+ // if there is data in b.head, copy it
+ if len(b.head.buf) > 0 {
+ r := copy(buf, b.head.buf)
+ buf, b.head.buf = buf[r:], b.head.buf[r:]
+ n += r
+ continue
+ }
+ // if there is a next buffer, make it the head
+ if len(b.head.buf) == 0 && b.head != b.tail {
+ b.head = b.head.next
+ continue
+ }
+
+ // if at least one byte has been copied, return
+ if n > 0 {
+ break
+ }
+
+ // if nothing was read, and there is nothing outstanding
+ // check to see if the buffer is closed.
+ if b.closed {
+ err = io.EOF
+ break
+ }
+ // out of buffers, wait for producer
+ b.Cond.Wait()
+ }
+ return
+}
diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go
new file mode 100644
index 00000000..27d0e14a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/certs.go
@@ -0,0 +1,611 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "sort"
+ "time"
+)
+
+// Certificate algorithm names from [PROTOCOL.certkeys]. These values can appear
+// in Certificate.Type, PublicKey.Type, and ClientConfig.HostKeyAlgorithms.
+// Unlike key algorithm names, these are not passed to AlgorithmSigner nor
+// returned by MultiAlgorithmSigner and don't appear in the Signature.Format
+// field.
+const (
+ CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
+ CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
+ CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
+ CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
+ CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
+ CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
+ CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com"
+ CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com"
+
+ // CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can't appear as a
+ // Certificate.Type (or PublicKey.Type), but only in
+ // ClientConfig.HostKeyAlgorithms.
+ CertAlgoRSASHA256v01 = "rsa-sha2-256-cert-v01@openssh.com"
+ CertAlgoRSASHA512v01 = "rsa-sha2-512-cert-v01@openssh.com"
+)
+
+const (
+ // Deprecated: use CertAlgoRSAv01.
+ CertSigAlgoRSAv01 = CertAlgoRSAv01
+ // Deprecated: use CertAlgoRSASHA256v01.
+ CertSigAlgoRSASHA2256v01 = CertAlgoRSASHA256v01
+ // Deprecated: use CertAlgoRSASHA512v01.
+ CertSigAlgoRSASHA2512v01 = CertAlgoRSASHA512v01
+)
+
+// Certificate types distinguish between host and user
+// certificates. The values can be set in the CertType field of
+// Certificate.
+const (
+ UserCert = 1
+ HostCert = 2
+)
+
+// Signature represents a cryptographic signature.
+type Signature struct {
+ Format string
+ Blob []byte
+ Rest []byte `ssh:"rest"`
+}
+
+// CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that
+// a certificate does not expire.
+const CertTimeInfinity = 1<<64 - 1
+
+// An Certificate represents an OpenSSH certificate as defined in
+// [PROTOCOL.certkeys]?rev=1.8. The Certificate type implements the
+// PublicKey interface, so it can be unmarshaled using
+// ParsePublicKey.
+type Certificate struct {
+ Nonce []byte
+ Key PublicKey
+ Serial uint64
+ CertType uint32
+ KeyId string
+ ValidPrincipals []string
+ ValidAfter uint64
+ ValidBefore uint64
+ Permissions
+ Reserved []byte
+ SignatureKey PublicKey
+ Signature *Signature
+}
+
+// genericCertData holds the key-independent part of the certificate data.
+// Overall, certificates contain an nonce, public key fields and
+// key-independent fields.
+type genericCertData struct {
+ Serial uint64
+ CertType uint32
+ KeyId string
+ ValidPrincipals []byte
+ ValidAfter uint64
+ ValidBefore uint64
+ CriticalOptions []byte
+ Extensions []byte
+ Reserved []byte
+ SignatureKey []byte
+ Signature []byte
+}
+
+func marshalStringList(namelist []string) []byte {
+ var to []byte
+ for _, name := range namelist {
+ s := struct{ N string }{name}
+ to = append(to, Marshal(&s)...)
+ }
+ return to
+}
+
+type optionsTuple struct {
+ Key string
+ Value []byte
+}
+
+type optionsTupleValue struct {
+ Value string
+}
+
+// serialize a map of critical options or extensions
+// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
+// we need two length prefixes for a non-empty string value
+func marshalTuples(tups map[string]string) []byte {
+ keys := make([]string, 0, len(tups))
+ for key := range tups {
+ keys = append(keys, key)
+ }
+ sort.Strings(keys)
+
+ var ret []byte
+ for _, key := range keys {
+ s := optionsTuple{Key: key}
+ if value := tups[key]; len(value) > 0 {
+ s.Value = Marshal(&optionsTupleValue{value})
+ }
+ ret = append(ret, Marshal(&s)...)
+ }
+ return ret
+}
+
+// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
+// we need two length prefixes for a non-empty option value
+func parseTuples(in []byte) (map[string]string, error) {
+ tups := map[string]string{}
+ var lastKey string
+ var haveLastKey bool
+
+ for len(in) > 0 {
+ var key, val, extra []byte
+ var ok bool
+
+ if key, in, ok = parseString(in); !ok {
+ return nil, errShortRead
+ }
+ keyStr := string(key)
+ // according to [PROTOCOL.certkeys], the names must be in
+ // lexical order.
+ if haveLastKey && keyStr <= lastKey {
+ return nil, fmt.Errorf("ssh: certificate options are not in lexical order")
+ }
+ lastKey, haveLastKey = keyStr, true
+ // the next field is a data field, which if non-empty has a string embedded
+ if val, in, ok = parseString(in); !ok {
+ return nil, errShortRead
+ }
+ if len(val) > 0 {
+ val, extra, ok = parseString(val)
+ if !ok {
+ return nil, errShortRead
+ }
+ if len(extra) > 0 {
+ return nil, fmt.Errorf("ssh: unexpected trailing data after certificate option value")
+ }
+ tups[keyStr] = string(val)
+ } else {
+ tups[keyStr] = ""
+ }
+ }
+ return tups, nil
+}
+
+func parseCert(in []byte, privAlgo string) (*Certificate, error) {
+ nonce, rest, ok := parseString(in)
+ if !ok {
+ return nil, errShortRead
+ }
+
+ key, rest, err := parsePubKey(rest, privAlgo)
+ if err != nil {
+ return nil, err
+ }
+
+ var g genericCertData
+ if err := Unmarshal(rest, &g); err != nil {
+ return nil, err
+ }
+
+ c := &Certificate{
+ Nonce: nonce,
+ Key: key,
+ Serial: g.Serial,
+ CertType: g.CertType,
+ KeyId: g.KeyId,
+ ValidAfter: g.ValidAfter,
+ ValidBefore: g.ValidBefore,
+ }
+
+ for principals := g.ValidPrincipals; len(principals) > 0; {
+ principal, rest, ok := parseString(principals)
+ if !ok {
+ return nil, errShortRead
+ }
+ c.ValidPrincipals = append(c.ValidPrincipals, string(principal))
+ principals = rest
+ }
+
+ c.CriticalOptions, err = parseTuples(g.CriticalOptions)
+ if err != nil {
+ return nil, err
+ }
+ c.Extensions, err = parseTuples(g.Extensions)
+ if err != nil {
+ return nil, err
+ }
+ c.Reserved = g.Reserved
+ k, err := ParsePublicKey(g.SignatureKey)
+ if err != nil {
+ return nil, err
+ }
+
+ c.SignatureKey = k
+ c.Signature, rest, ok = parseSignatureBody(g.Signature)
+ if !ok || len(rest) > 0 {
+ return nil, errors.New("ssh: signature parse error")
+ }
+
+ return c, nil
+}
+
+type openSSHCertSigner struct {
+ pub *Certificate
+ signer Signer
+}
+
+type algorithmOpenSSHCertSigner struct {
+ *openSSHCertSigner
+ algorithmSigner AlgorithmSigner
+}
+
+// NewCertSigner returns a Signer that signs with the given Certificate, whose
+// private key is held by signer. It returns an error if the public key in cert
+// doesn't match the key used by signer.
+func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
+ if !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) {
+ return nil, errors.New("ssh: signer and cert have different public key")
+ }
+
+ switch s := signer.(type) {
+ case MultiAlgorithmSigner:
+ return &multiAlgorithmSigner{
+ AlgorithmSigner: &algorithmOpenSSHCertSigner{
+ &openSSHCertSigner{cert, signer}, s},
+ supportedAlgorithms: s.Algorithms(),
+ }, nil
+ case AlgorithmSigner:
+ return &algorithmOpenSSHCertSigner{
+ &openSSHCertSigner{cert, signer}, s}, nil
+ default:
+ return &openSSHCertSigner{cert, signer}, nil
+ }
+}
+
+func (s *openSSHCertSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
+ return s.signer.Sign(rand, data)
+}
+
+func (s *openSSHCertSigner) PublicKey() PublicKey {
+ return s.pub
+}
+
+func (s *algorithmOpenSSHCertSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
+ return s.algorithmSigner.SignWithAlgorithm(rand, data, algorithm)
+}
+
+const sourceAddressCriticalOption = "source-address"
+
+// CertChecker does the work of verifying a certificate. Its methods
+// can be plugged into ClientConfig.HostKeyCallback and
+// ServerConfig.PublicKeyCallback. For the CertChecker to work,
+// minimally, the IsAuthority callback should be set.
+type CertChecker struct {
+ // SupportedCriticalOptions lists the CriticalOptions that the
+ // server application layer understands. These are only used
+ // for user certificates.
+ SupportedCriticalOptions []string
+
+ // IsUserAuthority should return true if the key is recognized as an
+ // authority for the given user certificate. This allows for
+ // certificates to be signed by other certificates. This must be set
+ // if this CertChecker will be checking user certificates.
+ IsUserAuthority func(auth PublicKey) bool
+
+ // IsHostAuthority should report whether the key is recognized as
+ // an authority for this host. This allows for certificates to be
+ // signed by other keys, and for those other keys to only be valid
+ // signers for particular hostnames. This must be set if this
+ // CertChecker will be checking host certificates.
+ IsHostAuthority func(auth PublicKey, address string) bool
+
+ // Clock is used for verifying time stamps. If nil, time.Now
+ // is used.
+ Clock func() time.Time
+
+ // UserKeyFallback is called when CertChecker.Authenticate encounters a
+ // public key that is not a certificate. It must implement validation
+ // of user keys or else, if nil, all such keys are rejected.
+ UserKeyFallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
+
+ // HostKeyFallback is called when CertChecker.CheckHostKey encounters a
+ // public key that is not a certificate. It must implement host key
+ // validation or else, if nil, all such keys are rejected.
+ HostKeyFallback HostKeyCallback
+
+ // IsRevoked is called for each certificate so that revocation checking
+ // can be implemented. It should return true if the given certificate
+ // is revoked and false otherwise. If nil, no certificates are
+ // considered to have been revoked.
+ IsRevoked func(cert *Certificate) bool
+}
+
+// CheckHostKey checks a host key certificate. This method can be
+// plugged into ClientConfig.HostKeyCallback.
+func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error {
+ cert, ok := key.(*Certificate)
+ if !ok {
+ if c.HostKeyFallback != nil {
+ return c.HostKeyFallback(addr, remote, key)
+ }
+ return errors.New("ssh: non-certificate host key")
+ }
+ if cert.CertType != HostCert {
+ return fmt.Errorf("ssh: certificate presented as a host key has type %d", cert.CertType)
+ }
+ if !c.IsHostAuthority(cert.SignatureKey, addr) {
+ return fmt.Errorf("ssh: no authorities for hostname: %v", addr)
+ }
+
+ hostname, _, err := net.SplitHostPort(addr)
+ if err != nil {
+ return err
+ }
+
+ // Pass hostname only as principal for host certificates (consistent with OpenSSH)
+ return c.CheckCert(hostname, cert)
+}
+
+// Authenticate checks a user certificate. Authenticate can be used as
+// a value for ServerConfig.PublicKeyCallback.
+func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error) {
+ cert, ok := pubKey.(*Certificate)
+ if !ok {
+ if c.UserKeyFallback != nil {
+ return c.UserKeyFallback(conn, pubKey)
+ }
+ return nil, errors.New("ssh: normal key pairs not accepted")
+ }
+
+ if cert.CertType != UserCert {
+ return nil, fmt.Errorf("ssh: cert has type %d", cert.CertType)
+ }
+ if !c.IsUserAuthority(cert.SignatureKey) {
+ return nil, fmt.Errorf("ssh: certificate signed by unrecognized authority")
+ }
+
+ if err := c.CheckCert(conn.User(), cert); err != nil {
+ return nil, err
+ }
+
+ return &cert.Permissions, nil
+}
+
+// CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and
+// the signature of the certificate.
+func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
+ if c.IsRevoked != nil && c.IsRevoked(cert) {
+ return fmt.Errorf("ssh: certificate serial %d revoked", cert.Serial)
+ }
+
+ for opt := range cert.CriticalOptions {
+ // sourceAddressCriticalOption will be enforced by
+ // serverAuthenticate
+ if opt == sourceAddressCriticalOption {
+ continue
+ }
+
+ found := false
+ for _, supp := range c.SupportedCriticalOptions {
+ if supp == opt {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return fmt.Errorf("ssh: unsupported critical option %q in certificate", opt)
+ }
+ }
+
+ if len(cert.ValidPrincipals) > 0 {
+ // By default, certs are valid for all users/hosts.
+ found := false
+ for _, p := range cert.ValidPrincipals {
+ if p == principal {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return fmt.Errorf("ssh: principal %q not in the set of valid principals for given certificate: %q", principal, cert.ValidPrincipals)
+ }
+ }
+
+ clock := c.Clock
+ if clock == nil {
+ clock = time.Now
+ }
+
+ unixNow := clock().Unix()
+ if after := int64(cert.ValidAfter); after < 0 || unixNow < int64(cert.ValidAfter) {
+ return fmt.Errorf("ssh: cert is not yet valid")
+ }
+ if before := int64(cert.ValidBefore); cert.ValidBefore != uint64(CertTimeInfinity) && (unixNow >= before || before < 0) {
+ return fmt.Errorf("ssh: cert has expired")
+ }
+ if err := cert.SignatureKey.Verify(cert.bytesForSigning(), cert.Signature); err != nil {
+ return fmt.Errorf("ssh: certificate signature does not verify")
+ }
+
+ return nil
+}
+
+// SignCert signs the certificate with an authority, setting the Nonce,
+// SignatureKey, and Signature fields. If the authority implements the
+// MultiAlgorithmSigner interface the first algorithm in the list is used. This
+// is useful if you want to sign with a specific algorithm.
+func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
+ c.Nonce = make([]byte, 32)
+ if _, err := io.ReadFull(rand, c.Nonce); err != nil {
+ return err
+ }
+ c.SignatureKey = authority.PublicKey()
+
+ if v, ok := authority.(MultiAlgorithmSigner); ok {
+ if len(v.Algorithms()) == 0 {
+ return errors.New("the provided authority has no signature algorithm")
+ }
+ // Use the first algorithm in the list.
+ sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), v.Algorithms()[0])
+ if err != nil {
+ return err
+ }
+ c.Signature = sig
+ return nil
+ } else if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA {
+ // Default to KeyAlgoRSASHA512 for ssh-rsa signers.
+ // TODO: consider using KeyAlgoRSASHA256 as default.
+ sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), KeyAlgoRSASHA512)
+ if err != nil {
+ return err
+ }
+ c.Signature = sig
+ return nil
+ }
+
+ sig, err := authority.Sign(rand, c.bytesForSigning())
+ if err != nil {
+ return err
+ }
+ c.Signature = sig
+ return nil
+}
+
+// certKeyAlgoNames is a mapping from known certificate algorithm names to the
+// corresponding public key signature algorithm.
+//
+// This map must be kept in sync with the one in agent/client.go.
+var certKeyAlgoNames = map[string]string{
+ CertAlgoRSAv01: KeyAlgoRSA,
+ CertAlgoRSASHA256v01: KeyAlgoRSASHA256,
+ CertAlgoRSASHA512v01: KeyAlgoRSASHA512,
+ CertAlgoDSAv01: KeyAlgoDSA,
+ CertAlgoECDSA256v01: KeyAlgoECDSA256,
+ CertAlgoECDSA384v01: KeyAlgoECDSA384,
+ CertAlgoECDSA521v01: KeyAlgoECDSA521,
+ CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256,
+ CertAlgoED25519v01: KeyAlgoED25519,
+ CertAlgoSKED25519v01: KeyAlgoSKED25519,
+}
+
+// underlyingAlgo returns the signature algorithm associated with algo (which is
+// an advertised or negotiated public key or host key algorithm). These are
+// usually the same, except for certificate algorithms.
+func underlyingAlgo(algo string) string {
+ if a, ok := certKeyAlgoNames[algo]; ok {
+ return a
+ }
+ return algo
+}
+
+// certificateAlgo returns the certificate algorithms that uses the provided
+// underlying signature algorithm.
+func certificateAlgo(algo string) (certAlgo string, ok bool) {
+ for certName, algoName := range certKeyAlgoNames {
+ if algoName == algo {
+ return certName, true
+ }
+ }
+ return "", false
+}
+
+func (cert *Certificate) bytesForSigning() []byte {
+ c2 := *cert
+ c2.Signature = nil
+ out := c2.Marshal()
+ // Drop trailing signature length.
+ return out[:len(out)-4]
+}
+
+// Marshal serializes c into OpenSSH's wire format. It is part of the
+// PublicKey interface.
+func (c *Certificate) Marshal() []byte {
+ generic := genericCertData{
+ Serial: c.Serial,
+ CertType: c.CertType,
+ KeyId: c.KeyId,
+ ValidPrincipals: marshalStringList(c.ValidPrincipals),
+ ValidAfter: uint64(c.ValidAfter),
+ ValidBefore: uint64(c.ValidBefore),
+ CriticalOptions: marshalTuples(c.CriticalOptions),
+ Extensions: marshalTuples(c.Extensions),
+ Reserved: c.Reserved,
+ SignatureKey: c.SignatureKey.Marshal(),
+ }
+ if c.Signature != nil {
+ generic.Signature = Marshal(c.Signature)
+ }
+ genericBytes := Marshal(&generic)
+ keyBytes := c.Key.Marshal()
+ _, keyBytes, _ = parseString(keyBytes)
+ prefix := Marshal(&struct {
+ Name string
+ Nonce []byte
+ Key []byte `ssh:"rest"`
+ }{c.Type(), c.Nonce, keyBytes})
+
+ result := make([]byte, 0, len(prefix)+len(genericBytes))
+ result = append(result, prefix...)
+ result = append(result, genericBytes...)
+ return result
+}
+
+// Type returns the certificate algorithm name. It is part of the PublicKey interface.
+func (c *Certificate) Type() string {
+ certName, ok := certificateAlgo(c.Key.Type())
+ if !ok {
+ panic("unknown certificate type for key type " + c.Key.Type())
+ }
+ return certName
+}
+
+// Verify verifies a signature against the certificate's public
+// key. It is part of the PublicKey interface.
+func (c *Certificate) Verify(data []byte, sig *Signature) error {
+ return c.Key.Verify(data, sig)
+}
+
+func parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) {
+ format, in, ok := parseString(in)
+ if !ok {
+ return
+ }
+
+ out = &Signature{
+ Format: string(format),
+ }
+
+ if out.Blob, in, ok = parseString(in); !ok {
+ return
+ }
+
+ switch out.Format {
+ case KeyAlgoSKECDSA256, CertAlgoSKECDSA256v01, KeyAlgoSKED25519, CertAlgoSKED25519v01:
+ out.Rest = in
+ return out, nil, ok
+ }
+
+ return out, in, ok
+}
+
+func parseSignature(in []byte) (out *Signature, rest []byte, ok bool) {
+ sigBytes, rest, ok := parseString(in)
+ if !ok {
+ return
+ }
+
+ out, trailing, ok := parseSignatureBody(sigBytes)
+ if !ok || len(trailing) > 0 {
+ return nil, nil, false
+ }
+ return
+}
diff --git a/vendor/golang.org/x/crypto/ssh/channel.go b/vendor/golang.org/x/crypto/ssh/channel.go
new file mode 100644
index 00000000..cc0bb7ab
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/channel.go
@@ -0,0 +1,645 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "sync"
+)
+
+const (
+ minPacketLength = 9
+ // channelMaxPacket contains the maximum number of bytes that will be
+ // sent in a single packet. As per RFC 4253, section 6.1, 32k is also
+ // the minimum.
+ channelMaxPacket = 1 << 15
+ // We follow OpenSSH here.
+ channelWindowSize = 64 * channelMaxPacket
+)
+
+// NewChannel represents an incoming request to a channel. It must either be
+// accepted for use by calling Accept, or rejected by calling Reject.
+type NewChannel interface {
+ // Accept accepts the channel creation request. It returns the Channel
+ // and a Go channel containing SSH requests. The Go channel must be
+ // serviced otherwise the Channel will hang.
+ Accept() (Channel, <-chan *Request, error)
+
+ // Reject rejects the channel creation request. After calling
+ // this, no other methods on the Channel may be called.
+ Reject(reason RejectionReason, message string) error
+
+ // ChannelType returns the type of the channel, as supplied by the
+ // client.
+ ChannelType() string
+
+ // ExtraData returns the arbitrary payload for this channel, as supplied
+ // by the client. This data is specific to the channel type.
+ ExtraData() []byte
+}
+
+// A Channel is an ordered, reliable, flow-controlled, duplex stream
+// that is multiplexed over an SSH connection.
+type Channel interface {
+ // Read reads up to len(data) bytes from the channel.
+ Read(data []byte) (int, error)
+
+ // Write writes len(data) bytes to the channel.
+ Write(data []byte) (int, error)
+
+ // Close signals end of channel use. No data may be sent after this
+ // call.
+ Close() error
+
+ // CloseWrite signals the end of sending in-band
+ // data. Requests may still be sent, and the other side may
+ // still send data
+ CloseWrite() error
+
+ // SendRequest sends a channel request. If wantReply is true,
+ // it will wait for a reply and return the result as a
+ // boolean, otherwise the return value will be false. Channel
+ // requests are out-of-band messages so they may be sent even
+ // if the data stream is closed or blocked by flow control.
+ // If the channel is closed before a reply is returned, io.EOF
+ // is returned.
+ SendRequest(name string, wantReply bool, payload []byte) (bool, error)
+
+ // Stderr returns an io.ReadWriter that writes to this channel
+ // with the extended data type set to stderr. Stderr may
+ // safely be read and written from a different goroutine than
+ // Read and Write respectively.
+ Stderr() io.ReadWriter
+}
+
+// Request is a request sent outside of the normal stream of
+// data. Requests can either be specific to an SSH channel, or they
+// can be global.
+type Request struct {
+ Type string
+ WantReply bool
+ Payload []byte
+
+ ch *channel
+ mux *mux
+}
+
+// Reply sends a response to a request. It must be called for all requests
+// where WantReply is true and is a no-op otherwise. The payload argument is
+// ignored for replies to channel-specific requests.
+func (r *Request) Reply(ok bool, payload []byte) error {
+ if !r.WantReply {
+ return nil
+ }
+
+ if r.ch == nil {
+ return r.mux.ackRequest(ok, payload)
+ }
+
+ return r.ch.ackRequest(ok)
+}
+
+// RejectionReason is an enumeration used when rejecting channel creation
+// requests. See RFC 4254, section 5.1.
+type RejectionReason uint32
+
+const (
+ Prohibited RejectionReason = iota + 1
+ ConnectionFailed
+ UnknownChannelType
+ ResourceShortage
+)
+
+// String converts the rejection reason to human readable form.
+func (r RejectionReason) String() string {
+ switch r {
+ case Prohibited:
+ return "administratively prohibited"
+ case ConnectionFailed:
+ return "connect failed"
+ case UnknownChannelType:
+ return "unknown channel type"
+ case ResourceShortage:
+ return "resource shortage"
+ }
+ return fmt.Sprintf("unknown reason %d", int(r))
+}
+
+func min(a uint32, b int) uint32 {
+ if a < uint32(b) {
+ return a
+ }
+ return uint32(b)
+}
+
+type channelDirection uint8
+
+const (
+ channelInbound channelDirection = iota
+ channelOutbound
+)
+
+// channel is an implementation of the Channel interface that works
+// with the mux class.
+type channel struct {
+ // R/O after creation
+ chanType string
+ extraData []byte
+ localId, remoteId uint32
+
+ // maxIncomingPayload and maxRemotePayload are the maximum
+ // payload sizes of normal and extended data packets for
+ // receiving and sending, respectively. The wire packet will
+ // be 9 or 13 bytes larger (excluding encryption overhead).
+ maxIncomingPayload uint32
+ maxRemotePayload uint32
+
+ mux *mux
+
+ // decided is set to true if an accept or reject message has been sent
+ // (for outbound channels) or received (for inbound channels).
+ decided bool
+
+ // direction contains either channelOutbound, for channels created
+ // locally, or channelInbound, for channels created by the peer.
+ direction channelDirection
+
+ // Pending internal channel messages.
+ msg chan interface{}
+
+ // Since requests have no ID, there can be only one request
+ // with WantReply=true outstanding. This lock is held by a
+ // goroutine that has such an outgoing request pending.
+ sentRequestMu sync.Mutex
+
+ incomingRequests chan *Request
+
+ sentEOF bool
+
+ // thread-safe data
+ remoteWin window
+ pending *buffer
+ extPending *buffer
+
+ // windowMu protects myWindow, the flow-control window, and myConsumed,
+ // the number of bytes consumed since we last increased myWindow
+ windowMu sync.Mutex
+ myWindow uint32
+ myConsumed uint32
+
+ // writeMu serializes calls to mux.conn.writePacket() and
+ // protects sentClose and packetPool. This mutex must be
+ // different from windowMu, as writePacket can block if there
+ // is a key exchange pending.
+ writeMu sync.Mutex
+ sentClose bool
+
+ // packetPool has a buffer for each extended channel ID to
+ // save allocations during writes.
+ packetPool map[uint32][]byte
+}
+
+// writePacket sends a packet. If the packet is a channel close, it updates
+// sentClose. This method takes the lock c.writeMu.
+func (ch *channel) writePacket(packet []byte) error {
+ ch.writeMu.Lock()
+ if ch.sentClose {
+ ch.writeMu.Unlock()
+ return io.EOF
+ }
+ ch.sentClose = (packet[0] == msgChannelClose)
+ err := ch.mux.conn.writePacket(packet)
+ ch.writeMu.Unlock()
+ return err
+}
+
+func (ch *channel) sendMessage(msg interface{}) error {
+ if debugMux {
+ log.Printf("send(%d): %#v", ch.mux.chanList.offset, msg)
+ }
+
+ p := Marshal(msg)
+ binary.BigEndian.PutUint32(p[1:], ch.remoteId)
+ return ch.writePacket(p)
+}
+
+// WriteExtended writes data to a specific extended stream. These streams are
+// used, for example, for stderr.
+func (ch *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err error) {
+ if ch.sentEOF {
+ return 0, io.EOF
+ }
+ // 1 byte message type, 4 bytes remoteId, 4 bytes data length
+ opCode := byte(msgChannelData)
+ headerLength := uint32(9)
+ if extendedCode > 0 {
+ headerLength += 4
+ opCode = msgChannelExtendedData
+ }
+
+ ch.writeMu.Lock()
+ packet := ch.packetPool[extendedCode]
+ // We don't remove the buffer from packetPool, so
+ // WriteExtended calls from different goroutines will be
+ // flagged as errors by the race detector.
+ ch.writeMu.Unlock()
+
+ for len(data) > 0 {
+ space := min(ch.maxRemotePayload, len(data))
+ if space, err = ch.remoteWin.reserve(space); err != nil {
+ return n, err
+ }
+ if want := headerLength + space; uint32(cap(packet)) < want {
+ packet = make([]byte, want)
+ } else {
+ packet = packet[:want]
+ }
+
+ todo := data[:space]
+
+ packet[0] = opCode
+ binary.BigEndian.PutUint32(packet[1:], ch.remoteId)
+ if extendedCode > 0 {
+ binary.BigEndian.PutUint32(packet[5:], uint32(extendedCode))
+ }
+ binary.BigEndian.PutUint32(packet[headerLength-4:], uint32(len(todo)))
+ copy(packet[headerLength:], todo)
+ if err = ch.writePacket(packet); err != nil {
+ return n, err
+ }
+
+ n += len(todo)
+ data = data[len(todo):]
+ }
+
+ ch.writeMu.Lock()
+ ch.packetPool[extendedCode] = packet
+ ch.writeMu.Unlock()
+
+ return n, err
+}
+
+func (ch *channel) handleData(packet []byte) error {
+ headerLen := 9
+ isExtendedData := packet[0] == msgChannelExtendedData
+ if isExtendedData {
+ headerLen = 13
+ }
+ if len(packet) < headerLen {
+ // malformed data packet
+ return parseError(packet[0])
+ }
+
+ var extended uint32
+ if isExtendedData {
+ extended = binary.BigEndian.Uint32(packet[5:])
+ }
+
+ length := binary.BigEndian.Uint32(packet[headerLen-4 : headerLen])
+ if length == 0 {
+ return nil
+ }
+ if length > ch.maxIncomingPayload {
+ // TODO(hanwen): should send Disconnect?
+ return errors.New("ssh: incoming packet exceeds maximum payload size")
+ }
+
+ data := packet[headerLen:]
+ if length != uint32(len(data)) {
+ return errors.New("ssh: wrong packet length")
+ }
+
+ ch.windowMu.Lock()
+ if ch.myWindow < length {
+ ch.windowMu.Unlock()
+ // TODO(hanwen): should send Disconnect with reason?
+ return errors.New("ssh: remote side wrote too much")
+ }
+ ch.myWindow -= length
+ ch.windowMu.Unlock()
+
+ if extended == 1 {
+ ch.extPending.write(data)
+ } else if extended > 0 {
+ // discard other extended data.
+ } else {
+ ch.pending.write(data)
+ }
+ return nil
+}
+
+func (c *channel) adjustWindow(adj uint32) error {
+ c.windowMu.Lock()
+ // Since myConsumed and myWindow are managed on our side, and can never
+ // exceed the initial window setting, we don't worry about overflow.
+ c.myConsumed += adj
+ var sendAdj uint32
+ if (channelWindowSize-c.myWindow > 3*c.maxIncomingPayload) ||
+ (c.myWindow < channelWindowSize/2) {
+ sendAdj = c.myConsumed
+ c.myConsumed = 0
+ c.myWindow += sendAdj
+ }
+ c.windowMu.Unlock()
+ if sendAdj == 0 {
+ return nil
+ }
+ return c.sendMessage(windowAdjustMsg{
+ AdditionalBytes: sendAdj,
+ })
+}
+
+func (c *channel) ReadExtended(data []byte, extended uint32) (n int, err error) {
+ switch extended {
+ case 1:
+ n, err = c.extPending.Read(data)
+ case 0:
+ n, err = c.pending.Read(data)
+ default:
+ return 0, fmt.Errorf("ssh: extended code %d unimplemented", extended)
+ }
+
+ if n > 0 {
+ err = c.adjustWindow(uint32(n))
+ // sendWindowAdjust can return io.EOF if the remote
+ // peer has closed the connection, however we want to
+ // defer forwarding io.EOF to the caller of Read until
+ // the buffer has been drained.
+ if n > 0 && err == io.EOF {
+ err = nil
+ }
+ }
+
+ return n, err
+}
+
+func (c *channel) close() {
+ c.pending.eof()
+ c.extPending.eof()
+ close(c.msg)
+ close(c.incomingRequests)
+ c.writeMu.Lock()
+ // This is not necessary for a normal channel teardown, but if
+ // there was another error, it is.
+ c.sentClose = true
+ c.writeMu.Unlock()
+ // Unblock writers.
+ c.remoteWin.close()
+}
+
+// responseMessageReceived is called when a success or failure message is
+// received on a channel to check that such a message is reasonable for the
+// given channel.
+func (ch *channel) responseMessageReceived() error {
+ if ch.direction == channelInbound {
+ return errors.New("ssh: channel response message received on inbound channel")
+ }
+ if ch.decided {
+ return errors.New("ssh: duplicate response received for channel")
+ }
+ ch.decided = true
+ return nil
+}
+
+func (ch *channel) handlePacket(packet []byte) error {
+ switch packet[0] {
+ case msgChannelData, msgChannelExtendedData:
+ return ch.handleData(packet)
+ case msgChannelClose:
+ ch.sendMessage(channelCloseMsg{PeersID: ch.remoteId})
+ ch.mux.chanList.remove(ch.localId)
+ ch.close()
+ return nil
+ case msgChannelEOF:
+ // RFC 4254 is mute on how EOF affects dataExt messages but
+ // it is logical to signal EOF at the same time.
+ ch.extPending.eof()
+ ch.pending.eof()
+ return nil
+ }
+
+ decoded, err := decode(packet)
+ if err != nil {
+ return err
+ }
+
+ switch msg := decoded.(type) {
+ case *channelOpenFailureMsg:
+ if err := ch.responseMessageReceived(); err != nil {
+ return err
+ }
+ ch.mux.chanList.remove(msg.PeersID)
+ ch.msg <- msg
+ case *channelOpenConfirmMsg:
+ if err := ch.responseMessageReceived(); err != nil {
+ return err
+ }
+ if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
+ return fmt.Errorf("ssh: invalid MaxPacketSize %d from peer", msg.MaxPacketSize)
+ }
+ ch.remoteId = msg.MyID
+ ch.maxRemotePayload = msg.MaxPacketSize
+ ch.remoteWin.add(msg.MyWindow)
+ ch.msg <- msg
+ case *windowAdjustMsg:
+ if !ch.remoteWin.add(msg.AdditionalBytes) {
+ return fmt.Errorf("ssh: invalid window update for %d bytes", msg.AdditionalBytes)
+ }
+ case *channelRequestMsg:
+ req := Request{
+ Type: msg.Request,
+ WantReply: msg.WantReply,
+ Payload: msg.RequestSpecificData,
+ ch: ch,
+ }
+
+ ch.incomingRequests <- &req
+ default:
+ ch.msg <- msg
+ }
+ return nil
+}
+
+func (m *mux) newChannel(chanType string, direction channelDirection, extraData []byte) *channel {
+ ch := &channel{
+ remoteWin: window{Cond: newCond()},
+ myWindow: channelWindowSize,
+ pending: newBuffer(),
+ extPending: newBuffer(),
+ direction: direction,
+ incomingRequests: make(chan *Request, chanSize),
+ msg: make(chan interface{}, chanSize),
+ chanType: chanType,
+ extraData: extraData,
+ mux: m,
+ packetPool: make(map[uint32][]byte),
+ }
+ ch.localId = m.chanList.add(ch)
+ return ch
+}
+
+var errUndecided = errors.New("ssh: must Accept or Reject channel")
+var errDecidedAlready = errors.New("ssh: can call Accept or Reject only once")
+
+type extChannel struct {
+ code uint32
+ ch *channel
+}
+
+func (e *extChannel) Write(data []byte) (n int, err error) {
+ return e.ch.WriteExtended(data, e.code)
+}
+
+func (e *extChannel) Read(data []byte) (n int, err error) {
+ return e.ch.ReadExtended(data, e.code)
+}
+
+func (ch *channel) Accept() (Channel, <-chan *Request, error) {
+ if ch.decided {
+ return nil, nil, errDecidedAlready
+ }
+ ch.maxIncomingPayload = channelMaxPacket
+ confirm := channelOpenConfirmMsg{
+ PeersID: ch.remoteId,
+ MyID: ch.localId,
+ MyWindow: ch.myWindow,
+ MaxPacketSize: ch.maxIncomingPayload,
+ }
+ ch.decided = true
+ if err := ch.sendMessage(confirm); err != nil {
+ return nil, nil, err
+ }
+
+ return ch, ch.incomingRequests, nil
+}
+
+func (ch *channel) Reject(reason RejectionReason, message string) error {
+ if ch.decided {
+ return errDecidedAlready
+ }
+ reject := channelOpenFailureMsg{
+ PeersID: ch.remoteId,
+ Reason: reason,
+ Message: message,
+ Language: "en",
+ }
+ ch.decided = true
+ return ch.sendMessage(reject)
+}
+
+func (ch *channel) Read(data []byte) (int, error) {
+ if !ch.decided {
+ return 0, errUndecided
+ }
+ return ch.ReadExtended(data, 0)
+}
+
+func (ch *channel) Write(data []byte) (int, error) {
+ if !ch.decided {
+ return 0, errUndecided
+ }
+ return ch.WriteExtended(data, 0)
+}
+
+func (ch *channel) CloseWrite() error {
+ if !ch.decided {
+ return errUndecided
+ }
+ ch.sentEOF = true
+ return ch.sendMessage(channelEOFMsg{
+ PeersID: ch.remoteId})
+}
+
+func (ch *channel) Close() error {
+ if !ch.decided {
+ return errUndecided
+ }
+
+ return ch.sendMessage(channelCloseMsg{
+ PeersID: ch.remoteId})
+}
+
+// Extended returns an io.ReadWriter that sends and receives data on the given,
+// SSH extended stream. Such streams are used, for example, for stderr.
+func (ch *channel) Extended(code uint32) io.ReadWriter {
+ if !ch.decided {
+ return nil
+ }
+ return &extChannel{code, ch}
+}
+
+func (ch *channel) Stderr() io.ReadWriter {
+ return ch.Extended(1)
+}
+
+func (ch *channel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) {
+ if !ch.decided {
+ return false, errUndecided
+ }
+
+ if wantReply {
+ ch.sentRequestMu.Lock()
+ defer ch.sentRequestMu.Unlock()
+ }
+
+ msg := channelRequestMsg{
+ PeersID: ch.remoteId,
+ Request: name,
+ WantReply: wantReply,
+ RequestSpecificData: payload,
+ }
+
+ if err := ch.sendMessage(msg); err != nil {
+ return false, err
+ }
+
+ if wantReply {
+ m, ok := (<-ch.msg)
+ if !ok {
+ return false, io.EOF
+ }
+ switch m.(type) {
+ case *channelRequestFailureMsg:
+ return false, nil
+ case *channelRequestSuccessMsg:
+ return true, nil
+ default:
+ return false, fmt.Errorf("ssh: unexpected response to channel request: %#v", m)
+ }
+ }
+
+ return false, nil
+}
+
+// ackRequest either sends an ack or nack to the channel request.
+func (ch *channel) ackRequest(ok bool) error {
+ if !ch.decided {
+ return errUndecided
+ }
+
+ var msg interface{}
+ if !ok {
+ msg = channelRequestFailureMsg{
+ PeersID: ch.remoteId,
+ }
+ } else {
+ msg = channelRequestSuccessMsg{
+ PeersID: ch.remoteId,
+ }
+ }
+ return ch.sendMessage(msg)
+}
+
+func (ch *channel) ChannelType() string {
+ return ch.chanType
+}
+
+func (ch *channel) ExtraData() []byte {
+ return ch.extraData
+}
diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go
new file mode 100644
index 00000000..741e984f
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/cipher.go
@@ -0,0 +1,789 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/des"
+ "crypto/rc4"
+ "crypto/subtle"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+
+ "golang.org/x/crypto/chacha20"
+ "golang.org/x/crypto/internal/poly1305"
+)
+
+const (
+ packetSizeMultiple = 16 // TODO(huin) this should be determined by the cipher.
+
+ // RFC 4253 section 6.1 defines a minimum packet size of 32768 that implementations
+ // MUST be able to process (plus a few more kilobytes for padding and mac). The RFC
+ // indicates implementations SHOULD be able to handle larger packet sizes, but then
+ // waffles on about reasonable limits.
+ //
+ // OpenSSH caps their maxPacket at 256kB so we choose to do
+ // the same. maxPacket is also used to ensure that uint32
+ // length fields do not overflow, so it should remain well
+ // below 4G.
+ maxPacket = 256 * 1024
+)
+
+// noneCipher implements cipher.Stream and provides no encryption. It is used
+// by the transport before the first key-exchange.
+type noneCipher struct{}
+
+func (c noneCipher) XORKeyStream(dst, src []byte) {
+ copy(dst, src)
+}
+
+func newAESCTR(key, iv []byte) (cipher.Stream, error) {
+ c, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+ return cipher.NewCTR(c, iv), nil
+}
+
+func newRC4(key, iv []byte) (cipher.Stream, error) {
+ return rc4.NewCipher(key)
+}
+
+type cipherMode struct {
+ keySize int
+ ivSize int
+ create func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error)
+}
+
+func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+ return func(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+ stream, err := createFunc(key, iv)
+ if err != nil {
+ return nil, err
+ }
+
+ var streamDump []byte
+ if skip > 0 {
+ streamDump = make([]byte, 512)
+ }
+
+ for remainingToDump := skip; remainingToDump > 0; {
+ dumpThisTime := remainingToDump
+ if dumpThisTime > len(streamDump) {
+ dumpThisTime = len(streamDump)
+ }
+ stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])
+ remainingToDump -= dumpThisTime
+ }
+
+ mac := macModes[algs.MAC].new(macKey)
+ return &streamPacketCipher{
+ mac: mac,
+ etm: macModes[algs.MAC].etm,
+ macResult: make([]byte, mac.Size()),
+ cipher: stream,
+ }, nil
+ }
+}
+
+// cipherModes documents properties of supported ciphers. Ciphers not included
+// are not supported and will not be negotiated, even if explicitly requested in
+// ClientConfig.Crypto.Ciphers.
+var cipherModes = map[string]*cipherMode{
+ // Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms
+ // are defined in the order specified in the RFC.
+ "aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
+ "aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
+ "aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
+
+ // Ciphers from RFC 4345, which introduces security-improved arcfour ciphers.
+ // They are defined in the order specified in the RFC.
+ "arcfour128": {16, 0, streamCipherMode(1536, newRC4)},
+ "arcfour256": {32, 0, streamCipherMode(1536, newRC4)},
+
+ // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
+ // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
+ // RC4) has problems with weak keys, and should be used with caution."
+ // RFC 4345 introduces improved versions of Arcfour.
+ "arcfour": {16, 0, streamCipherMode(0, newRC4)},
+
+ // AEAD ciphers
+ gcm128CipherID: {16, 12, newGCMCipher},
+ gcm256CipherID: {32, 12, newGCMCipher},
+ chacha20Poly1305ID: {64, 0, newChaCha20Cipher},
+
+ // CBC mode is insecure and so is not included in the default config.
+ // (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely
+ // needed, it's possible to specify a custom Config to enable it.
+ // You should expect that an active attacker can recover plaintext if
+ // you do.
+ aes128cbcID: {16, aes.BlockSize, newAESCBCCipher},
+
+ // 3des-cbc is insecure and is not included in the default
+ // config.
+ tripledescbcID: {24, des.BlockSize, newTripleDESCBCCipher},
+}
+
+// prefixLen is the length of the packet prefix that contains the packet length
+// and number of padding bytes.
+const prefixLen = 5
+
+// streamPacketCipher is a packetCipher using a stream cipher.
+type streamPacketCipher struct {
+ mac hash.Hash
+ cipher cipher.Stream
+ etm bool
+
+ // The following members are to avoid per-packet allocations.
+ prefix [prefixLen]byte
+ seqNumBytes [4]byte
+ padding [2 * packetSizeMultiple]byte
+ packetData []byte
+ macResult []byte
+}
+
+// readCipherPacket reads and decrypt a single packet from the reader argument.
+func (s *streamPacketCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {
+ if _, err := io.ReadFull(r, s.prefix[:]); err != nil {
+ return nil, err
+ }
+
+ var encryptedPaddingLength [1]byte
+ if s.mac != nil && s.etm {
+ copy(encryptedPaddingLength[:], s.prefix[4:5])
+ s.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])
+ } else {
+ s.cipher.XORKeyStream(s.prefix[:], s.prefix[:])
+ }
+
+ length := binary.BigEndian.Uint32(s.prefix[0:4])
+ paddingLength := uint32(s.prefix[4])
+
+ var macSize uint32
+ if s.mac != nil {
+ s.mac.Reset()
+ binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)
+ s.mac.Write(s.seqNumBytes[:])
+ if s.etm {
+ s.mac.Write(s.prefix[:4])
+ s.mac.Write(encryptedPaddingLength[:])
+ } else {
+ s.mac.Write(s.prefix[:])
+ }
+ macSize = uint32(s.mac.Size())
+ }
+
+ if length <= paddingLength+1 {
+ return nil, errors.New("ssh: invalid packet length, packet too small")
+ }
+
+ if length > maxPacket {
+ return nil, errors.New("ssh: invalid packet length, packet too large")
+ }
+
+ // the maxPacket check above ensures that length-1+macSize
+ // does not overflow.
+ if uint32(cap(s.packetData)) < length-1+macSize {
+ s.packetData = make([]byte, length-1+macSize)
+ } else {
+ s.packetData = s.packetData[:length-1+macSize]
+ }
+
+ if _, err := io.ReadFull(r, s.packetData); err != nil {
+ return nil, err
+ }
+ mac := s.packetData[length-1:]
+ data := s.packetData[:length-1]
+
+ if s.mac != nil && s.etm {
+ s.mac.Write(data)
+ }
+
+ s.cipher.XORKeyStream(data, data)
+
+ if s.mac != nil {
+ if !s.etm {
+ s.mac.Write(data)
+ }
+ s.macResult = s.mac.Sum(s.macResult[:0])
+ if subtle.ConstantTimeCompare(s.macResult, mac) != 1 {
+ return nil, errors.New("ssh: MAC failure")
+ }
+ }
+
+ return s.packetData[:length-paddingLength-1], nil
+}
+
+// writeCipherPacket encrypts and sends a packet of data to the writer argument
+func (s *streamPacketCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
+ if len(packet) > maxPacket {
+ return errors.New("ssh: packet too large")
+ }
+
+ aadlen := 0
+ if s.mac != nil && s.etm {
+ // packet length is not encrypted for EtM modes
+ aadlen = 4
+ }
+
+ paddingLength := packetSizeMultiple - (prefixLen+len(packet)-aadlen)%packetSizeMultiple
+ if paddingLength < 4 {
+ paddingLength += packetSizeMultiple
+ }
+
+ length := len(packet) + 1 + paddingLength
+ binary.BigEndian.PutUint32(s.prefix[:], uint32(length))
+ s.prefix[4] = byte(paddingLength)
+ padding := s.padding[:paddingLength]
+ if _, err := io.ReadFull(rand, padding); err != nil {
+ return err
+ }
+
+ if s.mac != nil {
+ s.mac.Reset()
+ binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)
+ s.mac.Write(s.seqNumBytes[:])
+
+ if s.etm {
+ // For EtM algorithms, the packet length must stay unencrypted,
+ // but the following data (padding length) must be encrypted
+ s.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])
+ }
+
+ s.mac.Write(s.prefix[:])
+
+ if !s.etm {
+ // For non-EtM algorithms, the algorithm is applied on unencrypted data
+ s.mac.Write(packet)
+ s.mac.Write(padding)
+ }
+ }
+
+ if !(s.mac != nil && s.etm) {
+ // For EtM algorithms, the padding length has already been encrypted
+ // and the packet length must remain unencrypted
+ s.cipher.XORKeyStream(s.prefix[:], s.prefix[:])
+ }
+
+ s.cipher.XORKeyStream(packet, packet)
+ s.cipher.XORKeyStream(padding, padding)
+
+ if s.mac != nil && s.etm {
+ // For EtM algorithms, packet and padding must be encrypted
+ s.mac.Write(packet)
+ s.mac.Write(padding)
+ }
+
+ if _, err := w.Write(s.prefix[:]); err != nil {
+ return err
+ }
+ if _, err := w.Write(packet); err != nil {
+ return err
+ }
+ if _, err := w.Write(padding); err != nil {
+ return err
+ }
+
+ if s.mac != nil {
+ s.macResult = s.mac.Sum(s.macResult[:0])
+ if _, err := w.Write(s.macResult); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+type gcmCipher struct {
+ aead cipher.AEAD
+ prefix [4]byte
+ iv []byte
+ buf []byte
+}
+
+func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {
+ c, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+
+ aead, err := cipher.NewGCM(c)
+ if err != nil {
+ return nil, err
+ }
+
+ return &gcmCipher{
+ aead: aead,
+ iv: iv,
+ }, nil
+}
+
+const gcmTagSize = 16
+
+func (c *gcmCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
+ // Pad out to multiple of 16 bytes. This is different from the
+ // stream cipher because that encrypts the length too.
+ padding := byte(packetSizeMultiple - (1+len(packet))%packetSizeMultiple)
+ if padding < 4 {
+ padding += packetSizeMultiple
+ }
+
+ length := uint32(len(packet) + int(padding) + 1)
+ binary.BigEndian.PutUint32(c.prefix[:], length)
+ if _, err := w.Write(c.prefix[:]); err != nil {
+ return err
+ }
+
+ if cap(c.buf) < int(length) {
+ c.buf = make([]byte, length)
+ } else {
+ c.buf = c.buf[:length]
+ }
+
+ c.buf[0] = padding
+ copy(c.buf[1:], packet)
+ if _, err := io.ReadFull(rand, c.buf[1+len(packet):]); err != nil {
+ return err
+ }
+ c.buf = c.aead.Seal(c.buf[:0], c.iv, c.buf, c.prefix[:])
+ if _, err := w.Write(c.buf); err != nil {
+ return err
+ }
+ c.incIV()
+
+ return nil
+}
+
+func (c *gcmCipher) incIV() {
+ for i := 4 + 7; i >= 4; i-- {
+ c.iv[i]++
+ if c.iv[i] != 0 {
+ break
+ }
+ }
+}
+
+func (c *gcmCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {
+ if _, err := io.ReadFull(r, c.prefix[:]); err != nil {
+ return nil, err
+ }
+ length := binary.BigEndian.Uint32(c.prefix[:])
+ if length > maxPacket {
+ return nil, errors.New("ssh: max packet length exceeded")
+ }
+
+ if cap(c.buf) < int(length+gcmTagSize) {
+ c.buf = make([]byte, length+gcmTagSize)
+ } else {
+ c.buf = c.buf[:length+gcmTagSize]
+ }
+
+ if _, err := io.ReadFull(r, c.buf); err != nil {
+ return nil, err
+ }
+
+ plain, err := c.aead.Open(c.buf[:0], c.iv, c.buf, c.prefix[:])
+ if err != nil {
+ return nil, err
+ }
+ c.incIV()
+
+ if len(plain) == 0 {
+ return nil, errors.New("ssh: empty packet")
+ }
+
+ padding := plain[0]
+ if padding < 4 {
+ // padding is a byte, so it automatically satisfies
+ // the maximum size, which is 255.
+ return nil, fmt.Errorf("ssh: illegal padding %d", padding)
+ }
+
+ if int(padding+1) >= len(plain) {
+ return nil, fmt.Errorf("ssh: padding %d too large", padding)
+ }
+ plain = plain[1 : length-uint32(padding)]
+ return plain, nil
+}
+
+// cbcCipher implements aes128-cbc cipher defined in RFC 4253 section 6.1
+type cbcCipher struct {
+ mac hash.Hash
+ macSize uint32
+ decrypter cipher.BlockMode
+ encrypter cipher.BlockMode
+
+ // The following members are to avoid per-packet allocations.
+ seqNumBytes [4]byte
+ packetData []byte
+ macResult []byte
+
+ // Amount of data we should still read to hide which
+ // verification error triggered.
+ oracleCamouflage uint32
+}
+
+func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+ cbc := &cbcCipher{
+ mac: macModes[algs.MAC].new(macKey),
+ decrypter: cipher.NewCBCDecrypter(c, iv),
+ encrypter: cipher.NewCBCEncrypter(c, iv),
+ packetData: make([]byte, 1024),
+ }
+ if cbc.mac != nil {
+ cbc.macSize = uint32(cbc.mac.Size())
+ }
+
+ return cbc, nil
+}
+
+func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+ c, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+
+ cbc, err := newCBCCipher(c, key, iv, macKey, algs)
+ if err != nil {
+ return nil, err
+ }
+
+ return cbc, nil
+}
+
+func newTripleDESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+ c, err := des.NewTripleDESCipher(key)
+ if err != nil {
+ return nil, err
+ }
+
+ cbc, err := newCBCCipher(c, key, iv, macKey, algs)
+ if err != nil {
+ return nil, err
+ }
+
+ return cbc, nil
+}
+
+func maxUInt32(a, b int) uint32 {
+ if a > b {
+ return uint32(a)
+ }
+ return uint32(b)
+}
+
+const (
+ cbcMinPacketSizeMultiple = 8
+ cbcMinPacketSize = 16
+ cbcMinPaddingSize = 4
+)
+
+// cbcError represents a verification error that may leak information.
+type cbcError string
+
+func (e cbcError) Error() string { return string(e) }
+
+func (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {
+ p, err := c.readCipherPacketLeaky(seqNum, r)
+ if err != nil {
+ if _, ok := err.(cbcError); ok {
+ // Verification error: read a fixed amount of
+ // data, to make distinguishing between
+ // failing MAC and failing length check more
+ // difficult.
+ io.CopyN(io.Discard, r, int64(c.oracleCamouflage))
+ }
+ }
+ return p, err
+}
+
+func (c *cbcCipher) readCipherPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error) {
+ blockSize := c.decrypter.BlockSize()
+
+ // Read the header, which will include some of the subsequent data in the
+ // case of block ciphers - this is copied back to the payload later.
+ // How many bytes of payload/padding will be read with this first read.
+ firstBlockLength := uint32((prefixLen + blockSize - 1) / blockSize * blockSize)
+ firstBlock := c.packetData[:firstBlockLength]
+ if _, err := io.ReadFull(r, firstBlock); err != nil {
+ return nil, err
+ }
+
+ c.oracleCamouflage = maxPacket + 4 + c.macSize - firstBlockLength
+
+ c.decrypter.CryptBlocks(firstBlock, firstBlock)
+ length := binary.BigEndian.Uint32(firstBlock[:4])
+ if length > maxPacket {
+ return nil, cbcError("ssh: packet too large")
+ }
+ if length+4 < maxUInt32(cbcMinPacketSize, blockSize) {
+ // The minimum size of a packet is 16 (or the cipher block size, whichever
+ // is larger) bytes.
+ return nil, cbcError("ssh: packet too small")
+ }
+ // The length of the packet (including the length field but not the MAC) must
+ // be a multiple of the block size or 8, whichever is larger.
+ if (length+4)%maxUInt32(cbcMinPacketSizeMultiple, blockSize) != 0 {
+ return nil, cbcError("ssh: invalid packet length multiple")
+ }
+
+ paddingLength := uint32(firstBlock[4])
+ if paddingLength < cbcMinPaddingSize || length <= paddingLength+1 {
+ return nil, cbcError("ssh: invalid packet length")
+ }
+
+ // Positions within the c.packetData buffer:
+ macStart := 4 + length
+ paddingStart := macStart - paddingLength
+
+ // Entire packet size, starting before length, ending at end of mac.
+ entirePacketSize := macStart + c.macSize
+
+ // Ensure c.packetData is large enough for the entire packet data.
+ if uint32(cap(c.packetData)) < entirePacketSize {
+ // Still need to upsize and copy, but this should be rare at runtime, only
+ // on upsizing the packetData buffer.
+ c.packetData = make([]byte, entirePacketSize)
+ copy(c.packetData, firstBlock)
+ } else {
+ c.packetData = c.packetData[:entirePacketSize]
+ }
+
+ n, err := io.ReadFull(r, c.packetData[firstBlockLength:])
+ if err != nil {
+ return nil, err
+ }
+ c.oracleCamouflage -= uint32(n)
+
+ remainingCrypted := c.packetData[firstBlockLength:macStart]
+ c.decrypter.CryptBlocks(remainingCrypted, remainingCrypted)
+
+ mac := c.packetData[macStart:]
+ if c.mac != nil {
+ c.mac.Reset()
+ binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)
+ c.mac.Write(c.seqNumBytes[:])
+ c.mac.Write(c.packetData[:macStart])
+ c.macResult = c.mac.Sum(c.macResult[:0])
+ if subtle.ConstantTimeCompare(c.macResult, mac) != 1 {
+ return nil, cbcError("ssh: MAC failure")
+ }
+ }
+
+ return c.packetData[prefixLen:paddingStart], nil
+}
+
+func (c *cbcCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
+ effectiveBlockSize := maxUInt32(cbcMinPacketSizeMultiple, c.encrypter.BlockSize())
+
+ // Length of encrypted portion of the packet (header, payload, padding).
+ // Enforce minimum padding and packet size.
+ encLength := maxUInt32(prefixLen+len(packet)+cbcMinPaddingSize, cbcMinPaddingSize)
+ // Enforce block size.
+ encLength = (encLength + effectiveBlockSize - 1) / effectiveBlockSize * effectiveBlockSize
+
+ length := encLength - 4
+ paddingLength := int(length) - (1 + len(packet))
+
+ // Overall buffer contains: header, payload, padding, mac.
+ // Space for the MAC is reserved in the capacity but not the slice length.
+ bufferSize := encLength + c.macSize
+ if uint32(cap(c.packetData)) < bufferSize {
+ c.packetData = make([]byte, encLength, bufferSize)
+ } else {
+ c.packetData = c.packetData[:encLength]
+ }
+
+ p := c.packetData
+
+ // Packet header.
+ binary.BigEndian.PutUint32(p, length)
+ p = p[4:]
+ p[0] = byte(paddingLength)
+
+ // Payload.
+ p = p[1:]
+ copy(p, packet)
+
+ // Padding.
+ p = p[len(packet):]
+ if _, err := io.ReadFull(rand, p); err != nil {
+ return err
+ }
+
+ if c.mac != nil {
+ c.mac.Reset()
+ binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)
+ c.mac.Write(c.seqNumBytes[:])
+ c.mac.Write(c.packetData)
+ // The MAC is now appended into the capacity reserved for it earlier.
+ c.packetData = c.mac.Sum(c.packetData)
+ }
+
+ c.encrypter.CryptBlocks(c.packetData[:encLength], c.packetData[:encLength])
+
+ if _, err := w.Write(c.packetData); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+const chacha20Poly1305ID = "chacha20-poly1305@openssh.com"
+
+// chacha20Poly1305Cipher implements the chacha20-poly1305@openssh.com
+// AEAD, which is described here:
+//
+// https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
+//
+// the methods here also implement padding, which RFC 4253 Section 6
+// also requires of stream ciphers.
+type chacha20Poly1305Cipher struct {
+ lengthKey [32]byte
+ contentKey [32]byte
+ buf []byte
+}
+
+func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {
+ if len(key) != 64 {
+ panic(len(key))
+ }
+
+ c := &chacha20Poly1305Cipher{
+ buf: make([]byte, 256),
+ }
+
+ copy(c.contentKey[:], key[:32])
+ copy(c.lengthKey[:], key[32:])
+ return c, nil
+}
+
+func (c *chacha20Poly1305Cipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {
+ nonce := make([]byte, 12)
+ binary.BigEndian.PutUint32(nonce[8:], seqNum)
+ s, err := chacha20.NewUnauthenticatedCipher(c.contentKey[:], nonce)
+ if err != nil {
+ return nil, err
+ }
+ var polyKey, discardBuf [32]byte
+ s.XORKeyStream(polyKey[:], polyKey[:])
+ s.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes
+
+ encryptedLength := c.buf[:4]
+ if _, err := io.ReadFull(r, encryptedLength); err != nil {
+ return nil, err
+ }
+
+ var lenBytes [4]byte
+ ls, err := chacha20.NewUnauthenticatedCipher(c.lengthKey[:], nonce)
+ if err != nil {
+ return nil, err
+ }
+ ls.XORKeyStream(lenBytes[:], encryptedLength)
+
+ length := binary.BigEndian.Uint32(lenBytes[:])
+ if length > maxPacket {
+ return nil, errors.New("ssh: invalid packet length, packet too large")
+ }
+
+ contentEnd := 4 + length
+ packetEnd := contentEnd + poly1305.TagSize
+ if uint32(cap(c.buf)) < packetEnd {
+ c.buf = make([]byte, packetEnd)
+ copy(c.buf[:], encryptedLength)
+ } else {
+ c.buf = c.buf[:packetEnd]
+ }
+
+ if _, err := io.ReadFull(r, c.buf[4:packetEnd]); err != nil {
+ return nil, err
+ }
+
+ var mac [poly1305.TagSize]byte
+ copy(mac[:], c.buf[contentEnd:packetEnd])
+ if !poly1305.Verify(&mac, c.buf[:contentEnd], &polyKey) {
+ return nil, errors.New("ssh: MAC failure")
+ }
+
+ plain := c.buf[4:contentEnd]
+ s.XORKeyStream(plain, plain)
+
+ if len(plain) == 0 {
+ return nil, errors.New("ssh: empty packet")
+ }
+
+ padding := plain[0]
+ if padding < 4 {
+ // padding is a byte, so it automatically satisfies
+ // the maximum size, which is 255.
+ return nil, fmt.Errorf("ssh: illegal padding %d", padding)
+ }
+
+ if int(padding)+1 >= len(plain) {
+ return nil, fmt.Errorf("ssh: padding %d too large", padding)
+ }
+
+ plain = plain[1 : len(plain)-int(padding)]
+
+ return plain, nil
+}
+
+func (c *chacha20Poly1305Cipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, payload []byte) error {
+ nonce := make([]byte, 12)
+ binary.BigEndian.PutUint32(nonce[8:], seqNum)
+ s, err := chacha20.NewUnauthenticatedCipher(c.contentKey[:], nonce)
+ if err != nil {
+ return err
+ }
+ var polyKey, discardBuf [32]byte
+ s.XORKeyStream(polyKey[:], polyKey[:])
+ s.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes
+
+ // There is no blocksize, so fall back to multiple of 8 byte
+ // padding, as described in RFC 4253, Sec 6.
+ const packetSizeMultiple = 8
+
+ padding := packetSizeMultiple - (1+len(payload))%packetSizeMultiple
+ if padding < 4 {
+ padding += packetSizeMultiple
+ }
+
+ // size (4 bytes), padding (1), payload, padding, tag.
+ totalLength := 4 + 1 + len(payload) + padding + poly1305.TagSize
+ if cap(c.buf) < totalLength {
+ c.buf = make([]byte, totalLength)
+ } else {
+ c.buf = c.buf[:totalLength]
+ }
+
+ binary.BigEndian.PutUint32(c.buf, uint32(1+len(payload)+padding))
+ ls, err := chacha20.NewUnauthenticatedCipher(c.lengthKey[:], nonce)
+ if err != nil {
+ return err
+ }
+ ls.XORKeyStream(c.buf, c.buf[:4])
+ c.buf[4] = byte(padding)
+ copy(c.buf[5:], payload)
+ packetEnd := 5 + len(payload) + padding
+ if _, err := io.ReadFull(rand, c.buf[5+len(payload):packetEnd]); err != nil {
+ return err
+ }
+
+ s.XORKeyStream(c.buf[4:], c.buf[4:packetEnd])
+
+ var mac [poly1305.TagSize]byte
+ poly1305.Sum(&mac, c.buf[:packetEnd], &polyKey)
+
+ copy(c.buf[packetEnd:], mac[:])
+
+ if _, err := w.Write(c.buf); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/crypto/ssh/client.go b/vendor/golang.org/x/crypto/ssh/client.go
new file mode 100644
index 00000000..fd8c4974
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/client.go
@@ -0,0 +1,282 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "net"
+ "os"
+ "sync"
+ "time"
+)
+
+// Client implements a traditional SSH client that supports shells,
+// subprocesses, TCP port/streamlocal forwarding and tunneled dialing.
+type Client struct {
+ Conn
+
+ handleForwardsOnce sync.Once // guards calling (*Client).handleForwards
+
+ forwards forwardList // forwarded tcpip connections from the remote side
+ mu sync.Mutex
+ channelHandlers map[string]chan NewChannel
+}
+
+// HandleChannelOpen returns a channel on which NewChannel requests
+// for the given type are sent. If the type already is being handled,
+// nil is returned. The channel is closed when the connection is closed.
+func (c *Client) HandleChannelOpen(channelType string) <-chan NewChannel {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.channelHandlers == nil {
+ // The SSH channel has been closed.
+ c := make(chan NewChannel)
+ close(c)
+ return c
+ }
+
+ ch := c.channelHandlers[channelType]
+ if ch != nil {
+ return nil
+ }
+
+ ch = make(chan NewChannel, chanSize)
+ c.channelHandlers[channelType] = ch
+ return ch
+}
+
+// NewClient creates a Client on top of the given connection.
+func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client {
+ conn := &Client{
+ Conn: c,
+ channelHandlers: make(map[string]chan NewChannel, 1),
+ }
+
+ go conn.handleGlobalRequests(reqs)
+ go conn.handleChannelOpens(chans)
+ go func() {
+ conn.Wait()
+ conn.forwards.closeAll()
+ }()
+ return conn
+}
+
+// NewClientConn establishes an authenticated SSH connection using c
+// as the underlying transport. The Request and NewChannel channels
+// must be serviced or the connection will hang.
+func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan NewChannel, <-chan *Request, error) {
+ fullConf := *config
+ fullConf.SetDefaults()
+ if fullConf.HostKeyCallback == nil {
+ c.Close()
+ return nil, nil, nil, errors.New("ssh: must specify HostKeyCallback")
+ }
+
+ conn := &connection{
+ sshConn: sshConn{conn: c, user: fullConf.User},
+ }
+
+ if err := conn.clientHandshake(addr, &fullConf); err != nil {
+ c.Close()
+ return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %w", err)
+ }
+ conn.mux = newMux(conn.transport)
+ return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil
+}
+
+// clientHandshake performs the client side key exchange. See RFC 4253 Section
+// 7.
+func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error {
+ if config.ClientVersion != "" {
+ c.clientVersion = []byte(config.ClientVersion)
+ } else {
+ c.clientVersion = []byte(packageVersion)
+ }
+ var err error
+ c.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion)
+ if err != nil {
+ return err
+ }
+
+ c.transport = newClientTransport(
+ newTransport(c.sshConn.conn, config.Rand, true /* is client */),
+ c.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr())
+ if err := c.transport.waitSession(); err != nil {
+ return err
+ }
+
+ c.sessionID = c.transport.getSessionID()
+ return c.clientAuthenticate(config)
+}
+
+// verifyHostKeySignature verifies the host key obtained in the key exchange.
+// algo is the negotiated algorithm, and may be a certificate type.
+func verifyHostKeySignature(hostKey PublicKey, algo string, result *kexResult) error {
+ sig, rest, ok := parseSignatureBody(result.Signature)
+ if len(rest) > 0 || !ok {
+ return errors.New("ssh: signature parse error")
+ }
+
+ if a := underlyingAlgo(algo); sig.Format != a {
+ return fmt.Errorf("ssh: invalid signature algorithm %q, expected %q", sig.Format, a)
+ }
+
+ return hostKey.Verify(result.H, sig)
+}
+
+// NewSession opens a new Session for this client. (A session is a remote
+// execution of a program.)
+func (c *Client) NewSession() (*Session, error) {
+ ch, in, err := c.OpenChannel("session", nil)
+ if err != nil {
+ return nil, err
+ }
+ return newSession(ch, in)
+}
+
+func (c *Client) handleGlobalRequests(incoming <-chan *Request) {
+ for r := range incoming {
+ // This handles keepalive messages and matches
+ // the behaviour of OpenSSH.
+ r.Reply(false, nil)
+ }
+}
+
+// handleChannelOpens channel open messages from the remote side.
+func (c *Client) handleChannelOpens(in <-chan NewChannel) {
+ for ch := range in {
+ c.mu.Lock()
+ handler := c.channelHandlers[ch.ChannelType()]
+ c.mu.Unlock()
+
+ if handler != nil {
+ handler <- ch
+ } else {
+ ch.Reject(UnknownChannelType, fmt.Sprintf("unknown channel type: %v", ch.ChannelType()))
+ }
+ }
+
+ c.mu.Lock()
+ for _, ch := range c.channelHandlers {
+ close(ch)
+ }
+ c.channelHandlers = nil
+ c.mu.Unlock()
+}
+
+// Dial starts a client connection to the given SSH server. It is a
+// convenience function that connects to the given network address,
+// initiates the SSH handshake, and then sets up a Client. For access
+// to incoming channels and requests, use net.Dial with NewClientConn
+// instead.
+func Dial(network, addr string, config *ClientConfig) (*Client, error) {
+ conn, err := net.DialTimeout(network, addr, config.Timeout)
+ if err != nil {
+ return nil, err
+ }
+ c, chans, reqs, err := NewClientConn(conn, addr, config)
+ if err != nil {
+ return nil, err
+ }
+ return NewClient(c, chans, reqs), nil
+}
+
+// HostKeyCallback is the function type used for verifying server
+// keys. A HostKeyCallback must return nil if the host key is OK, or
+// an error to reject it. It receives the hostname as passed to Dial
+// or NewClientConn. The remote address is the RemoteAddr of the
+// net.Conn underlying the SSH connection.
+type HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error
+
+// BannerCallback is the function type used for treat the banner sent by
+// the server. A BannerCallback receives the message sent by the remote server.
+type BannerCallback func(message string) error
+
+// A ClientConfig structure is used to configure a Client. It must not be
+// modified after having been passed to an SSH function.
+type ClientConfig struct {
+ // Config contains configuration that is shared between clients and
+ // servers.
+ Config
+
+ // User contains the username to authenticate as.
+ User string
+
+ // Auth contains possible authentication methods to use with the
+ // server. Only the first instance of a particular RFC 4252 method will
+ // be used during authentication.
+ Auth []AuthMethod
+
+ // HostKeyCallback is called during the cryptographic
+ // handshake to validate the server's host key. The client
+ // configuration must supply this callback for the connection
+ // to succeed. The functions InsecureIgnoreHostKey or
+ // FixedHostKey can be used for simplistic host key checks.
+ HostKeyCallback HostKeyCallback
+
+ // BannerCallback is called during the SSH dance to display a custom
+ // server's message. The client configuration can supply this callback to
+ // handle it as wished. The function BannerDisplayStderr can be used for
+ // simplistic display on Stderr.
+ BannerCallback BannerCallback
+
+ // ClientVersion contains the version identification string that will
+ // be used for the connection. If empty, a reasonable default is used.
+ ClientVersion string
+
+ // HostKeyAlgorithms lists the public key algorithms that the client will
+ // accept from the server for host key authentication, in order of
+ // preference. If empty, a reasonable default is used. Any
+ // string returned from a PublicKey.Type method may be used, or
+ // any of the CertAlgo and KeyAlgo constants.
+ HostKeyAlgorithms []string
+
+ // Timeout is the maximum amount of time for the TCP connection to establish.
+ //
+ // A Timeout of zero means no timeout.
+ Timeout time.Duration
+}
+
+// InsecureIgnoreHostKey returns a function that can be used for
+// ClientConfig.HostKeyCallback to accept any host key. It should
+// not be used for production code.
+func InsecureIgnoreHostKey() HostKeyCallback {
+ return func(hostname string, remote net.Addr, key PublicKey) error {
+ return nil
+ }
+}
+
+type fixedHostKey struct {
+ key PublicKey
+}
+
+func (f *fixedHostKey) check(hostname string, remote net.Addr, key PublicKey) error {
+ if f.key == nil {
+ return fmt.Errorf("ssh: required host key was nil")
+ }
+ if !bytes.Equal(key.Marshal(), f.key.Marshal()) {
+ return fmt.Errorf("ssh: host key mismatch")
+ }
+ return nil
+}
+
+// FixedHostKey returns a function for use in
+// ClientConfig.HostKeyCallback to accept only a specific host key.
+func FixedHostKey(key PublicKey) HostKeyCallback {
+ hk := &fixedHostKey{key}
+ return hk.check
+}
+
+// BannerDisplayStderr returns a function that can be used for
+// ClientConfig.BannerCallback to display banners on os.Stderr.
+func BannerDisplayStderr() BannerCallback {
+ return func(banner string) error {
+ _, err := os.Stderr.WriteString(banner)
+
+ return err
+ }
+}
diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go
new file mode 100644
index 00000000..b9396101
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/client_auth.go
@@ -0,0 +1,791 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "strings"
+)
+
+type authResult int
+
+const (
+ authFailure authResult = iota
+ authPartialSuccess
+ authSuccess
+)
+
+// clientAuthenticate authenticates with the remote server. See RFC 4252.
+func (c *connection) clientAuthenticate(config *ClientConfig) error {
+ // initiate user auth session
+ if err := c.transport.writePacket(Marshal(&serviceRequestMsg{serviceUserAuth})); err != nil {
+ return err
+ }
+ packet, err := c.transport.readPacket()
+ if err != nil {
+ return err
+ }
+ // The server may choose to send a SSH_MSG_EXT_INFO at this point (if we
+ // advertised willingness to receive one, which we always do) or not. See
+ // RFC 8308, Section 2.4.
+ extensions := make(map[string][]byte)
+ if len(packet) > 0 && packet[0] == msgExtInfo {
+ var extInfo extInfoMsg
+ if err := Unmarshal(packet, &extInfo); err != nil {
+ return err
+ }
+ payload := extInfo.Payload
+ for i := uint32(0); i < extInfo.NumExtensions; i++ {
+ name, rest, ok := parseString(payload)
+ if !ok {
+ return parseError(msgExtInfo)
+ }
+ value, rest, ok := parseString(rest)
+ if !ok {
+ return parseError(msgExtInfo)
+ }
+ extensions[string(name)] = value
+ payload = rest
+ }
+ packet, err = c.transport.readPacket()
+ if err != nil {
+ return err
+ }
+ }
+ var serviceAccept serviceAcceptMsg
+ if err := Unmarshal(packet, &serviceAccept); err != nil {
+ return err
+ }
+
+ // during the authentication phase the client first attempts the "none" method
+ // then any untried methods suggested by the server.
+ var tried []string
+ var lastMethods []string
+
+ sessionID := c.transport.getSessionID()
+ for auth := AuthMethod(new(noneAuth)); auth != nil; {
+ ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions)
+ if err != nil {
+ // On disconnect, return error immediately
+ if _, ok := err.(*disconnectMsg); ok {
+ return err
+ }
+ // We return the error later if there is no other method left to
+ // try.
+ ok = authFailure
+ }
+ if ok == authSuccess {
+ // success
+ return nil
+ } else if ok == authFailure {
+ if m := auth.method(); !contains(tried, m) {
+ tried = append(tried, m)
+ }
+ }
+ if methods == nil {
+ methods = lastMethods
+ }
+ lastMethods = methods
+
+ auth = nil
+
+ findNext:
+ for _, a := range config.Auth {
+ candidateMethod := a.method()
+ if contains(tried, candidateMethod) {
+ continue
+ }
+ for _, meth := range methods {
+ if meth == candidateMethod {
+ auth = a
+ break findNext
+ }
+ }
+ }
+
+ if auth == nil && err != nil {
+ // We have an error and there are no other authentication methods to
+ // try, so we return it.
+ return err
+ }
+ }
+ return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried)
+}
+
+func contains(list []string, e string) bool {
+ for _, s := range list {
+ if s == e {
+ return true
+ }
+ }
+ return false
+}
+
+// An AuthMethod represents an instance of an RFC 4252 authentication method.
+type AuthMethod interface {
+ // auth authenticates user over transport t.
+ // Returns true if authentication is successful.
+ // If authentication is not successful, a []string of alternative
+ // method names is returned. If the slice is nil, it will be ignored
+ // and the previous set of possible methods will be reused.
+ auth(session []byte, user string, p packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error)
+
+ // method returns the RFC 4252 method name.
+ method() string
+}
+
+// "none" authentication, RFC 4252 section 5.2.
+type noneAuth int
+
+func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
+ if err := c.writePacket(Marshal(&userAuthRequestMsg{
+ User: user,
+ Service: serviceSSH,
+ Method: "none",
+ })); err != nil {
+ return authFailure, nil, err
+ }
+
+ return handleAuthResponse(c)
+}
+
+func (n *noneAuth) method() string {
+ return "none"
+}
+
+// passwordCallback is an AuthMethod that fetches the password through
+// a function call, e.g. by prompting the user.
+type passwordCallback func() (password string, err error)
+
+func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
+ type passwordAuthMsg struct {
+ User string `sshtype:"50"`
+ Service string
+ Method string
+ Reply bool
+ Password string
+ }
+
+ pw, err := cb()
+ // REVIEW NOTE: is there a need to support skipping a password attempt?
+ // The program may only find out that the user doesn't have a password
+ // when prompting.
+ if err != nil {
+ return authFailure, nil, err
+ }
+
+ if err := c.writePacket(Marshal(&passwordAuthMsg{
+ User: user,
+ Service: serviceSSH,
+ Method: cb.method(),
+ Reply: false,
+ Password: pw,
+ })); err != nil {
+ return authFailure, nil, err
+ }
+
+ return handleAuthResponse(c)
+}
+
+func (cb passwordCallback) method() string {
+ return "password"
+}
+
+// Password returns an AuthMethod using the given password.
+func Password(secret string) AuthMethod {
+ return passwordCallback(func() (string, error) { return secret, nil })
+}
+
+// PasswordCallback returns an AuthMethod that uses a callback for
+// fetching a password.
+func PasswordCallback(prompt func() (secret string, err error)) AuthMethod {
+ return passwordCallback(prompt)
+}
+
+type publickeyAuthMsg struct {
+ User string `sshtype:"50"`
+ Service string
+ Method string
+ // HasSig indicates to the receiver packet that the auth request is signed and
+ // should be used for authentication of the request.
+ HasSig bool
+ Algoname string
+ PubKey []byte
+ // Sig is tagged with "rest" so Marshal will exclude it during
+ // validateKey
+ Sig []byte `ssh:"rest"`
+}
+
+// publicKeyCallback is an AuthMethod that uses a set of key
+// pairs for authentication.
+type publicKeyCallback func() ([]Signer, error)
+
+func (cb publicKeyCallback) method() string {
+ return "publickey"
+}
+
+func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiAlgorithmSigner, string, error) {
+ var as MultiAlgorithmSigner
+ keyFormat := signer.PublicKey().Type()
+
+ // If the signer implements MultiAlgorithmSigner we use the algorithms it
+ // support, if it implements AlgorithmSigner we assume it supports all
+ // algorithms, otherwise only the key format one.
+ switch s := signer.(type) {
+ case MultiAlgorithmSigner:
+ as = s
+ case AlgorithmSigner:
+ as = &multiAlgorithmSigner{
+ AlgorithmSigner: s,
+ supportedAlgorithms: algorithmsForKeyFormat(underlyingAlgo(keyFormat)),
+ }
+ default:
+ as = &multiAlgorithmSigner{
+ AlgorithmSigner: algorithmSignerWrapper{signer},
+ supportedAlgorithms: []string{underlyingAlgo(keyFormat)},
+ }
+ }
+
+ getFallbackAlgo := func() (string, error) {
+ // Fallback to use if there is no "server-sig-algs" extension or a
+ // common algorithm cannot be found. We use the public key format if the
+ // MultiAlgorithmSigner supports it, otherwise we return an error.
+ if !contains(as.Algorithms(), underlyingAlgo(keyFormat)) {
+ return "", fmt.Errorf("ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v",
+ underlyingAlgo(keyFormat), keyFormat, as.Algorithms())
+ }
+ return keyFormat, nil
+ }
+
+ extPayload, ok := extensions["server-sig-algs"]
+ if !ok {
+ // If there is no "server-sig-algs" extension use the fallback
+ // algorithm.
+ algo, err := getFallbackAlgo()
+ return as, algo, err
+ }
+
+ // The server-sig-algs extension only carries underlying signature
+ // algorithm, but we are trying to select a protocol-level public key
+ // algorithm, which might be a certificate type. Extend the list of server
+ // supported algorithms to include the corresponding certificate algorithms.
+ serverAlgos := strings.Split(string(extPayload), ",")
+ for _, algo := range serverAlgos {
+ if certAlgo, ok := certificateAlgo(algo); ok {
+ serverAlgos = append(serverAlgos, certAlgo)
+ }
+ }
+
+ // Filter algorithms based on those supported by MultiAlgorithmSigner.
+ var keyAlgos []string
+ for _, algo := range algorithmsForKeyFormat(keyFormat) {
+ if contains(as.Algorithms(), underlyingAlgo(algo)) {
+ keyAlgos = append(keyAlgos, algo)
+ }
+ }
+
+ algo, err := findCommon("public key signature algorithm", keyAlgos, serverAlgos)
+ if err != nil {
+ // If there is no overlap, return the fallback algorithm to support
+ // servers that fail to list all supported algorithms.
+ algo, err := getFallbackAlgo()
+ return as, algo, err
+ }
+ return as, algo, nil
+}
+
+func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) {
+ // Authentication is performed by sending an enquiry to test if a key is
+ // acceptable to the remote. If the key is acceptable, the client will
+ // attempt to authenticate with the valid key. If not the client will repeat
+ // the process with the remaining keys.
+
+ signers, err := cb()
+ if err != nil {
+ return authFailure, nil, err
+ }
+ var methods []string
+ var errSigAlgo error
+
+ origSignersLen := len(signers)
+ for idx := 0; idx < len(signers); idx++ {
+ signer := signers[idx]
+ pub := signer.PublicKey()
+ as, algo, err := pickSignatureAlgorithm(signer, extensions)
+ if err != nil && errSigAlgo == nil {
+ // If we cannot negotiate a signature algorithm store the first
+ // error so we can return it to provide a more meaningful message if
+ // no other signers work.
+ errSigAlgo = err
+ continue
+ }
+ ok, err := validateKey(pub, algo, user, c)
+ if err != nil {
+ return authFailure, nil, err
+ }
+ // OpenSSH 7.2-7.7 advertises support for rsa-sha2-256 and rsa-sha2-512
+ // in the "server-sig-algs" extension but doesn't support these
+ // algorithms for certificate authentication, so if the server rejects
+ // the key try to use the obtained algorithm as if "server-sig-algs" had
+ // not been implemented if supported from the algorithm signer.
+ if !ok && idx < origSignersLen && isRSACert(algo) && algo != CertAlgoRSAv01 {
+ if contains(as.Algorithms(), KeyAlgoRSA) {
+ // We retry using the compat algorithm after all signers have
+ // been tried normally.
+ signers = append(signers, &multiAlgorithmSigner{
+ AlgorithmSigner: as,
+ supportedAlgorithms: []string{KeyAlgoRSA},
+ })
+ }
+ }
+ if !ok {
+ continue
+ }
+
+ pubKey := pub.Marshal()
+ data := buildDataSignedForAuth(session, userAuthRequestMsg{
+ User: user,
+ Service: serviceSSH,
+ Method: cb.method(),
+ }, algo, pubKey)
+ sign, err := as.SignWithAlgorithm(rand, data, underlyingAlgo(algo))
+ if err != nil {
+ return authFailure, nil, err
+ }
+
+ // manually wrap the serialized signature in a string
+ s := Marshal(sign)
+ sig := make([]byte, stringLength(len(s)))
+ marshalString(sig, s)
+ msg := publickeyAuthMsg{
+ User: user,
+ Service: serviceSSH,
+ Method: cb.method(),
+ HasSig: true,
+ Algoname: algo,
+ PubKey: pubKey,
+ Sig: sig,
+ }
+ p := Marshal(&msg)
+ if err := c.writePacket(p); err != nil {
+ return authFailure, nil, err
+ }
+ var success authResult
+ success, methods, err = handleAuthResponse(c)
+ if err != nil {
+ return authFailure, nil, err
+ }
+
+ // If authentication succeeds or the list of available methods does not
+ // contain the "publickey" method, do not attempt to authenticate with any
+ // other keys. According to RFC 4252 Section 7, the latter can occur when
+ // additional authentication methods are required.
+ if success == authSuccess || !contains(methods, cb.method()) {
+ return success, methods, err
+ }
+ }
+
+ return authFailure, methods, errSigAlgo
+}
+
+// validateKey validates the key provided is acceptable to the server.
+func validateKey(key PublicKey, algo string, user string, c packetConn) (bool, error) {
+ pubKey := key.Marshal()
+ msg := publickeyAuthMsg{
+ User: user,
+ Service: serviceSSH,
+ Method: "publickey",
+ HasSig: false,
+ Algoname: algo,
+ PubKey: pubKey,
+ }
+ if err := c.writePacket(Marshal(&msg)); err != nil {
+ return false, err
+ }
+
+ return confirmKeyAck(key, c)
+}
+
+func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
+ pubKey := key.Marshal()
+
+ for {
+ packet, err := c.readPacket()
+ if err != nil {
+ return false, err
+ }
+ switch packet[0] {
+ case msgUserAuthBanner:
+ if err := handleBannerResponse(c, packet); err != nil {
+ return false, err
+ }
+ case msgUserAuthPubKeyOk:
+ var msg userAuthPubKeyOkMsg
+ if err := Unmarshal(packet, &msg); err != nil {
+ return false, err
+ }
+ // According to RFC 4252 Section 7 the algorithm in
+ // SSH_MSG_USERAUTH_PK_OK should match that of the request but some
+ // servers send the key type instead. OpenSSH allows any algorithm
+ // that matches the public key, so we do the same.
+ // https://github.com/openssh/openssh-portable/blob/86bdd385/sshconnect2.c#L709
+ if !contains(algorithmsForKeyFormat(key.Type()), msg.Algo) {
+ return false, nil
+ }
+ if !bytes.Equal(msg.PubKey, pubKey) {
+ return false, nil
+ }
+ return true, nil
+ case msgUserAuthFailure:
+ return false, nil
+ default:
+ return false, unexpectedMessageError(msgUserAuthPubKeyOk, packet[0])
+ }
+ }
+}
+
+// PublicKeys returns an AuthMethod that uses the given key
+// pairs.
+func PublicKeys(signers ...Signer) AuthMethod {
+ return publicKeyCallback(func() ([]Signer, error) { return signers, nil })
+}
+
+// PublicKeysCallback returns an AuthMethod that runs the given
+// function to obtain a list of key pairs.
+func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMethod {
+ return publicKeyCallback(getSigners)
+}
+
+// handleAuthResponse returns whether the preceding authentication request succeeded
+// along with a list of remaining authentication methods to try next and
+// an error if an unexpected response was received.
+func handleAuthResponse(c packetConn) (authResult, []string, error) {
+ gotMsgExtInfo := false
+ for {
+ packet, err := c.readPacket()
+ if err != nil {
+ return authFailure, nil, err
+ }
+
+ switch packet[0] {
+ case msgUserAuthBanner:
+ if err := handleBannerResponse(c, packet); err != nil {
+ return authFailure, nil, err
+ }
+ case msgExtInfo:
+ // Ignore post-authentication RFC 8308 extensions, once.
+ if gotMsgExtInfo {
+ return authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
+ }
+ gotMsgExtInfo = true
+ case msgUserAuthFailure:
+ var msg userAuthFailureMsg
+ if err := Unmarshal(packet, &msg); err != nil {
+ return authFailure, nil, err
+ }
+ if msg.PartialSuccess {
+ return authPartialSuccess, msg.Methods, nil
+ }
+ return authFailure, msg.Methods, nil
+ case msgUserAuthSuccess:
+ return authSuccess, nil, nil
+ default:
+ return authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
+ }
+ }
+}
+
+func handleBannerResponse(c packetConn, packet []byte) error {
+ var msg userAuthBannerMsg
+ if err := Unmarshal(packet, &msg); err != nil {
+ return err
+ }
+
+ transport, ok := c.(*handshakeTransport)
+ if !ok {
+ return nil
+ }
+
+ if transport.bannerCallback != nil {
+ return transport.bannerCallback(msg.Message)
+ }
+
+ return nil
+}
+
+// KeyboardInteractiveChallenge should print questions, optionally
+// disabling echoing (e.g. for passwords), and return all the answers.
+// Challenge may be called multiple times in a single session. After
+// successful authentication, the server may send a challenge with no
+// questions, for which the name and instruction messages should be
+// printed. RFC 4256 section 3.3 details how the UI should behave for
+// both CLI and GUI environments.
+type KeyboardInteractiveChallenge func(name, instruction string, questions []string, echos []bool) (answers []string, err error)
+
+// KeyboardInteractive returns an AuthMethod using a prompt/response
+// sequence controlled by the server.
+func KeyboardInteractive(challenge KeyboardInteractiveChallenge) AuthMethod {
+ return challenge
+}
+
+func (cb KeyboardInteractiveChallenge) method() string {
+ return "keyboard-interactive"
+}
+
+func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
+ type initiateMsg struct {
+ User string `sshtype:"50"`
+ Service string
+ Method string
+ Language string
+ Submethods string
+ }
+
+ if err := c.writePacket(Marshal(&initiateMsg{
+ User: user,
+ Service: serviceSSH,
+ Method: "keyboard-interactive",
+ })); err != nil {
+ return authFailure, nil, err
+ }
+
+ gotMsgExtInfo := false
+ for {
+ packet, err := c.readPacket()
+ if err != nil {
+ return authFailure, nil, err
+ }
+
+ // like handleAuthResponse, but with less options.
+ switch packet[0] {
+ case msgUserAuthBanner:
+ if err := handleBannerResponse(c, packet); err != nil {
+ return authFailure, nil, err
+ }
+ continue
+ case msgExtInfo:
+ // Ignore post-authentication RFC 8308 extensions, once.
+ if gotMsgExtInfo {
+ return authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
+ }
+ gotMsgExtInfo = true
+ continue
+ case msgUserAuthInfoRequest:
+ // OK
+ case msgUserAuthFailure:
+ var msg userAuthFailureMsg
+ if err := Unmarshal(packet, &msg); err != nil {
+ return authFailure, nil, err
+ }
+ if msg.PartialSuccess {
+ return authPartialSuccess, msg.Methods, nil
+ }
+ return authFailure, msg.Methods, nil
+ case msgUserAuthSuccess:
+ return authSuccess, nil, nil
+ default:
+ return authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
+ }
+
+ var msg userAuthInfoRequestMsg
+ if err := Unmarshal(packet, &msg); err != nil {
+ return authFailure, nil, err
+ }
+
+ // Manually unpack the prompt/echo pairs.
+ rest := msg.Prompts
+ var prompts []string
+ var echos []bool
+ for i := 0; i < int(msg.NumPrompts); i++ {
+ prompt, r, ok := parseString(rest)
+ if !ok || len(r) == 0 {
+ return authFailure, nil, errors.New("ssh: prompt format error")
+ }
+ prompts = append(prompts, string(prompt))
+ echos = append(echos, r[0] != 0)
+ rest = r[1:]
+ }
+
+ if len(rest) != 0 {
+ return authFailure, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
+ }
+
+ answers, err := cb(msg.Name, msg.Instruction, prompts, echos)
+ if err != nil {
+ return authFailure, nil, err
+ }
+
+ if len(answers) != len(prompts) {
+ return authFailure, nil, fmt.Errorf("ssh: incorrect number of answers from keyboard-interactive callback %d (expected %d)", len(answers), len(prompts))
+ }
+ responseLength := 1 + 4
+ for _, a := range answers {
+ responseLength += stringLength(len(a))
+ }
+ serialized := make([]byte, responseLength)
+ p := serialized
+ p[0] = msgUserAuthInfoResponse
+ p = p[1:]
+ p = marshalUint32(p, uint32(len(answers)))
+ for _, a := range answers {
+ p = marshalString(p, []byte(a))
+ }
+
+ if err := c.writePacket(serialized); err != nil {
+ return authFailure, nil, err
+ }
+ }
+}
+
+type retryableAuthMethod struct {
+ authMethod AuthMethod
+ maxTries int
+}
+
+func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (ok authResult, methods []string, err error) {
+ for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {
+ ok, methods, err = r.authMethod.auth(session, user, c, rand, extensions)
+ if ok != authFailure || err != nil { // either success, partial success or error terminate
+ return ok, methods, err
+ }
+ }
+ return ok, methods, err
+}
+
+func (r *retryableAuthMethod) method() string {
+ return r.authMethod.method()
+}
+
+// RetryableAuthMethod is a decorator for other auth methods enabling them to
+// be retried up to maxTries before considering that AuthMethod itself failed.
+// If maxTries is <= 0, will retry indefinitely
+//
+// This is useful for interactive clients using challenge/response type
+// authentication (e.g. Keyboard-Interactive, Password, etc) where the user
+// could mistype their response resulting in the server issuing a
+// SSH_MSG_USERAUTH_FAILURE (rfc4252 #8 [password] and rfc4256 #3.4
+// [keyboard-interactive]); Without this decorator, the non-retryable
+// AuthMethod would be removed from future consideration, and never tried again
+// (and so the user would never be able to retry their entry).
+func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod {
+ return &retryableAuthMethod{authMethod: auth, maxTries: maxTries}
+}
+
+// GSSAPIWithMICAuthMethod is an AuthMethod with "gssapi-with-mic" authentication.
+// See RFC 4462 section 3
+// gssAPIClient is implementation of the GSSAPIClient interface, see the definition of the interface for details.
+// target is the server host you want to log in to.
+func GSSAPIWithMICAuthMethod(gssAPIClient GSSAPIClient, target string) AuthMethod {
+ if gssAPIClient == nil {
+ panic("gss-api client must be not nil with enable gssapi-with-mic")
+ }
+ return &gssAPIWithMICCallback{gssAPIClient: gssAPIClient, target: target}
+}
+
+type gssAPIWithMICCallback struct {
+ gssAPIClient GSSAPIClient
+ target string
+}
+
+func (g *gssAPIWithMICCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
+ m := &userAuthRequestMsg{
+ User: user,
+ Service: serviceSSH,
+ Method: g.method(),
+ }
+ // The GSS-API authentication method is initiated when the client sends an SSH_MSG_USERAUTH_REQUEST.
+ // See RFC 4462 section 3.2.
+ m.Payload = appendU32(m.Payload, 1)
+ m.Payload = appendString(m.Payload, string(krb5OID))
+ if err := c.writePacket(Marshal(m)); err != nil {
+ return authFailure, nil, err
+ }
+ // The server responds to the SSH_MSG_USERAUTH_REQUEST with either an
+ // SSH_MSG_USERAUTH_FAILURE if none of the mechanisms are supported or
+ // with an SSH_MSG_USERAUTH_GSSAPI_RESPONSE.
+ // See RFC 4462 section 3.3.
+ // OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication,so I don't want to check
+ // selected mech if it is valid.
+ packet, err := c.readPacket()
+ if err != nil {
+ return authFailure, nil, err
+ }
+ userAuthGSSAPIResp := &userAuthGSSAPIResponse{}
+ if err := Unmarshal(packet, userAuthGSSAPIResp); err != nil {
+ return authFailure, nil, err
+ }
+ // Start the loop into the exchange token.
+ // See RFC 4462 section 3.4.
+ var token []byte
+ defer g.gssAPIClient.DeleteSecContext()
+ for {
+ // Initiates the establishment of a security context between the application and a remote peer.
+ nextToken, needContinue, err := g.gssAPIClient.InitSecContext("host@"+g.target, token, false)
+ if err != nil {
+ return authFailure, nil, err
+ }
+ if len(nextToken) > 0 {
+ if err := c.writePacket(Marshal(&userAuthGSSAPIToken{
+ Token: nextToken,
+ })); err != nil {
+ return authFailure, nil, err
+ }
+ }
+ if !needContinue {
+ break
+ }
+ packet, err = c.readPacket()
+ if err != nil {
+ return authFailure, nil, err
+ }
+ switch packet[0] {
+ case msgUserAuthFailure:
+ var msg userAuthFailureMsg
+ if err := Unmarshal(packet, &msg); err != nil {
+ return authFailure, nil, err
+ }
+ if msg.PartialSuccess {
+ return authPartialSuccess, msg.Methods, nil
+ }
+ return authFailure, msg.Methods, nil
+ case msgUserAuthGSSAPIError:
+ userAuthGSSAPIErrorResp := &userAuthGSSAPIError{}
+ if err := Unmarshal(packet, userAuthGSSAPIErrorResp); err != nil {
+ return authFailure, nil, err
+ }
+ return authFailure, nil, fmt.Errorf("GSS-API Error:\n"+
+ "Major Status: %d\n"+
+ "Minor Status: %d\n"+
+ "Error Message: %s\n", userAuthGSSAPIErrorResp.MajorStatus, userAuthGSSAPIErrorResp.MinorStatus,
+ userAuthGSSAPIErrorResp.Message)
+ case msgUserAuthGSSAPIToken:
+ userAuthGSSAPITokenReq := &userAuthGSSAPIToken{}
+ if err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {
+ return authFailure, nil, err
+ }
+ token = userAuthGSSAPITokenReq.Token
+ }
+ }
+ // Binding Encryption Keys.
+ // See RFC 4462 section 3.5.
+ micField := buildMIC(string(session), user, "ssh-connection", "gssapi-with-mic")
+ micToken, err := g.gssAPIClient.GetMIC(micField)
+ if err != nil {
+ return authFailure, nil, err
+ }
+ if err := c.writePacket(Marshal(&userAuthGSSAPIMIC{
+ MIC: micToken,
+ })); err != nil {
+ return authFailure, nil, err
+ }
+ return handleAuthResponse(c)
+}
+
+func (g *gssAPIWithMICCallback) method() string {
+ return "gssapi-with-mic"
+}
diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go
new file mode 100644
index 00000000..7e9c2cbc
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/common.go
@@ -0,0 +1,476 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "crypto"
+ "crypto/rand"
+ "fmt"
+ "io"
+ "math"
+ "sync"
+
+ _ "crypto/sha1"
+ _ "crypto/sha256"
+ _ "crypto/sha512"
+)
+
+// These are string constants in the SSH protocol.
+const (
+ compressionNone = "none"
+ serviceUserAuth = "ssh-userauth"
+ serviceSSH = "ssh-connection"
+)
+
+// supportedCiphers lists ciphers we support but might not recommend.
+var supportedCiphers = []string{
+ "aes128-ctr", "aes192-ctr", "aes256-ctr",
+ "aes128-gcm@openssh.com", gcm256CipherID,
+ chacha20Poly1305ID,
+ "arcfour256", "arcfour128", "arcfour",
+ aes128cbcID,
+ tripledescbcID,
+}
+
+// preferredCiphers specifies the default preference for ciphers.
+var preferredCiphers = []string{
+ "aes128-gcm@openssh.com", gcm256CipherID,
+ chacha20Poly1305ID,
+ "aes128-ctr", "aes192-ctr", "aes256-ctr",
+}
+
+// supportedKexAlgos specifies the supported key-exchange algorithms in
+// preference order.
+var supportedKexAlgos = []string{
+ kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,
+ // P384 and P521 are not constant-time yet, but since we don't
+ // reuse ephemeral keys, using them for ECDH should be OK.
+ kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
+ kexAlgoDH14SHA256, kexAlgoDH16SHA512, kexAlgoDH14SHA1,
+ kexAlgoDH1SHA1,
+}
+
+// serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden
+// for the server half.
+var serverForbiddenKexAlgos = map[string]struct{}{
+ kexAlgoDHGEXSHA1: {}, // server half implementation is only minimal to satisfy the automated tests
+ kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests
+}
+
+// preferredKexAlgos specifies the default preference for key-exchange
+// algorithms in preference order. The diffie-hellman-group16-sha512 algorithm
+// is disabled by default because it is a bit slower than the others.
+var preferredKexAlgos = []string{
+ kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,
+ kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
+ kexAlgoDH14SHA256, kexAlgoDH14SHA1,
+}
+
+// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
+// of authenticating servers) in preference order.
+var supportedHostKeyAlgos = []string{
+ CertAlgoRSASHA256v01, CertAlgoRSASHA512v01,
+ CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
+ CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
+
+ KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
+ KeyAlgoRSASHA256, KeyAlgoRSASHA512,
+ KeyAlgoRSA, KeyAlgoDSA,
+
+ KeyAlgoED25519,
+}
+
+// supportedMACs specifies a default set of MAC algorithms in preference order.
+// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed
+// because they have reached the end of their useful life.
+var supportedMACs = []string{
+ "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1", "hmac-sha1-96",
+}
+
+var supportedCompressions = []string{compressionNone}
+
+// hashFuncs keeps the mapping of supported signature algorithms to their
+// respective hashes needed for signing and verification.
+var hashFuncs = map[string]crypto.Hash{
+ KeyAlgoRSA: crypto.SHA1,
+ KeyAlgoRSASHA256: crypto.SHA256,
+ KeyAlgoRSASHA512: crypto.SHA512,
+ KeyAlgoDSA: crypto.SHA1,
+ KeyAlgoECDSA256: crypto.SHA256,
+ KeyAlgoECDSA384: crypto.SHA384,
+ KeyAlgoECDSA521: crypto.SHA512,
+ // KeyAlgoED25519 doesn't pre-hash.
+ KeyAlgoSKECDSA256: crypto.SHA256,
+ KeyAlgoSKED25519: crypto.SHA256,
+}
+
+// algorithmsForKeyFormat returns the supported signature algorithms for a given
+// public key format (PublicKey.Type), in order of preference. See RFC 8332,
+// Section 2. See also the note in sendKexInit on backwards compatibility.
+func algorithmsForKeyFormat(keyFormat string) []string {
+ switch keyFormat {
+ case KeyAlgoRSA:
+ return []string{KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA}
+ case CertAlgoRSAv01:
+ return []string{CertAlgoRSASHA256v01, CertAlgoRSASHA512v01, CertAlgoRSAv01}
+ default:
+ return []string{keyFormat}
+ }
+}
+
+// isRSA returns whether algo is a supported RSA algorithm, including certificate
+// algorithms.
+func isRSA(algo string) bool {
+ algos := algorithmsForKeyFormat(KeyAlgoRSA)
+ return contains(algos, underlyingAlgo(algo))
+}
+
+func isRSACert(algo string) bool {
+ _, ok := certKeyAlgoNames[algo]
+ if !ok {
+ return false
+ }
+ return isRSA(algo)
+}
+
+// supportedPubKeyAuthAlgos specifies the supported client public key
+// authentication algorithms. Note that this doesn't include certificate types
+// since those use the underlying algorithm. This list is sent to the client if
+// it supports the server-sig-algs extension. Order is irrelevant.
+var supportedPubKeyAuthAlgos = []string{
+ KeyAlgoED25519,
+ KeyAlgoSKED25519, KeyAlgoSKECDSA256,
+ KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
+ KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA,
+ KeyAlgoDSA,
+}
+
+// unexpectedMessageError results when the SSH message that we received didn't
+// match what we wanted.
+func unexpectedMessageError(expected, got uint8) error {
+ return fmt.Errorf("ssh: unexpected message type %d (expected %d)", got, expected)
+}
+
+// parseError results from a malformed SSH message.
+func parseError(tag uint8) error {
+ return fmt.Errorf("ssh: parse error in message type %d", tag)
+}
+
+func findCommon(what string, client []string, server []string) (common string, err error) {
+ for _, c := range client {
+ for _, s := range server {
+ if c == s {
+ return c, nil
+ }
+ }
+ }
+ return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server)
+}
+
+// directionAlgorithms records algorithm choices in one direction (either read or write)
+type directionAlgorithms struct {
+ Cipher string
+ MAC string
+ Compression string
+}
+
+// rekeyBytes returns a rekeying intervals in bytes.
+func (a *directionAlgorithms) rekeyBytes() int64 {
+ // According to RFC 4344 block ciphers should rekey after
+ // 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
+ // 128.
+ switch a.Cipher {
+ case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcm128CipherID, gcm256CipherID, aes128cbcID:
+ return 16 * (1 << 32)
+
+ }
+
+ // For others, stick with RFC 4253 recommendation to rekey after 1 Gb of data.
+ return 1 << 30
+}
+
+var aeadCiphers = map[string]bool{
+ gcm128CipherID: true,
+ gcm256CipherID: true,
+ chacha20Poly1305ID: true,
+}
+
+type algorithms struct {
+ kex string
+ hostKey string
+ w directionAlgorithms
+ r directionAlgorithms
+}
+
+func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) {
+ result := &algorithms{}
+
+ result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos)
+ if err != nil {
+ return
+ }
+
+ result.hostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos)
+ if err != nil {
+ return
+ }
+
+ stoc, ctos := &result.w, &result.r
+ if isClient {
+ ctos, stoc = stoc, ctos
+ }
+
+ ctos.Cipher, err = findCommon("client to server cipher", clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer)
+ if err != nil {
+ return
+ }
+
+ stoc.Cipher, err = findCommon("server to client cipher", clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient)
+ if err != nil {
+ return
+ }
+
+ if !aeadCiphers[ctos.Cipher] {
+ ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
+ if err != nil {
+ return
+ }
+ }
+
+ if !aeadCiphers[stoc.Cipher] {
+ stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
+ if err != nil {
+ return
+ }
+ }
+
+ ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
+ if err != nil {
+ return
+ }
+
+ stoc.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient)
+ if err != nil {
+ return
+ }
+
+ return result, nil
+}
+
+// If rekeythreshold is too small, we can't make any progress sending
+// stuff.
+const minRekeyThreshold uint64 = 256
+
+// Config contains configuration data common to both ServerConfig and
+// ClientConfig.
+type Config struct {
+ // Rand provides the source of entropy for cryptographic
+ // primitives. If Rand is nil, the cryptographic random reader
+ // in package crypto/rand will be used.
+ Rand io.Reader
+
+ // The maximum number of bytes sent or received after which a
+ // new key is negotiated. It must be at least 256. If
+ // unspecified, a size suitable for the chosen cipher is used.
+ RekeyThreshold uint64
+
+ // The allowed key exchanges algorithms. If unspecified then a default set
+ // of algorithms is used. Unsupported values are silently ignored.
+ KeyExchanges []string
+
+ // The allowed cipher algorithms. If unspecified then a sensible default is
+ // used. Unsupported values are silently ignored.
+ Ciphers []string
+
+ // The allowed MAC algorithms. If unspecified then a sensible default is
+ // used. Unsupported values are silently ignored.
+ MACs []string
+}
+
+// SetDefaults sets sensible values for unset fields in config. This is
+// exported for testing: Configs passed to SSH functions are copied and have
+// default values set automatically.
+func (c *Config) SetDefaults() {
+ if c.Rand == nil {
+ c.Rand = rand.Reader
+ }
+ if c.Ciphers == nil {
+ c.Ciphers = preferredCiphers
+ }
+ var ciphers []string
+ for _, c := range c.Ciphers {
+ if cipherModes[c] != nil {
+ // Ignore the cipher if we have no cipherModes definition.
+ ciphers = append(ciphers, c)
+ }
+ }
+ c.Ciphers = ciphers
+
+ if c.KeyExchanges == nil {
+ c.KeyExchanges = preferredKexAlgos
+ }
+ var kexs []string
+ for _, k := range c.KeyExchanges {
+ if kexAlgoMap[k] != nil {
+ // Ignore the KEX if we have no kexAlgoMap definition.
+ kexs = append(kexs, k)
+ }
+ }
+ c.KeyExchanges = kexs
+
+ if c.MACs == nil {
+ c.MACs = supportedMACs
+ }
+ var macs []string
+ for _, m := range c.MACs {
+ if macModes[m] != nil {
+ // Ignore the MAC if we have no macModes definition.
+ macs = append(macs, m)
+ }
+ }
+ c.MACs = macs
+
+ if c.RekeyThreshold == 0 {
+ // cipher specific default
+ } else if c.RekeyThreshold < minRekeyThreshold {
+ c.RekeyThreshold = minRekeyThreshold
+ } else if c.RekeyThreshold >= math.MaxInt64 {
+ // Avoid weirdness if somebody uses -1 as a threshold.
+ c.RekeyThreshold = math.MaxInt64
+ }
+}
+
+// buildDataSignedForAuth returns the data that is signed in order to prove
+// possession of a private key. See RFC 4252, section 7. algo is the advertised
+// algorithm, and may be a certificate type.
+func buildDataSignedForAuth(sessionID []byte, req userAuthRequestMsg, algo string, pubKey []byte) []byte {
+ data := struct {
+ Session []byte
+ Type byte
+ User string
+ Service string
+ Method string
+ Sign bool
+ Algo string
+ PubKey []byte
+ }{
+ sessionID,
+ msgUserAuthRequest,
+ req.User,
+ req.Service,
+ req.Method,
+ true,
+ algo,
+ pubKey,
+ }
+ return Marshal(data)
+}
+
+func appendU16(buf []byte, n uint16) []byte {
+ return append(buf, byte(n>>8), byte(n))
+}
+
+func appendU32(buf []byte, n uint32) []byte {
+ return append(buf, byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
+}
+
+func appendU64(buf []byte, n uint64) []byte {
+ return append(buf,
+ byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32),
+ byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
+}
+
+func appendInt(buf []byte, n int) []byte {
+ return appendU32(buf, uint32(n))
+}
+
+func appendString(buf []byte, s string) []byte {
+ buf = appendU32(buf, uint32(len(s)))
+ buf = append(buf, s...)
+ return buf
+}
+
+func appendBool(buf []byte, b bool) []byte {
+ if b {
+ return append(buf, 1)
+ }
+ return append(buf, 0)
+}
+
+// newCond is a helper to hide the fact that there is no usable zero
+// value for sync.Cond.
+func newCond() *sync.Cond { return sync.NewCond(new(sync.Mutex)) }
+
+// window represents the buffer available to clients
+// wishing to write to a channel.
+type window struct {
+ *sync.Cond
+ win uint32 // RFC 4254 5.2 says the window size can grow to 2^32-1
+ writeWaiters int
+ closed bool
+}
+
+// add adds win to the amount of window available
+// for consumers.
+func (w *window) add(win uint32) bool {
+ // a zero sized window adjust is a noop.
+ if win == 0 {
+ return true
+ }
+ w.L.Lock()
+ if w.win+win < win {
+ w.L.Unlock()
+ return false
+ }
+ w.win += win
+ // It is unusual that multiple goroutines would be attempting to reserve
+ // window space, but not guaranteed. Use broadcast to notify all waiters
+ // that additional window is available.
+ w.Broadcast()
+ w.L.Unlock()
+ return true
+}
+
+// close sets the window to closed, so all reservations fail
+// immediately.
+func (w *window) close() {
+ w.L.Lock()
+ w.closed = true
+ w.Broadcast()
+ w.L.Unlock()
+}
+
+// reserve reserves win from the available window capacity.
+// If no capacity remains, reserve will block. reserve may
+// return less than requested.
+func (w *window) reserve(win uint32) (uint32, error) {
+ var err error
+ w.L.Lock()
+ w.writeWaiters++
+ w.Broadcast()
+ for w.win == 0 && !w.closed {
+ w.Wait()
+ }
+ w.writeWaiters--
+ if w.win < win {
+ win = w.win
+ }
+ w.win -= win
+ if w.closed {
+ err = io.EOF
+ }
+ w.L.Unlock()
+ return win, err
+}
+
+// waitWriterBlocked waits until some goroutine is blocked for further
+// writes. It is used in tests only.
+func (w *window) waitWriterBlocked() {
+ w.Cond.L.Lock()
+ for w.writeWaiters == 0 {
+ w.Cond.Wait()
+ }
+ w.Cond.L.Unlock()
+}
diff --git a/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go
new file mode 100644
index 00000000..8f345ee9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/connection.go
@@ -0,0 +1,143 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "fmt"
+ "net"
+)
+
+// OpenChannelError is returned if the other side rejects an
+// OpenChannel request.
+type OpenChannelError struct {
+ Reason RejectionReason
+ Message string
+}
+
+func (e *OpenChannelError) Error() string {
+ return fmt.Sprintf("ssh: rejected: %s (%s)", e.Reason, e.Message)
+}
+
+// ConnMetadata holds metadata for the connection.
+type ConnMetadata interface {
+ // User returns the user ID for this connection.
+ User() string
+
+ // SessionID returns the session hash, also denoted by H.
+ SessionID() []byte
+
+ // ClientVersion returns the client's version string as hashed
+ // into the session ID.
+ ClientVersion() []byte
+
+ // ServerVersion returns the server's version string as hashed
+ // into the session ID.
+ ServerVersion() []byte
+
+ // RemoteAddr returns the remote address for this connection.
+ RemoteAddr() net.Addr
+
+ // LocalAddr returns the local address for this connection.
+ LocalAddr() net.Addr
+}
+
+// Conn represents an SSH connection for both server and client roles.
+// Conn is the basis for implementing an application layer, such
+// as ClientConn, which implements the traditional shell access for
+// clients.
+type Conn interface {
+ ConnMetadata
+
+ // SendRequest sends a global request, and returns the
+ // reply. If wantReply is true, it returns the response status
+ // and payload. See also RFC 4254, section 4.
+ SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)
+
+ // OpenChannel tries to open an channel. If the request is
+ // rejected, it returns *OpenChannelError. On success it returns
+ // the SSH Channel and a Go channel for incoming, out-of-band
+ // requests. The Go channel must be serviced, or the
+ // connection will hang.
+ OpenChannel(name string, data []byte) (Channel, <-chan *Request, error)
+
+ // Close closes the underlying network connection
+ Close() error
+
+ // Wait blocks until the connection has shut down, and returns the
+ // error causing the shutdown.
+ Wait() error
+
+ // TODO(hanwen): consider exposing:
+ // RequestKeyChange
+ // Disconnect
+}
+
+// DiscardRequests consumes and rejects all requests from the
+// passed-in channel.
+func DiscardRequests(in <-chan *Request) {
+ for req := range in {
+ if req.WantReply {
+ req.Reply(false, nil)
+ }
+ }
+}
+
+// A connection represents an incoming connection.
+type connection struct {
+ transport *handshakeTransport
+ sshConn
+
+ // The connection protocol.
+ *mux
+}
+
+func (c *connection) Close() error {
+ return c.sshConn.conn.Close()
+}
+
+// sshConn provides net.Conn metadata, but disallows direct reads and
+// writes.
+type sshConn struct {
+ conn net.Conn
+
+ user string
+ sessionID []byte
+ clientVersion []byte
+ serverVersion []byte
+}
+
+func dup(src []byte) []byte {
+ dst := make([]byte, len(src))
+ copy(dst, src)
+ return dst
+}
+
+func (c *sshConn) User() string {
+ return c.user
+}
+
+func (c *sshConn) RemoteAddr() net.Addr {
+ return c.conn.RemoteAddr()
+}
+
+func (c *sshConn) Close() error {
+ return c.conn.Close()
+}
+
+func (c *sshConn) LocalAddr() net.Addr {
+ return c.conn.LocalAddr()
+}
+
+func (c *sshConn) SessionID() []byte {
+ return dup(c.sessionID)
+}
+
+func (c *sshConn) ClientVersion() []byte {
+ return dup(c.clientVersion)
+}
+
+func (c *sshConn) ServerVersion() []byte {
+ return dup(c.serverVersion)
+}
diff --git a/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go
new file mode 100644
index 00000000..f5d352fe
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/doc.go
@@ -0,0 +1,23 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package ssh implements an SSH client and server.
+
+SSH is a transport security protocol, an authentication protocol and a
+family of application protocols. The most typical application level
+protocol is a remote shell and this is specifically implemented. However,
+the multiplexed nature of SSH is exposed to users that wish to support
+others.
+
+References:
+
+ [PROTOCOL]: https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=HEAD
+ [PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
+ [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
+
+This package does not fall under the stability promise of the Go language itself,
+so its API may be changed when pressing needs arise.
+*/
+package ssh
diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go
new file mode 100644
index 00000000..56cdc7c2
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/handshake.go
@@ -0,0 +1,806 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "crypto/rand"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "net"
+ "strings"
+ "sync"
+)
+
+// debugHandshake, if set, prints messages sent and received. Key
+// exchange messages are printed as if DH were used, so the debug
+// messages are wrong when using ECDH.
+const debugHandshake = false
+
+// chanSize sets the amount of buffering SSH connections. This is
+// primarily for testing: setting chanSize=0 uncovers deadlocks more
+// quickly.
+const chanSize = 16
+
+// keyingTransport is a packet based transport that supports key
+// changes. It need not be thread-safe. It should pass through
+// msgNewKeys in both directions.
+type keyingTransport interface {
+ packetConn
+
+ // prepareKeyChange sets up a key change. The key change for a
+ // direction will be effected if a msgNewKeys message is sent
+ // or received.
+ prepareKeyChange(*algorithms, *kexResult) error
+
+ // setStrictMode sets the strict KEX mode, notably triggering
+ // sequence number resets on sending or receiving msgNewKeys.
+ // If the sequence number is already > 1 when setStrictMode
+ // is called, an error is returned.
+ setStrictMode() error
+
+ // setInitialKEXDone indicates to the transport that the initial key exchange
+ // was completed
+ setInitialKEXDone()
+}
+
+// handshakeTransport implements rekeying on top of a keyingTransport
+// and offers a thread-safe writePacket() interface.
+type handshakeTransport struct {
+ conn keyingTransport
+ config *Config
+
+ serverVersion []byte
+ clientVersion []byte
+
+ // hostKeys is non-empty if we are the server. In that case,
+ // it contains all host keys that can be used to sign the
+ // connection.
+ hostKeys []Signer
+
+ // publicKeyAuthAlgorithms is non-empty if we are the server. In that case,
+ // it contains the supported client public key authentication algorithms.
+ publicKeyAuthAlgorithms []string
+
+ // hostKeyAlgorithms is non-empty if we are the client. In that case,
+ // we accept these key types from the server as host key.
+ hostKeyAlgorithms []string
+
+ // On read error, incoming is closed, and readError is set.
+ incoming chan []byte
+ readError error
+
+ mu sync.Mutex
+ writeError error
+ sentInitPacket []byte
+ sentInitMsg *kexInitMsg
+ pendingPackets [][]byte // Used when a key exchange is in progress.
+ writePacketsLeft uint32
+ writeBytesLeft int64
+
+ // If the read loop wants to schedule a kex, it pings this
+ // channel, and the write loop will send out a kex
+ // message.
+ requestKex chan struct{}
+
+ // If the other side requests or confirms a kex, its kexInit
+ // packet is sent here for the write loop to find it.
+ startKex chan *pendingKex
+ kexLoopDone chan struct{} // closed (with writeError non-nil) when kexLoop exits
+
+ // data for host key checking
+ hostKeyCallback HostKeyCallback
+ dialAddress string
+ remoteAddr net.Addr
+
+ // bannerCallback is non-empty if we are the client and it has been set in
+ // ClientConfig. In that case it is called during the user authentication
+ // dance to handle a custom server's message.
+ bannerCallback BannerCallback
+
+ // Algorithms agreed in the last key exchange.
+ algorithms *algorithms
+
+ // Counters exclusively owned by readLoop.
+ readPacketsLeft uint32
+ readBytesLeft int64
+
+ // The session ID or nil if first kex did not complete yet.
+ sessionID []byte
+
+ // strictMode indicates if the other side of the handshake indicated
+ // that we should be following the strict KEX protocol restrictions.
+ strictMode bool
+}
+
+type pendingKex struct {
+ otherInit []byte
+ done chan error
+}
+
+func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion, serverVersion []byte) *handshakeTransport {
+ t := &handshakeTransport{
+ conn: conn,
+ serverVersion: serverVersion,
+ clientVersion: clientVersion,
+ incoming: make(chan []byte, chanSize),
+ requestKex: make(chan struct{}, 1),
+ startKex: make(chan *pendingKex),
+ kexLoopDone: make(chan struct{}),
+
+ config: config,
+ }
+ t.resetReadThresholds()
+ t.resetWriteThresholds()
+
+ // We always start with a mandatory key exchange.
+ t.requestKex <- struct{}{}
+ return t
+}
+
+func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ClientConfig, dialAddr string, addr net.Addr) *handshakeTransport {
+ t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)
+ t.dialAddress = dialAddr
+ t.remoteAddr = addr
+ t.hostKeyCallback = config.HostKeyCallback
+ t.bannerCallback = config.BannerCallback
+ if config.HostKeyAlgorithms != nil {
+ t.hostKeyAlgorithms = config.HostKeyAlgorithms
+ } else {
+ t.hostKeyAlgorithms = supportedHostKeyAlgos
+ }
+ go t.readLoop()
+ go t.kexLoop()
+ return t
+}
+
+func newServerTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ServerConfig) *handshakeTransport {
+ t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)
+ t.hostKeys = config.hostKeys
+ t.publicKeyAuthAlgorithms = config.PublicKeyAuthAlgorithms
+ go t.readLoop()
+ go t.kexLoop()
+ return t
+}
+
+func (t *handshakeTransport) getSessionID() []byte {
+ return t.sessionID
+}
+
+// waitSession waits for the session to be established. This should be
+// the first thing to call after instantiating handshakeTransport.
+func (t *handshakeTransport) waitSession() error {
+ p, err := t.readPacket()
+ if err != nil {
+ return err
+ }
+ if p[0] != msgNewKeys {
+ return fmt.Errorf("ssh: first packet should be msgNewKeys")
+ }
+
+ return nil
+}
+
+func (t *handshakeTransport) id() string {
+ if len(t.hostKeys) > 0 {
+ return "server"
+ }
+ return "client"
+}
+
+func (t *handshakeTransport) printPacket(p []byte, write bool) {
+ action := "got"
+ if write {
+ action = "sent"
+ }
+
+ if p[0] == msgChannelData || p[0] == msgChannelExtendedData {
+ log.Printf("%s %s data (packet %d bytes)", t.id(), action, len(p))
+ } else {
+ msg, err := decode(p)
+ log.Printf("%s %s %T %v (%v)", t.id(), action, msg, msg, err)
+ }
+}
+
+func (t *handshakeTransport) readPacket() ([]byte, error) {
+ p, ok := <-t.incoming
+ if !ok {
+ return nil, t.readError
+ }
+ return p, nil
+}
+
+func (t *handshakeTransport) readLoop() {
+ first := true
+ for {
+ p, err := t.readOnePacket(first)
+ first = false
+ if err != nil {
+ t.readError = err
+ close(t.incoming)
+ break
+ }
+ // If this is the first kex, and strict KEX mode is enabled,
+ // we don't ignore any messages, as they may be used to manipulate
+ // the packet sequence numbers.
+ if !(t.sessionID == nil && t.strictMode) && (p[0] == msgIgnore || p[0] == msgDebug) {
+ continue
+ }
+ t.incoming <- p
+ }
+
+ // Stop writers too.
+ t.recordWriteError(t.readError)
+
+ // Unblock the writer should it wait for this.
+ close(t.startKex)
+
+ // Don't close t.requestKex; it's also written to from writePacket.
+}
+
+func (t *handshakeTransport) pushPacket(p []byte) error {
+ if debugHandshake {
+ t.printPacket(p, true)
+ }
+ return t.conn.writePacket(p)
+}
+
+func (t *handshakeTransport) getWriteError() error {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ return t.writeError
+}
+
+func (t *handshakeTransport) recordWriteError(err error) {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ if t.writeError == nil && err != nil {
+ t.writeError = err
+ }
+}
+
+func (t *handshakeTransport) requestKeyExchange() {
+ select {
+ case t.requestKex <- struct{}{}:
+ default:
+ // something already requested a kex, so do nothing.
+ }
+}
+
+func (t *handshakeTransport) resetWriteThresholds() {
+ t.writePacketsLeft = packetRekeyThreshold
+ if t.config.RekeyThreshold > 0 {
+ t.writeBytesLeft = int64(t.config.RekeyThreshold)
+ } else if t.algorithms != nil {
+ t.writeBytesLeft = t.algorithms.w.rekeyBytes()
+ } else {
+ t.writeBytesLeft = 1 << 30
+ }
+}
+
+func (t *handshakeTransport) kexLoop() {
+
+write:
+ for t.getWriteError() == nil {
+ var request *pendingKex
+ var sent bool
+
+ for request == nil || !sent {
+ var ok bool
+ select {
+ case request, ok = <-t.startKex:
+ if !ok {
+ break write
+ }
+ case <-t.requestKex:
+ break
+ }
+
+ if !sent {
+ if err := t.sendKexInit(); err != nil {
+ t.recordWriteError(err)
+ break
+ }
+ sent = true
+ }
+ }
+
+ if err := t.getWriteError(); err != nil {
+ if request != nil {
+ request.done <- err
+ }
+ break
+ }
+
+ // We're not servicing t.requestKex, but that is OK:
+ // we never block on sending to t.requestKex.
+
+ // We're not servicing t.startKex, but the remote end
+ // has just sent us a kexInitMsg, so it can't send
+ // another key change request, until we close the done
+ // channel on the pendingKex request.
+
+ err := t.enterKeyExchange(request.otherInit)
+
+ t.mu.Lock()
+ t.writeError = err
+ t.sentInitPacket = nil
+ t.sentInitMsg = nil
+
+ t.resetWriteThresholds()
+
+ // we have completed the key exchange. Since the
+ // reader is still blocked, it is safe to clear out
+ // the requestKex channel. This avoids the situation
+ // where: 1) we consumed our own request for the
+ // initial kex, and 2) the kex from the remote side
+ // caused another send on the requestKex channel,
+ clear:
+ for {
+ select {
+ case <-t.requestKex:
+ //
+ default:
+ break clear
+ }
+ }
+
+ request.done <- t.writeError
+
+ // kex finished. Push packets that we received while
+ // the kex was in progress. Don't look at t.startKex
+ // and don't increment writtenSinceKex: if we trigger
+ // another kex while we are still busy with the last
+ // one, things will become very confusing.
+ for _, p := range t.pendingPackets {
+ t.writeError = t.pushPacket(p)
+ if t.writeError != nil {
+ break
+ }
+ }
+ t.pendingPackets = t.pendingPackets[:0]
+ t.mu.Unlock()
+ }
+
+ // Unblock reader.
+ t.conn.Close()
+
+ // drain startKex channel. We don't service t.requestKex
+ // because nobody does blocking sends there.
+ for request := range t.startKex {
+ request.done <- t.getWriteError()
+ }
+
+ // Mark that the loop is done so that Close can return.
+ close(t.kexLoopDone)
+}
+
+// The protocol uses uint32 for packet counters, so we can't let them
+// reach 1<<32. We will actually read and write more packets than
+// this, though: the other side may send more packets, and after we
+// hit this limit on writing we will send a few more packets for the
+// key exchange itself.
+const packetRekeyThreshold = (1 << 31)
+
+func (t *handshakeTransport) resetReadThresholds() {
+ t.readPacketsLeft = packetRekeyThreshold
+ if t.config.RekeyThreshold > 0 {
+ t.readBytesLeft = int64(t.config.RekeyThreshold)
+ } else if t.algorithms != nil {
+ t.readBytesLeft = t.algorithms.r.rekeyBytes()
+ } else {
+ t.readBytesLeft = 1 << 30
+ }
+}
+
+func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) {
+ p, err := t.conn.readPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ if t.readPacketsLeft > 0 {
+ t.readPacketsLeft--
+ } else {
+ t.requestKeyExchange()
+ }
+
+ if t.readBytesLeft > 0 {
+ t.readBytesLeft -= int64(len(p))
+ } else {
+ t.requestKeyExchange()
+ }
+
+ if debugHandshake {
+ t.printPacket(p, false)
+ }
+
+ if first && p[0] != msgKexInit {
+ return nil, fmt.Errorf("ssh: first packet should be msgKexInit")
+ }
+
+ if p[0] != msgKexInit {
+ return p, nil
+ }
+
+ firstKex := t.sessionID == nil
+
+ kex := pendingKex{
+ done: make(chan error, 1),
+ otherInit: p,
+ }
+ t.startKex <- &kex
+ err = <-kex.done
+
+ if debugHandshake {
+ log.Printf("%s exited key exchange (first %v), err %v", t.id(), firstKex, err)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ t.resetReadThresholds()
+
+ // By default, a key exchange is hidden from higher layers by
+ // translating it into msgIgnore.
+ successPacket := []byte{msgIgnore}
+ if firstKex {
+ // sendKexInit() for the first kex waits for
+ // msgNewKeys so the authentication process is
+ // guaranteed to happen over an encrypted transport.
+ successPacket = []byte{msgNewKeys}
+ }
+
+ return successPacket, nil
+}
+
+const (
+ kexStrictClient = "kex-strict-c-v00@openssh.com"
+ kexStrictServer = "kex-strict-s-v00@openssh.com"
+)
+
+// sendKexInit sends a key change message.
+func (t *handshakeTransport) sendKexInit() error {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ if t.sentInitMsg != nil {
+ // kexInits may be sent either in response to the other side,
+ // or because our side wants to initiate a key change, so we
+ // may have already sent a kexInit. In that case, don't send a
+ // second kexInit.
+ return nil
+ }
+
+ msg := &kexInitMsg{
+ CiphersClientServer: t.config.Ciphers,
+ CiphersServerClient: t.config.Ciphers,
+ MACsClientServer: t.config.MACs,
+ MACsServerClient: t.config.MACs,
+ CompressionClientServer: supportedCompressions,
+ CompressionServerClient: supportedCompressions,
+ }
+ io.ReadFull(rand.Reader, msg.Cookie[:])
+
+ // We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm,
+ // and possibly to add the ext-info extension algorithm. Since the slice may be the
+ // user owned KeyExchanges, we create our own slice in order to avoid using user
+ // owned memory by mistake.
+ msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+2) // room for kex-strict and ext-info
+ msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
+
+ isServer := len(t.hostKeys) > 0
+ if isServer {
+ for _, k := range t.hostKeys {
+ // If k is a MultiAlgorithmSigner, we restrict the signature
+ // algorithms. If k is a AlgorithmSigner, presume it supports all
+ // signature algorithms associated with the key format. If k is not
+ // an AlgorithmSigner, we can only assume it only supports the
+ // algorithms that matches the key format. (This means that Sign
+ // can't pick a different default).
+ keyFormat := k.PublicKey().Type()
+
+ switch s := k.(type) {
+ case MultiAlgorithmSigner:
+ for _, algo := range algorithmsForKeyFormat(keyFormat) {
+ if contains(s.Algorithms(), underlyingAlgo(algo)) {
+ msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo)
+ }
+ }
+ case AlgorithmSigner:
+ msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algorithmsForKeyFormat(keyFormat)...)
+ default:
+ msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)
+ }
+ }
+
+ if t.sessionID == nil {
+ msg.KexAlgos = append(msg.KexAlgos, kexStrictServer)
+ }
+ } else {
+ msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
+
+ // As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what
+ // algorithms the server supports for public key authentication. See RFC
+ // 8308, Section 2.1.
+ //
+ // We also send the strict KEX mode extension algorithm, in order to opt
+ // into the strict KEX mode.
+ if firstKeyExchange := t.sessionID == nil; firstKeyExchange {
+ msg.KexAlgos = append(msg.KexAlgos, "ext-info-c")
+ msg.KexAlgos = append(msg.KexAlgos, kexStrictClient)
+ }
+
+ }
+
+ packet := Marshal(msg)
+
+ // writePacket destroys the contents, so save a copy.
+ packetCopy := make([]byte, len(packet))
+ copy(packetCopy, packet)
+
+ if err := t.pushPacket(packetCopy); err != nil {
+ return err
+ }
+
+ t.sentInitMsg = msg
+ t.sentInitPacket = packet
+
+ return nil
+}
+
+func (t *handshakeTransport) writePacket(p []byte) error {
+ switch p[0] {
+ case msgKexInit:
+ return errors.New("ssh: only handshakeTransport can send kexInit")
+ case msgNewKeys:
+ return errors.New("ssh: only handshakeTransport can send newKeys")
+ }
+
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ if t.writeError != nil {
+ return t.writeError
+ }
+
+ if t.sentInitMsg != nil {
+ // Copy the packet so the writer can reuse the buffer.
+ cp := make([]byte, len(p))
+ copy(cp, p)
+ t.pendingPackets = append(t.pendingPackets, cp)
+ return nil
+ }
+
+ if t.writeBytesLeft > 0 {
+ t.writeBytesLeft -= int64(len(p))
+ } else {
+ t.requestKeyExchange()
+ }
+
+ if t.writePacketsLeft > 0 {
+ t.writePacketsLeft--
+ } else {
+ t.requestKeyExchange()
+ }
+
+ if err := t.pushPacket(p); err != nil {
+ t.writeError = err
+ }
+
+ return nil
+}
+
+func (t *handshakeTransport) Close() error {
+ // Close the connection. This should cause the readLoop goroutine to wake up
+ // and close t.startKex, which will shut down kexLoop if running.
+ err := t.conn.Close()
+
+ // Wait for the kexLoop goroutine to complete.
+ // At that point we know that the readLoop goroutine is complete too,
+ // because kexLoop itself waits for readLoop to close the startKex channel.
+ <-t.kexLoopDone
+
+ return err
+}
+
+func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
+ if debugHandshake {
+ log.Printf("%s entered key exchange", t.id())
+ }
+
+ otherInit := &kexInitMsg{}
+ if err := Unmarshal(otherInitPacket, otherInit); err != nil {
+ return err
+ }
+
+ magics := handshakeMagics{
+ clientVersion: t.clientVersion,
+ serverVersion: t.serverVersion,
+ clientKexInit: otherInitPacket,
+ serverKexInit: t.sentInitPacket,
+ }
+
+ clientInit := otherInit
+ serverInit := t.sentInitMsg
+ isClient := len(t.hostKeys) == 0
+ if isClient {
+ clientInit, serverInit = serverInit, clientInit
+
+ magics.clientKexInit = t.sentInitPacket
+ magics.serverKexInit = otherInitPacket
+ }
+
+ var err error
+ t.algorithms, err = findAgreedAlgorithms(isClient, clientInit, serverInit)
+ if err != nil {
+ return err
+ }
+
+ if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) {
+ t.strictMode = true
+ if err := t.conn.setStrictMode(); err != nil {
+ return err
+ }
+ }
+
+ // We don't send FirstKexFollows, but we handle receiving it.
+ //
+ // RFC 4253 section 7 defines the kex and the agreement method for
+ // first_kex_packet_follows. It states that the guessed packet
+ // should be ignored if the "kex algorithm and/or the host
+ // key algorithm is guessed wrong (server and client have
+ // different preferred algorithm), or if any of the other
+ // algorithms cannot be agreed upon". The other algorithms have
+ // already been checked above so the kex algorithm and host key
+ // algorithm are checked here.
+ if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) {
+ // other side sent a kex message for the wrong algorithm,
+ // which we have to ignore.
+ if _, err := t.conn.readPacket(); err != nil {
+ return err
+ }
+ }
+
+ kex, ok := kexAlgoMap[t.algorithms.kex]
+ if !ok {
+ return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.kex)
+ }
+
+ var result *kexResult
+ if len(t.hostKeys) > 0 {
+ result, err = t.server(kex, &magics)
+ } else {
+ result, err = t.client(kex, &magics)
+ }
+
+ if err != nil {
+ return err
+ }
+
+ firstKeyExchange := t.sessionID == nil
+ if firstKeyExchange {
+ t.sessionID = result.H
+ }
+ result.SessionID = t.sessionID
+
+ if err := t.conn.prepareKeyChange(t.algorithms, result); err != nil {
+ return err
+ }
+ if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil {
+ return err
+ }
+
+ // On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO
+ // message with the server-sig-algs extension if the client supports it. See
+ // RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9.
+ if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
+ supportedPubKeyAuthAlgosList := strings.Join(t.publicKeyAuthAlgorithms, ",")
+ extInfo := &extInfoMsg{
+ NumExtensions: 2,
+ Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)+4+16+4+1),
+ }
+ extInfo.Payload = appendInt(extInfo.Payload, len("server-sig-algs"))
+ extInfo.Payload = append(extInfo.Payload, "server-sig-algs"...)
+ extInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList))
+ extInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...)
+ extInfo.Payload = appendInt(extInfo.Payload, len("ping@openssh.com"))
+ extInfo.Payload = append(extInfo.Payload, "ping@openssh.com"...)
+ extInfo.Payload = appendInt(extInfo.Payload, 1)
+ extInfo.Payload = append(extInfo.Payload, "0"...)
+ if err := t.conn.writePacket(Marshal(extInfo)); err != nil {
+ return err
+ }
+ }
+
+ if packet, err := t.conn.readPacket(); err != nil {
+ return err
+ } else if packet[0] != msgNewKeys {
+ return unexpectedMessageError(msgNewKeys, packet[0])
+ }
+
+ if firstKeyExchange {
+ // Indicates to the transport that the first key exchange is completed
+ // after receiving SSH_MSG_NEWKEYS.
+ t.conn.setInitialKEXDone()
+ }
+
+ return nil
+}
+
+// algorithmSignerWrapper is an AlgorithmSigner that only supports the default
+// key format algorithm.
+//
+// This is technically a violation of the AlgorithmSigner interface, but it
+// should be unreachable given where we use this. Anyway, at least it returns an
+// error instead of panicing or producing an incorrect signature.
+type algorithmSignerWrapper struct {
+ Signer
+}
+
+func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
+ if algorithm != underlyingAlgo(a.PublicKey().Type()) {
+ return nil, errors.New("ssh: internal error: algorithmSignerWrapper invoked with non-default algorithm")
+ }
+ return a.Sign(rand, data)
+}
+
+func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner {
+ for _, k := range hostKeys {
+ if s, ok := k.(MultiAlgorithmSigner); ok {
+ if !contains(s.Algorithms(), underlyingAlgo(algo)) {
+ continue
+ }
+ }
+
+ if algo == k.PublicKey().Type() {
+ return algorithmSignerWrapper{k}
+ }
+
+ k, ok := k.(AlgorithmSigner)
+ if !ok {
+ continue
+ }
+ for _, a := range algorithmsForKeyFormat(k.PublicKey().Type()) {
+ if algo == a {
+ return k
+ }
+ }
+ }
+ return nil
+}
+
+func (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {
+ hostKey := pickHostKey(t.hostKeys, t.algorithms.hostKey)
+ if hostKey == nil {
+ return nil, errors.New("ssh: internal error: negotiated unsupported signature type")
+ }
+
+ r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.hostKey)
+ return r, err
+}
+
+func (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {
+ result, err := kex.Client(t.conn, t.config.Rand, magics)
+ if err != nil {
+ return nil, err
+ }
+
+ hostKey, err := ParsePublicKey(result.HostKey)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := verifyHostKeySignature(hostKey, t.algorithms.hostKey, result); err != nil {
+ return nil, err
+ }
+
+ err = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey)
+ if err != nil {
+ return nil, err
+ }
+
+ return result, nil
+}
diff --git a/vendor/golang.org/x/crypto/ssh/internal/bcrypt_pbkdf/bcrypt_pbkdf.go b/vendor/golang.org/x/crypto/ssh/internal/bcrypt_pbkdf/bcrypt_pbkdf.go
new file mode 100644
index 00000000..af81d266
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/internal/bcrypt_pbkdf/bcrypt_pbkdf.go
@@ -0,0 +1,93 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package bcrypt_pbkdf implements bcrypt_pbkdf(3) from OpenBSD.
+//
+// See https://flak.tedunangst.com/post/bcrypt-pbkdf and
+// https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libutil/bcrypt_pbkdf.c.
+package bcrypt_pbkdf
+
+import (
+ "crypto/sha512"
+ "errors"
+ "golang.org/x/crypto/blowfish"
+)
+
+const blockSize = 32
+
+// Key derives a key from the password, salt and rounds count, returning a
+// []byte of length keyLen that can be used as cryptographic key.
+func Key(password, salt []byte, rounds, keyLen int) ([]byte, error) {
+ if rounds < 1 {
+ return nil, errors.New("bcrypt_pbkdf: number of rounds is too small")
+ }
+ if len(password) == 0 {
+ return nil, errors.New("bcrypt_pbkdf: empty password")
+ }
+ if len(salt) == 0 || len(salt) > 1<<20 {
+ return nil, errors.New("bcrypt_pbkdf: bad salt length")
+ }
+ if keyLen > 1024 {
+ return nil, errors.New("bcrypt_pbkdf: keyLen is too large")
+ }
+
+ numBlocks := (keyLen + blockSize - 1) / blockSize
+ key := make([]byte, numBlocks*blockSize)
+
+ h := sha512.New()
+ h.Write(password)
+ shapass := h.Sum(nil)
+
+ shasalt := make([]byte, 0, sha512.Size)
+ cnt, tmp := make([]byte, 4), make([]byte, blockSize)
+ for block := 1; block <= numBlocks; block++ {
+ h.Reset()
+ h.Write(salt)
+ cnt[0] = byte(block >> 24)
+ cnt[1] = byte(block >> 16)
+ cnt[2] = byte(block >> 8)
+ cnt[3] = byte(block)
+ h.Write(cnt)
+ bcryptHash(tmp, shapass, h.Sum(shasalt))
+
+ out := make([]byte, blockSize)
+ copy(out, tmp)
+ for i := 2; i <= rounds; i++ {
+ h.Reset()
+ h.Write(tmp)
+ bcryptHash(tmp, shapass, h.Sum(shasalt))
+ for j := 0; j < len(out); j++ {
+ out[j] ^= tmp[j]
+ }
+ }
+
+ for i, v := range out {
+ key[i*numBlocks+(block-1)] = v
+ }
+ }
+ return key[:keyLen], nil
+}
+
+var magic = []byte("OxychromaticBlowfishSwatDynamite")
+
+func bcryptHash(out, shapass, shasalt []byte) {
+ c, err := blowfish.NewSaltedCipher(shapass, shasalt)
+ if err != nil {
+ panic(err)
+ }
+ for i := 0; i < 64; i++ {
+ blowfish.ExpandKey(shasalt, c)
+ blowfish.ExpandKey(shapass, c)
+ }
+ copy(out, magic)
+ for i := 0; i < 32; i += 8 {
+ for j := 0; j < 64; j++ {
+ c.Encrypt(out[i:i+8], out[i:i+8])
+ }
+ }
+ // Swap bytes due to different endianness.
+ for i := 0; i < 32; i += 4 {
+ out[i+3], out[i+2], out[i+1], out[i] = out[i], out[i+1], out[i+2], out[i+3]
+ }
+}
diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go
new file mode 100644
index 00000000..8a05f799
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/kex.go
@@ -0,0 +1,786 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/subtle"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "math/big"
+
+ "golang.org/x/crypto/curve25519"
+)
+
+const (
+ kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1"
+ kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1"
+ kexAlgoDH14SHA256 = "diffie-hellman-group14-sha256"
+ kexAlgoDH16SHA512 = "diffie-hellman-group16-sha512"
+ kexAlgoECDH256 = "ecdh-sha2-nistp256"
+ kexAlgoECDH384 = "ecdh-sha2-nistp384"
+ kexAlgoECDH521 = "ecdh-sha2-nistp521"
+ kexAlgoCurve25519SHA256LibSSH = "curve25519-sha256@libssh.org"
+ kexAlgoCurve25519SHA256 = "curve25519-sha256"
+
+ // For the following kex only the client half contains a production
+ // ready implementation. The server half only consists of a minimal
+ // implementation to satisfy the automated tests.
+ kexAlgoDHGEXSHA1 = "diffie-hellman-group-exchange-sha1"
+ kexAlgoDHGEXSHA256 = "diffie-hellman-group-exchange-sha256"
+)
+
+// kexResult captures the outcome of a key exchange.
+type kexResult struct {
+ // Session hash. See also RFC 4253, section 8.
+ H []byte
+
+ // Shared secret. See also RFC 4253, section 8.
+ K []byte
+
+ // Host key as hashed into H.
+ HostKey []byte
+
+ // Signature of H.
+ Signature []byte
+
+ // A cryptographic hash function that matches the security
+ // level of the key exchange algorithm. It is used for
+ // calculating H, and for deriving keys from H and K.
+ Hash crypto.Hash
+
+ // The session ID, which is the first H computed. This is used
+ // to derive key material inside the transport.
+ SessionID []byte
+}
+
+// handshakeMagics contains data that is always included in the
+// session hash.
+type handshakeMagics struct {
+ clientVersion, serverVersion []byte
+ clientKexInit, serverKexInit []byte
+}
+
+func (m *handshakeMagics) write(w io.Writer) {
+ writeString(w, m.clientVersion)
+ writeString(w, m.serverVersion)
+ writeString(w, m.clientKexInit)
+ writeString(w, m.serverKexInit)
+}
+
+// kexAlgorithm abstracts different key exchange algorithms.
+type kexAlgorithm interface {
+ // Server runs server-side key agreement, signing the result
+ // with a hostkey. algo is the negotiated algorithm, and may
+ // be a certificate type.
+ Server(p packetConn, rand io.Reader, magics *handshakeMagics, s AlgorithmSigner, algo string) (*kexResult, error)
+
+ // Client runs the client-side key agreement. Caller is
+ // responsible for verifying the host key signature.
+ Client(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error)
+}
+
+// dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement.
+type dhGroup struct {
+ g, p, pMinus1 *big.Int
+ hashFunc crypto.Hash
+}
+
+func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
+ if theirPublic.Cmp(bigOne) <= 0 || theirPublic.Cmp(group.pMinus1) >= 0 {
+ return nil, errors.New("ssh: DH parameter out of bounds")
+ }
+ return new(big.Int).Exp(theirPublic, myPrivate, group.p), nil
+}
+
+func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
+ var x *big.Int
+ for {
+ var err error
+ if x, err = rand.Int(randSource, group.pMinus1); err != nil {
+ return nil, err
+ }
+ if x.Sign() > 0 {
+ break
+ }
+ }
+
+ X := new(big.Int).Exp(group.g, x, group.p)
+ kexDHInit := kexDHInitMsg{
+ X: X,
+ }
+ if err := c.writePacket(Marshal(&kexDHInit)); err != nil {
+ return nil, err
+ }
+
+ packet, err := c.readPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ var kexDHReply kexDHReplyMsg
+ if err = Unmarshal(packet, &kexDHReply); err != nil {
+ return nil, err
+ }
+
+ ki, err := group.diffieHellman(kexDHReply.Y, x)
+ if err != nil {
+ return nil, err
+ }
+
+ h := group.hashFunc.New()
+ magics.write(h)
+ writeString(h, kexDHReply.HostKey)
+ writeInt(h, X)
+ writeInt(h, kexDHReply.Y)
+ K := make([]byte, intLength(ki))
+ marshalInt(K, ki)
+ h.Write(K)
+
+ return &kexResult{
+ H: h.Sum(nil),
+ K: K,
+ HostKey: kexDHReply.HostKey,
+ Signature: kexDHReply.Signature,
+ Hash: group.hashFunc,
+ }, nil
+}
+
+func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
+ packet, err := c.readPacket()
+ if err != nil {
+ return
+ }
+ var kexDHInit kexDHInitMsg
+ if err = Unmarshal(packet, &kexDHInit); err != nil {
+ return
+ }
+
+ var y *big.Int
+ for {
+ if y, err = rand.Int(randSource, group.pMinus1); err != nil {
+ return
+ }
+ if y.Sign() > 0 {
+ break
+ }
+ }
+
+ Y := new(big.Int).Exp(group.g, y, group.p)
+ ki, err := group.diffieHellman(kexDHInit.X, y)
+ if err != nil {
+ return nil, err
+ }
+
+ hostKeyBytes := priv.PublicKey().Marshal()
+
+ h := group.hashFunc.New()
+ magics.write(h)
+ writeString(h, hostKeyBytes)
+ writeInt(h, kexDHInit.X)
+ writeInt(h, Y)
+
+ K := make([]byte, intLength(ki))
+ marshalInt(K, ki)
+ h.Write(K)
+
+ H := h.Sum(nil)
+
+ // H is already a hash, but the hostkey signing will apply its
+ // own key-specific hash algorithm.
+ sig, err := signAndMarshal(priv, randSource, H, algo)
+ if err != nil {
+ return nil, err
+ }
+
+ kexDHReply := kexDHReplyMsg{
+ HostKey: hostKeyBytes,
+ Y: Y,
+ Signature: sig,
+ }
+ packet = Marshal(&kexDHReply)
+
+ err = c.writePacket(packet)
+ return &kexResult{
+ H: H,
+ K: K,
+ HostKey: hostKeyBytes,
+ Signature: sig,
+ Hash: group.hashFunc,
+ }, err
+}
+
+// ecdh performs Elliptic Curve Diffie-Hellman key exchange as
+// described in RFC 5656, section 4.
+type ecdh struct {
+ curve elliptic.Curve
+}
+
+func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
+ ephKey, err := ecdsa.GenerateKey(kex.curve, rand)
+ if err != nil {
+ return nil, err
+ }
+
+ kexInit := kexECDHInitMsg{
+ ClientPubKey: elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y),
+ }
+
+ serialized := Marshal(&kexInit)
+ if err := c.writePacket(serialized); err != nil {
+ return nil, err
+ }
+
+ packet, err := c.readPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ var reply kexECDHReplyMsg
+ if err = Unmarshal(packet, &reply); err != nil {
+ return nil, err
+ }
+
+ x, y, err := unmarshalECKey(kex.curve, reply.EphemeralPubKey)
+ if err != nil {
+ return nil, err
+ }
+
+ // generate shared secret
+ secret, _ := kex.curve.ScalarMult(x, y, ephKey.D.Bytes())
+
+ h := ecHash(kex.curve).New()
+ magics.write(h)
+ writeString(h, reply.HostKey)
+ writeString(h, kexInit.ClientPubKey)
+ writeString(h, reply.EphemeralPubKey)
+ K := make([]byte, intLength(secret))
+ marshalInt(K, secret)
+ h.Write(K)
+
+ return &kexResult{
+ H: h.Sum(nil),
+ K: K,
+ HostKey: reply.HostKey,
+ Signature: reply.Signature,
+ Hash: ecHash(kex.curve),
+ }, nil
+}
+
+// unmarshalECKey parses and checks an EC key.
+func unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) {
+ x, y = elliptic.Unmarshal(curve, pubkey)
+ if x == nil {
+ return nil, nil, errors.New("ssh: elliptic.Unmarshal failure")
+ }
+ if !validateECPublicKey(curve, x, y) {
+ return nil, nil, errors.New("ssh: public key not on curve")
+ }
+ return x, y, nil
+}
+
+// validateECPublicKey checks that the point is a valid public key for
+// the given curve. See [SEC1], 3.2.2
+func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool {
+ if x.Sign() == 0 && y.Sign() == 0 {
+ return false
+ }
+
+ if x.Cmp(curve.Params().P) >= 0 {
+ return false
+ }
+
+ if y.Cmp(curve.Params().P) >= 0 {
+ return false
+ }
+
+ if !curve.IsOnCurve(x, y) {
+ return false
+ }
+
+ // We don't check if N * PubKey == 0, since
+ //
+ // - the NIST curves have cofactor = 1, so this is implicit.
+ // (We don't foresee an implementation that supports non NIST
+ // curves)
+ //
+ // - for ephemeral keys, we don't need to worry about small
+ // subgroup attacks.
+ return true
+}
+
+func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
+ packet, err := c.readPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ var kexECDHInit kexECDHInitMsg
+ if err = Unmarshal(packet, &kexECDHInit); err != nil {
+ return nil, err
+ }
+
+ clientX, clientY, err := unmarshalECKey(kex.curve, kexECDHInit.ClientPubKey)
+ if err != nil {
+ return nil, err
+ }
+
+ // We could cache this key across multiple users/multiple
+ // connection attempts, but the benefit is small. OpenSSH
+ // generates a new key for each incoming connection.
+ ephKey, err := ecdsa.GenerateKey(kex.curve, rand)
+ if err != nil {
+ return nil, err
+ }
+
+ hostKeyBytes := priv.PublicKey().Marshal()
+
+ serializedEphKey := elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y)
+
+ // generate shared secret
+ secret, _ := kex.curve.ScalarMult(clientX, clientY, ephKey.D.Bytes())
+
+ h := ecHash(kex.curve).New()
+ magics.write(h)
+ writeString(h, hostKeyBytes)
+ writeString(h, kexECDHInit.ClientPubKey)
+ writeString(h, serializedEphKey)
+
+ K := make([]byte, intLength(secret))
+ marshalInt(K, secret)
+ h.Write(K)
+
+ H := h.Sum(nil)
+
+ // H is already a hash, but the hostkey signing will apply its
+ // own key-specific hash algorithm.
+ sig, err := signAndMarshal(priv, rand, H, algo)
+ if err != nil {
+ return nil, err
+ }
+
+ reply := kexECDHReplyMsg{
+ EphemeralPubKey: serializedEphKey,
+ HostKey: hostKeyBytes,
+ Signature: sig,
+ }
+
+ serialized := Marshal(&reply)
+ if err := c.writePacket(serialized); err != nil {
+ return nil, err
+ }
+
+ return &kexResult{
+ H: H,
+ K: K,
+ HostKey: reply.HostKey,
+ Signature: sig,
+ Hash: ecHash(kex.curve),
+ }, nil
+}
+
+// ecHash returns the hash to match the given elliptic curve, see RFC
+// 5656, section 6.2.1
+func ecHash(curve elliptic.Curve) crypto.Hash {
+ bitSize := curve.Params().BitSize
+ switch {
+ case bitSize <= 256:
+ return crypto.SHA256
+ case bitSize <= 384:
+ return crypto.SHA384
+ }
+ return crypto.SHA512
+}
+
+var kexAlgoMap = map[string]kexAlgorithm{}
+
+func init() {
+ // This is the group called diffie-hellman-group1-sha1 in
+ // RFC 4253 and Oakley Group 2 in RFC 2409.
+ p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16)
+ kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{
+ g: new(big.Int).SetInt64(2),
+ p: p,
+ pMinus1: new(big.Int).Sub(p, bigOne),
+ hashFunc: crypto.SHA1,
+ }
+
+ // This are the groups called diffie-hellman-group14-sha1 and
+ // diffie-hellman-group14-sha256 in RFC 4253 and RFC 8268,
+ // and Oakley Group 14 in RFC 3526.
+ p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
+ group14 := &dhGroup{
+ g: new(big.Int).SetInt64(2),
+ p: p,
+ pMinus1: new(big.Int).Sub(p, bigOne),
+ }
+
+ kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{
+ g: group14.g, p: group14.p, pMinus1: group14.pMinus1,
+ hashFunc: crypto.SHA1,
+ }
+ kexAlgoMap[kexAlgoDH14SHA256] = &dhGroup{
+ g: group14.g, p: group14.p, pMinus1: group14.pMinus1,
+ hashFunc: crypto.SHA256,
+ }
+
+ // This is the group called diffie-hellman-group16-sha512 in RFC
+ // 8268 and Oakley Group 16 in RFC 3526.
+ p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", 16)
+
+ kexAlgoMap[kexAlgoDH16SHA512] = &dhGroup{
+ g: new(big.Int).SetInt64(2),
+ p: p,
+ pMinus1: new(big.Int).Sub(p, bigOne),
+ hashFunc: crypto.SHA512,
+ }
+
+ kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}
+ kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
+ kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
+ kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
+ kexAlgoMap[kexAlgoCurve25519SHA256LibSSH] = &curve25519sha256{}
+ kexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
+ kexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
+}
+
+// curve25519sha256 implements the curve25519-sha256 (formerly known as
+// curve25519-sha256@libssh.org) key exchange method, as described in RFC 8731.
+type curve25519sha256 struct{}
+
+type curve25519KeyPair struct {
+ priv [32]byte
+ pub [32]byte
+}
+
+func (kp *curve25519KeyPair) generate(rand io.Reader) error {
+ if _, err := io.ReadFull(rand, kp.priv[:]); err != nil {
+ return err
+ }
+ curve25519.ScalarBaseMult(&kp.pub, &kp.priv)
+ return nil
+}
+
+// curve25519Zeros is just an array of 32 zero bytes so that we have something
+// convenient to compare against in order to reject curve25519 points with the
+// wrong order.
+var curve25519Zeros [32]byte
+
+func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
+ var kp curve25519KeyPair
+ if err := kp.generate(rand); err != nil {
+ return nil, err
+ }
+ if err := c.writePacket(Marshal(&kexECDHInitMsg{kp.pub[:]})); err != nil {
+ return nil, err
+ }
+
+ packet, err := c.readPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ var reply kexECDHReplyMsg
+ if err = Unmarshal(packet, &reply); err != nil {
+ return nil, err
+ }
+ if len(reply.EphemeralPubKey) != 32 {
+ return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
+ }
+
+ var servPub, secret [32]byte
+ copy(servPub[:], reply.EphemeralPubKey)
+ curve25519.ScalarMult(&secret, &kp.priv, &servPub)
+ if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
+ return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
+ }
+
+ h := crypto.SHA256.New()
+ magics.write(h)
+ writeString(h, reply.HostKey)
+ writeString(h, kp.pub[:])
+ writeString(h, reply.EphemeralPubKey)
+
+ ki := new(big.Int).SetBytes(secret[:])
+ K := make([]byte, intLength(ki))
+ marshalInt(K, ki)
+ h.Write(K)
+
+ return &kexResult{
+ H: h.Sum(nil),
+ K: K,
+ HostKey: reply.HostKey,
+ Signature: reply.Signature,
+ Hash: crypto.SHA256,
+ }, nil
+}
+
+func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
+ packet, err := c.readPacket()
+ if err != nil {
+ return
+ }
+ var kexInit kexECDHInitMsg
+ if err = Unmarshal(packet, &kexInit); err != nil {
+ return
+ }
+
+ if len(kexInit.ClientPubKey) != 32 {
+ return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
+ }
+
+ var kp curve25519KeyPair
+ if err := kp.generate(rand); err != nil {
+ return nil, err
+ }
+
+ var clientPub, secret [32]byte
+ copy(clientPub[:], kexInit.ClientPubKey)
+ curve25519.ScalarMult(&secret, &kp.priv, &clientPub)
+ if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
+ return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
+ }
+
+ hostKeyBytes := priv.PublicKey().Marshal()
+
+ h := crypto.SHA256.New()
+ magics.write(h)
+ writeString(h, hostKeyBytes)
+ writeString(h, kexInit.ClientPubKey)
+ writeString(h, kp.pub[:])
+
+ ki := new(big.Int).SetBytes(secret[:])
+ K := make([]byte, intLength(ki))
+ marshalInt(K, ki)
+ h.Write(K)
+
+ H := h.Sum(nil)
+
+ sig, err := signAndMarshal(priv, rand, H, algo)
+ if err != nil {
+ return nil, err
+ }
+
+ reply := kexECDHReplyMsg{
+ EphemeralPubKey: kp.pub[:],
+ HostKey: hostKeyBytes,
+ Signature: sig,
+ }
+ if err := c.writePacket(Marshal(&reply)); err != nil {
+ return nil, err
+ }
+ return &kexResult{
+ H: H,
+ K: K,
+ HostKey: hostKeyBytes,
+ Signature: sig,
+ Hash: crypto.SHA256,
+ }, nil
+}
+
+// dhGEXSHA implements the diffie-hellman-group-exchange-sha1 and
+// diffie-hellman-group-exchange-sha256 key agreement protocols,
+// as described in RFC 4419
+type dhGEXSHA struct {
+ hashFunc crypto.Hash
+}
+
+const (
+ dhGroupExchangeMinimumBits = 2048
+ dhGroupExchangePreferredBits = 2048
+ dhGroupExchangeMaximumBits = 8192
+)
+
+func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
+ // Send GexRequest
+ kexDHGexRequest := kexDHGexRequestMsg{
+ MinBits: dhGroupExchangeMinimumBits,
+ PreferedBits: dhGroupExchangePreferredBits,
+ MaxBits: dhGroupExchangeMaximumBits,
+ }
+ if err := c.writePacket(Marshal(&kexDHGexRequest)); err != nil {
+ return nil, err
+ }
+
+ // Receive GexGroup
+ packet, err := c.readPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ var msg kexDHGexGroupMsg
+ if err = Unmarshal(packet, &msg); err != nil {
+ return nil, err
+ }
+
+ // reject if p's bit length < dhGroupExchangeMinimumBits or > dhGroupExchangeMaximumBits
+ if msg.P.BitLen() < dhGroupExchangeMinimumBits || msg.P.BitLen() > dhGroupExchangeMaximumBits {
+ return nil, fmt.Errorf("ssh: server-generated gex p is out of range (%d bits)", msg.P.BitLen())
+ }
+
+ // Check if g is safe by verifying that 1 < g < p-1
+ pMinusOne := new(big.Int).Sub(msg.P, bigOne)
+ if msg.G.Cmp(bigOne) <= 0 || msg.G.Cmp(pMinusOne) >= 0 {
+ return nil, fmt.Errorf("ssh: server provided gex g is not safe")
+ }
+
+ // Send GexInit
+ pHalf := new(big.Int).Rsh(msg.P, 1)
+ x, err := rand.Int(randSource, pHalf)
+ if err != nil {
+ return nil, err
+ }
+ X := new(big.Int).Exp(msg.G, x, msg.P)
+ kexDHGexInit := kexDHGexInitMsg{
+ X: X,
+ }
+ if err := c.writePacket(Marshal(&kexDHGexInit)); err != nil {
+ return nil, err
+ }
+
+ // Receive GexReply
+ packet, err = c.readPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ var kexDHGexReply kexDHGexReplyMsg
+ if err = Unmarshal(packet, &kexDHGexReply); err != nil {
+ return nil, err
+ }
+
+ if kexDHGexReply.Y.Cmp(bigOne) <= 0 || kexDHGexReply.Y.Cmp(pMinusOne) >= 0 {
+ return nil, errors.New("ssh: DH parameter out of bounds")
+ }
+ kInt := new(big.Int).Exp(kexDHGexReply.Y, x, msg.P)
+
+ // Check if k is safe by verifying that k > 1 and k < p - 1
+ if kInt.Cmp(bigOne) <= 0 || kInt.Cmp(pMinusOne) >= 0 {
+ return nil, fmt.Errorf("ssh: derived k is not safe")
+ }
+
+ h := gex.hashFunc.New()
+ magics.write(h)
+ writeString(h, kexDHGexReply.HostKey)
+ binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
+ binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
+ binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
+ writeInt(h, msg.P)
+ writeInt(h, msg.G)
+ writeInt(h, X)
+ writeInt(h, kexDHGexReply.Y)
+ K := make([]byte, intLength(kInt))
+ marshalInt(K, kInt)
+ h.Write(K)
+
+ return &kexResult{
+ H: h.Sum(nil),
+ K: K,
+ HostKey: kexDHGexReply.HostKey,
+ Signature: kexDHGexReply.Signature,
+ Hash: gex.hashFunc,
+ }, nil
+}
+
+// Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256.
+//
+// This is a minimal implementation to satisfy the automated tests.
+func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
+ // Receive GexRequest
+ packet, err := c.readPacket()
+ if err != nil {
+ return
+ }
+ var kexDHGexRequest kexDHGexRequestMsg
+ if err = Unmarshal(packet, &kexDHGexRequest); err != nil {
+ return
+ }
+
+ // Send GexGroup
+ // This is the group called diffie-hellman-group14-sha1 in RFC
+ // 4253 and Oakley Group 14 in RFC 3526.
+ p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
+ g := big.NewInt(2)
+
+ msg := &kexDHGexGroupMsg{
+ P: p,
+ G: g,
+ }
+ if err := c.writePacket(Marshal(msg)); err != nil {
+ return nil, err
+ }
+
+ // Receive GexInit
+ packet, err = c.readPacket()
+ if err != nil {
+ return
+ }
+ var kexDHGexInit kexDHGexInitMsg
+ if err = Unmarshal(packet, &kexDHGexInit); err != nil {
+ return
+ }
+
+ pHalf := new(big.Int).Rsh(p, 1)
+
+ y, err := rand.Int(randSource, pHalf)
+ if err != nil {
+ return
+ }
+ Y := new(big.Int).Exp(g, y, p)
+
+ pMinusOne := new(big.Int).Sub(p, bigOne)
+ if kexDHGexInit.X.Cmp(bigOne) <= 0 || kexDHGexInit.X.Cmp(pMinusOne) >= 0 {
+ return nil, errors.New("ssh: DH parameter out of bounds")
+ }
+ kInt := new(big.Int).Exp(kexDHGexInit.X, y, p)
+
+ hostKeyBytes := priv.PublicKey().Marshal()
+
+ h := gex.hashFunc.New()
+ magics.write(h)
+ writeString(h, hostKeyBytes)
+ binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
+ binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
+ binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
+ writeInt(h, p)
+ writeInt(h, g)
+ writeInt(h, kexDHGexInit.X)
+ writeInt(h, Y)
+
+ K := make([]byte, intLength(kInt))
+ marshalInt(K, kInt)
+ h.Write(K)
+
+ H := h.Sum(nil)
+
+ // H is already a hash, but the hostkey signing will apply its
+ // own key-specific hash algorithm.
+ sig, err := signAndMarshal(priv, randSource, H, algo)
+ if err != nil {
+ return nil, err
+ }
+
+ kexDHGexReply := kexDHGexReplyMsg{
+ HostKey: hostKeyBytes,
+ Y: Y,
+ Signature: sig,
+ }
+ packet = Marshal(&kexDHGexReply)
+
+ err = c.writePacket(packet)
+
+ return &kexResult{
+ H: H,
+ K: K,
+ HostKey: hostKeyBytes,
+ Signature: sig,
+ Hash: gex.hashFunc,
+ }, err
+}
diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go
new file mode 100644
index 00000000..7967665f
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/keys.go
@@ -0,0 +1,1736 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/dsa"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/md5"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha256"
+ "crypto/x509"
+ "encoding/asn1"
+ "encoding/base64"
+ "encoding/binary"
+ "encoding/hex"
+ "encoding/pem"
+ "errors"
+ "fmt"
+ "io"
+ "math/big"
+ "strings"
+
+ "golang.org/x/crypto/ssh/internal/bcrypt_pbkdf"
+)
+
+// Public key algorithms names. These values can appear in PublicKey.Type,
+// ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner
+// arguments.
+const (
+ KeyAlgoRSA = "ssh-rsa"
+ KeyAlgoDSA = "ssh-dss"
+ KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
+ KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com"
+ KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
+ KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
+ KeyAlgoED25519 = "ssh-ed25519"
+ KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com"
+
+ // KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not
+ // public key formats, so they can't appear as a PublicKey.Type. The
+ // corresponding PublicKey.Type is KeyAlgoRSA. See RFC 8332, Section 2.
+ KeyAlgoRSASHA256 = "rsa-sha2-256"
+ KeyAlgoRSASHA512 = "rsa-sha2-512"
+)
+
+const (
+ // Deprecated: use KeyAlgoRSA.
+ SigAlgoRSA = KeyAlgoRSA
+ // Deprecated: use KeyAlgoRSASHA256.
+ SigAlgoRSASHA2256 = KeyAlgoRSASHA256
+ // Deprecated: use KeyAlgoRSASHA512.
+ SigAlgoRSASHA2512 = KeyAlgoRSASHA512
+)
+
+// parsePubKey parses a public key of the given algorithm.
+// Use ParsePublicKey for keys with prepended algorithm.
+func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) {
+ switch algo {
+ case KeyAlgoRSA:
+ return parseRSA(in)
+ case KeyAlgoDSA:
+ return parseDSA(in)
+ case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
+ return parseECDSA(in)
+ case KeyAlgoSKECDSA256:
+ return parseSKECDSA(in)
+ case KeyAlgoED25519:
+ return parseED25519(in)
+ case KeyAlgoSKED25519:
+ return parseSKEd25519(in)
+ case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
+ cert, err := parseCert(in, certKeyAlgoNames[algo])
+ if err != nil {
+ return nil, nil, err
+ }
+ return cert, nil, nil
+ }
+ return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo)
+}
+
+// parseAuthorizedKey parses a public key in OpenSSH authorized_keys format
+// (see sshd(8) manual page) once the options and key type fields have been
+// removed.
+func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) {
+ in = bytes.TrimSpace(in)
+
+ i := bytes.IndexAny(in, " \t")
+ if i == -1 {
+ i = len(in)
+ }
+ base64Key := in[:i]
+
+ key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key)))
+ n, err := base64.StdEncoding.Decode(key, base64Key)
+ if err != nil {
+ return nil, "", err
+ }
+ key = key[:n]
+ out, err = ParsePublicKey(key)
+ if err != nil {
+ return nil, "", err
+ }
+ comment = string(bytes.TrimSpace(in[i:]))
+ return out, comment, nil
+}
+
+// ParseKnownHosts parses an entry in the format of the known_hosts file.
+//
+// The known_hosts format is documented in the sshd(8) manual page. This
+// function will parse a single entry from in. On successful return, marker
+// will contain the optional marker value (i.e. "cert-authority" or "revoked")
+// or else be empty, hosts will contain the hosts that this entry matches,
+// pubKey will contain the public key and comment will contain any trailing
+// comment at the end of the line. See the sshd(8) manual page for the various
+// forms that a host string can take.
+//
+// The unparsed remainder of the input will be returned in rest. This function
+// can be called repeatedly to parse multiple entries.
+//
+// If no entries were found in the input then err will be io.EOF. Otherwise a
+// non-nil err value indicates a parse error.
+func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, err error) {
+ for len(in) > 0 {
+ end := bytes.IndexByte(in, '\n')
+ if end != -1 {
+ rest = in[end+1:]
+ in = in[:end]
+ } else {
+ rest = nil
+ }
+
+ end = bytes.IndexByte(in, '\r')
+ if end != -1 {
+ in = in[:end]
+ }
+
+ in = bytes.TrimSpace(in)
+ if len(in) == 0 || in[0] == '#' {
+ in = rest
+ continue
+ }
+
+ i := bytes.IndexAny(in, " \t")
+ if i == -1 {
+ in = rest
+ continue
+ }
+
+ // Strip out the beginning of the known_host key.
+ // This is either an optional marker or a (set of) hostname(s).
+ keyFields := bytes.Fields(in)
+ if len(keyFields) < 3 || len(keyFields) > 5 {
+ return "", nil, nil, "", nil, errors.New("ssh: invalid entry in known_hosts data")
+ }
+
+ // keyFields[0] is either "@cert-authority", "@revoked" or a comma separated
+ // list of hosts
+ marker := ""
+ if keyFields[0][0] == '@' {
+ marker = string(keyFields[0][1:])
+ keyFields = keyFields[1:]
+ }
+
+ hosts := string(keyFields[0])
+ // keyFields[1] contains the key type (e.g. “ssh-rsa”).
+ // However, that information is duplicated inside the
+ // base64-encoded key and so is ignored here.
+
+ key := bytes.Join(keyFields[2:], []byte(" "))
+ if pubKey, comment, err = parseAuthorizedKey(key); err != nil {
+ return "", nil, nil, "", nil, err
+ }
+
+ return marker, strings.Split(hosts, ","), pubKey, comment, rest, nil
+ }
+
+ return "", nil, nil, "", nil, io.EOF
+}
+
+// ParseAuthorizedKey parses a public key from an authorized_keys
+// file used in OpenSSH according to the sshd(8) manual page.
+func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
+ for len(in) > 0 {
+ end := bytes.IndexByte(in, '\n')
+ if end != -1 {
+ rest = in[end+1:]
+ in = in[:end]
+ } else {
+ rest = nil
+ }
+
+ end = bytes.IndexByte(in, '\r')
+ if end != -1 {
+ in = in[:end]
+ }
+
+ in = bytes.TrimSpace(in)
+ if len(in) == 0 || in[0] == '#' {
+ in = rest
+ continue
+ }
+
+ i := bytes.IndexAny(in, " \t")
+ if i == -1 {
+ in = rest
+ continue
+ }
+
+ if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
+ return out, comment, options, rest, nil
+ }
+
+ // No key type recognised. Maybe there's an options field at
+ // the beginning.
+ var b byte
+ inQuote := false
+ var candidateOptions []string
+ optionStart := 0
+ for i, b = range in {
+ isEnd := !inQuote && (b == ' ' || b == '\t')
+ if (b == ',' && !inQuote) || isEnd {
+ if i-optionStart > 0 {
+ candidateOptions = append(candidateOptions, string(in[optionStart:i]))
+ }
+ optionStart = i + 1
+ }
+ if isEnd {
+ break
+ }
+ if b == '"' && (i == 0 || (i > 0 && in[i-1] != '\\')) {
+ inQuote = !inQuote
+ }
+ }
+ for i < len(in) && (in[i] == ' ' || in[i] == '\t') {
+ i++
+ }
+ if i == len(in) {
+ // Invalid line: unmatched quote
+ in = rest
+ continue
+ }
+
+ in = in[i:]
+ i = bytes.IndexAny(in, " \t")
+ if i == -1 {
+ in = rest
+ continue
+ }
+
+ if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
+ options = candidateOptions
+ return out, comment, options, rest, nil
+ }
+
+ in = rest
+ continue
+ }
+
+ return nil, "", nil, nil, errors.New("ssh: no key found")
+}
+
+// ParsePublicKey parses an SSH public key formatted for use in
+// the SSH wire protocol according to RFC 4253, section 6.6.
+func ParsePublicKey(in []byte) (out PublicKey, err error) {
+ algo, in, ok := parseString(in)
+ if !ok {
+ return nil, errShortRead
+ }
+ var rest []byte
+ out, rest, err = parsePubKey(in, string(algo))
+ if len(rest) > 0 {
+ return nil, errors.New("ssh: trailing junk in public key")
+ }
+
+ return out, err
+}
+
+// MarshalAuthorizedKey serializes key for inclusion in an OpenSSH
+// authorized_keys file. The return value ends with newline.
+func MarshalAuthorizedKey(key PublicKey) []byte {
+ b := &bytes.Buffer{}
+ b.WriteString(key.Type())
+ b.WriteByte(' ')
+ e := base64.NewEncoder(base64.StdEncoding, b)
+ e.Write(key.Marshal())
+ e.Close()
+ b.WriteByte('\n')
+ return b.Bytes()
+}
+
+// MarshalPrivateKey returns a PEM block with the private key serialized in the
+// OpenSSH format.
+func MarshalPrivateKey(key crypto.PrivateKey, comment string) (*pem.Block, error) {
+ return marshalOpenSSHPrivateKey(key, comment, unencryptedOpenSSHMarshaler)
+}
+
+// MarshalPrivateKeyWithPassphrase returns a PEM block holding the encrypted
+// private key serialized in the OpenSSH format.
+func MarshalPrivateKeyWithPassphrase(key crypto.PrivateKey, comment string, passphrase []byte) (*pem.Block, error) {
+ return marshalOpenSSHPrivateKey(key, comment, passphraseProtectedOpenSSHMarshaler(passphrase))
+}
+
+// PublicKey represents a public key using an unspecified algorithm.
+//
+// Some PublicKeys provided by this package also implement CryptoPublicKey.
+type PublicKey interface {
+ // Type returns the key format name, e.g. "ssh-rsa".
+ Type() string
+
+ // Marshal returns the serialized key data in SSH wire format, with the name
+ // prefix. To unmarshal the returned data, use the ParsePublicKey function.
+ Marshal() []byte
+
+ // Verify that sig is a signature on the given data using this key. This
+ // method will hash the data appropriately first. sig.Format is allowed to
+ // be any signature algorithm compatible with the key type, the caller
+ // should check if it has more stringent requirements.
+ Verify(data []byte, sig *Signature) error
+}
+
+// CryptoPublicKey, if implemented by a PublicKey,
+// returns the underlying crypto.PublicKey form of the key.
+type CryptoPublicKey interface {
+ CryptoPublicKey() crypto.PublicKey
+}
+
+// A Signer can create signatures that verify against a public key.
+//
+// Some Signers provided by this package also implement MultiAlgorithmSigner.
+type Signer interface {
+ // PublicKey returns the associated PublicKey.
+ PublicKey() PublicKey
+
+ // Sign returns a signature for the given data. This method will hash the
+ // data appropriately first. The signature algorithm is expected to match
+ // the key format returned by the PublicKey.Type method (and not to be any
+ // alternative algorithm supported by the key format).
+ Sign(rand io.Reader, data []byte) (*Signature, error)
+}
+
+// An AlgorithmSigner is a Signer that also supports specifying an algorithm to
+// use for signing.
+//
+// An AlgorithmSigner can't advertise the algorithms it supports, unless it also
+// implements MultiAlgorithmSigner, so it should be prepared to be invoked with
+// every algorithm supported by the public key format.
+type AlgorithmSigner interface {
+ Signer
+
+ // SignWithAlgorithm is like Signer.Sign, but allows specifying a desired
+ // signing algorithm. Callers may pass an empty string for the algorithm in
+ // which case the AlgorithmSigner will use a default algorithm. This default
+ // doesn't currently control any behavior in this package.
+ SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)
+}
+
+// MultiAlgorithmSigner is an AlgorithmSigner that also reports the algorithms
+// supported by that signer.
+type MultiAlgorithmSigner interface {
+ AlgorithmSigner
+
+ // Algorithms returns the available algorithms in preference order. The list
+ // must not be empty, and it must not include certificate types.
+ Algorithms() []string
+}
+
+// NewSignerWithAlgorithms returns a signer restricted to the specified
+// algorithms. The algorithms must be set in preference order. The list must not
+// be empty, and it must not include certificate types. An error is returned if
+// the specified algorithms are incompatible with the public key type.
+func NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (MultiAlgorithmSigner, error) {
+ if len(algorithms) == 0 {
+ return nil, errors.New("ssh: please specify at least one valid signing algorithm")
+ }
+ var signerAlgos []string
+ supportedAlgos := algorithmsForKeyFormat(underlyingAlgo(signer.PublicKey().Type()))
+ if s, ok := signer.(*multiAlgorithmSigner); ok {
+ signerAlgos = s.Algorithms()
+ } else {
+ signerAlgos = supportedAlgos
+ }
+
+ for _, algo := range algorithms {
+ if !contains(supportedAlgos, algo) {
+ return nil, fmt.Errorf("ssh: algorithm %q is not supported for key type %q",
+ algo, signer.PublicKey().Type())
+ }
+ if !contains(signerAlgos, algo) {
+ return nil, fmt.Errorf("ssh: algorithm %q is restricted for the provided signer", algo)
+ }
+ }
+ return &multiAlgorithmSigner{
+ AlgorithmSigner: signer,
+ supportedAlgorithms: algorithms,
+ }, nil
+}
+
+type multiAlgorithmSigner struct {
+ AlgorithmSigner
+ supportedAlgorithms []string
+}
+
+func (s *multiAlgorithmSigner) Algorithms() []string {
+ return s.supportedAlgorithms
+}
+
+func (s *multiAlgorithmSigner) isAlgorithmSupported(algorithm string) bool {
+ if algorithm == "" {
+ algorithm = underlyingAlgo(s.PublicKey().Type())
+ }
+ for _, algo := range s.supportedAlgorithms {
+ if algorithm == algo {
+ return true
+ }
+ }
+ return false
+}
+
+func (s *multiAlgorithmSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
+ if !s.isAlgorithmSupported(algorithm) {
+ return nil, fmt.Errorf("ssh: algorithm %q is not supported: %v", algorithm, s.supportedAlgorithms)
+ }
+ return s.AlgorithmSigner.SignWithAlgorithm(rand, data, algorithm)
+}
+
+type rsaPublicKey rsa.PublicKey
+
+func (r *rsaPublicKey) Type() string {
+ return "ssh-rsa"
+}
+
+// parseRSA parses an RSA key according to RFC 4253, section 6.6.
+func parseRSA(in []byte) (out PublicKey, rest []byte, err error) {
+ var w struct {
+ E *big.Int
+ N *big.Int
+ Rest []byte `ssh:"rest"`
+ }
+ if err := Unmarshal(in, &w); err != nil {
+ return nil, nil, err
+ }
+
+ if w.E.BitLen() > 24 {
+ return nil, nil, errors.New("ssh: exponent too large")
+ }
+ e := w.E.Int64()
+ if e < 3 || e&1 == 0 {
+ return nil, nil, errors.New("ssh: incorrect exponent")
+ }
+
+ var key rsa.PublicKey
+ key.E = int(e)
+ key.N = w.N
+ return (*rsaPublicKey)(&key), w.Rest, nil
+}
+
+func (r *rsaPublicKey) Marshal() []byte {
+ e := new(big.Int).SetInt64(int64(r.E))
+ // RSA publickey struct layout should match the struct used by
+ // parseRSACert in the x/crypto/ssh/agent package.
+ wirekey := struct {
+ Name string
+ E *big.Int
+ N *big.Int
+ }{
+ KeyAlgoRSA,
+ e,
+ r.N,
+ }
+ return Marshal(&wirekey)
+}
+
+func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
+ supportedAlgos := algorithmsForKeyFormat(r.Type())
+ if !contains(supportedAlgos, sig.Format) {
+ return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
+ }
+ hash := hashFuncs[sig.Format]
+ h := hash.New()
+ h.Write(data)
+ digest := h.Sum(nil)
+ return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), hash, digest, sig.Blob)
+}
+
+func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
+ return (*rsa.PublicKey)(r)
+}
+
+type dsaPublicKey dsa.PublicKey
+
+func (k *dsaPublicKey) Type() string {
+ return "ssh-dss"
+}
+
+func checkDSAParams(param *dsa.Parameters) error {
+ // SSH specifies FIPS 186-2, which only provided a single size
+ // (1024 bits) DSA key. FIPS 186-3 allows for larger key
+ // sizes, which would confuse SSH.
+ if l := param.P.BitLen(); l != 1024 {
+ return fmt.Errorf("ssh: unsupported DSA key size %d", l)
+ }
+
+ return nil
+}
+
+// parseDSA parses an DSA key according to RFC 4253, section 6.6.
+func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
+ var w struct {
+ P, Q, G, Y *big.Int
+ Rest []byte `ssh:"rest"`
+ }
+ if err := Unmarshal(in, &w); err != nil {
+ return nil, nil, err
+ }
+
+ param := dsa.Parameters{
+ P: w.P,
+ Q: w.Q,
+ G: w.G,
+ }
+ if err := checkDSAParams(¶m); err != nil {
+ return nil, nil, err
+ }
+
+ key := &dsaPublicKey{
+ Parameters: param,
+ Y: w.Y,
+ }
+ return key, w.Rest, nil
+}
+
+func (k *dsaPublicKey) Marshal() []byte {
+ // DSA publickey struct layout should match the struct used by
+ // parseDSACert in the x/crypto/ssh/agent package.
+ w := struct {
+ Name string
+ P, Q, G, Y *big.Int
+ }{
+ k.Type(),
+ k.P,
+ k.Q,
+ k.G,
+ k.Y,
+ }
+
+ return Marshal(&w)
+}
+
+func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
+ if sig.Format != k.Type() {
+ return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
+ }
+ h := hashFuncs[sig.Format].New()
+ h.Write(data)
+ digest := h.Sum(nil)
+
+ // Per RFC 4253, section 6.6,
+ // The value for 'dss_signature_blob' is encoded as a string containing
+ // r, followed by s (which are 160-bit integers, without lengths or
+ // padding, unsigned, and in network byte order).
+ // For DSS purposes, sig.Blob should be exactly 40 bytes in length.
+ if len(sig.Blob) != 40 {
+ return errors.New("ssh: DSA signature parse error")
+ }
+ r := new(big.Int).SetBytes(sig.Blob[:20])
+ s := new(big.Int).SetBytes(sig.Blob[20:])
+ if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) {
+ return nil
+ }
+ return errors.New("ssh: signature did not verify")
+}
+
+func (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey {
+ return (*dsa.PublicKey)(k)
+}
+
+type dsaPrivateKey struct {
+ *dsa.PrivateKey
+}
+
+func (k *dsaPrivateKey) PublicKey() PublicKey {
+ return (*dsaPublicKey)(&k.PrivateKey.PublicKey)
+}
+
+func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
+ return k.SignWithAlgorithm(rand, data, k.PublicKey().Type())
+}
+
+func (k *dsaPrivateKey) Algorithms() []string {
+ return []string{k.PublicKey().Type()}
+}
+
+func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
+ if algorithm != "" && algorithm != k.PublicKey().Type() {
+ return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
+ }
+
+ h := hashFuncs[k.PublicKey().Type()].New()
+ h.Write(data)
+ digest := h.Sum(nil)
+ r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
+ if err != nil {
+ return nil, err
+ }
+
+ sig := make([]byte, 40)
+ rb := r.Bytes()
+ sb := s.Bytes()
+
+ copy(sig[20-len(rb):20], rb)
+ copy(sig[40-len(sb):], sb)
+
+ return &Signature{
+ Format: k.PublicKey().Type(),
+ Blob: sig,
+ }, nil
+}
+
+type ecdsaPublicKey ecdsa.PublicKey
+
+func (k *ecdsaPublicKey) Type() string {
+ return "ecdsa-sha2-" + k.nistID()
+}
+
+func (k *ecdsaPublicKey) nistID() string {
+ switch k.Params().BitSize {
+ case 256:
+ return "nistp256"
+ case 384:
+ return "nistp384"
+ case 521:
+ return "nistp521"
+ }
+ panic("ssh: unsupported ecdsa key size")
+}
+
+type ed25519PublicKey ed25519.PublicKey
+
+func (k ed25519PublicKey) Type() string {
+ return KeyAlgoED25519
+}
+
+func parseED25519(in []byte) (out PublicKey, rest []byte, err error) {
+ var w struct {
+ KeyBytes []byte
+ Rest []byte `ssh:"rest"`
+ }
+
+ if err := Unmarshal(in, &w); err != nil {
+ return nil, nil, err
+ }
+
+ if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
+ return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
+ }
+
+ return ed25519PublicKey(w.KeyBytes), w.Rest, nil
+}
+
+func (k ed25519PublicKey) Marshal() []byte {
+ w := struct {
+ Name string
+ KeyBytes []byte
+ }{
+ KeyAlgoED25519,
+ []byte(k),
+ }
+ return Marshal(&w)
+}
+
+func (k ed25519PublicKey) Verify(b []byte, sig *Signature) error {
+ if sig.Format != k.Type() {
+ return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
+ }
+ if l := len(k); l != ed25519.PublicKeySize {
+ return fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
+ }
+
+ if ok := ed25519.Verify(ed25519.PublicKey(k), b, sig.Blob); !ok {
+ return errors.New("ssh: signature did not verify")
+ }
+
+ return nil
+}
+
+func (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey {
+ return ed25519.PublicKey(k)
+}
+
+func supportedEllipticCurve(curve elliptic.Curve) bool {
+ return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
+}
+
+// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
+func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
+ var w struct {
+ Curve string
+ KeyBytes []byte
+ Rest []byte `ssh:"rest"`
+ }
+
+ if err := Unmarshal(in, &w); err != nil {
+ return nil, nil, err
+ }
+
+ key := new(ecdsa.PublicKey)
+
+ switch w.Curve {
+ case "nistp256":
+ key.Curve = elliptic.P256()
+ case "nistp384":
+ key.Curve = elliptic.P384()
+ case "nistp521":
+ key.Curve = elliptic.P521()
+ default:
+ return nil, nil, errors.New("ssh: unsupported curve")
+ }
+
+ key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
+ if key.X == nil || key.Y == nil {
+ return nil, nil, errors.New("ssh: invalid curve point")
+ }
+ return (*ecdsaPublicKey)(key), w.Rest, nil
+}
+
+func (k *ecdsaPublicKey) Marshal() []byte {
+ // See RFC 5656, section 3.1.
+ keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
+ // ECDSA publickey struct layout should match the struct used by
+ // parseECDSACert in the x/crypto/ssh/agent package.
+ w := struct {
+ Name string
+ ID string
+ Key []byte
+ }{
+ k.Type(),
+ k.nistID(),
+ keyBytes,
+ }
+
+ return Marshal(&w)
+}
+
+func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
+ if sig.Format != k.Type() {
+ return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
+ }
+
+ h := hashFuncs[sig.Format].New()
+ h.Write(data)
+ digest := h.Sum(nil)
+
+ // Per RFC 5656, section 3.1.2,
+ // The ecdsa_signature_blob value has the following specific encoding:
+ // mpint r
+ // mpint s
+ var ecSig struct {
+ R *big.Int
+ S *big.Int
+ }
+
+ if err := Unmarshal(sig.Blob, &ecSig); err != nil {
+ return err
+ }
+
+ if ecdsa.Verify((*ecdsa.PublicKey)(k), digest, ecSig.R, ecSig.S) {
+ return nil
+ }
+ return errors.New("ssh: signature did not verify")
+}
+
+func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
+ return (*ecdsa.PublicKey)(k)
+}
+
+// skFields holds the additional fields present in U2F/FIDO2 signatures.
+// See openssh/PROTOCOL.u2f 'SSH U2F Signatures' for details.
+type skFields struct {
+ // Flags contains U2F/FIDO2 flags such as 'user present'
+ Flags byte
+ // Counter is a monotonic signature counter which can be
+ // used to detect concurrent use of a private key, should
+ // it be extracted from hardware.
+ Counter uint32
+}
+
+type skECDSAPublicKey struct {
+ // application is a URL-like string, typically "ssh:" for SSH.
+ // see openssh/PROTOCOL.u2f for details.
+ application string
+ ecdsa.PublicKey
+}
+
+func (k *skECDSAPublicKey) Type() string {
+ return KeyAlgoSKECDSA256
+}
+
+func (k *skECDSAPublicKey) nistID() string {
+ return "nistp256"
+}
+
+func parseSKECDSA(in []byte) (out PublicKey, rest []byte, err error) {
+ var w struct {
+ Curve string
+ KeyBytes []byte
+ Application string
+ Rest []byte `ssh:"rest"`
+ }
+
+ if err := Unmarshal(in, &w); err != nil {
+ return nil, nil, err
+ }
+
+ key := new(skECDSAPublicKey)
+ key.application = w.Application
+
+ if w.Curve != "nistp256" {
+ return nil, nil, errors.New("ssh: unsupported curve")
+ }
+ key.Curve = elliptic.P256()
+
+ key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
+ if key.X == nil || key.Y == nil {
+ return nil, nil, errors.New("ssh: invalid curve point")
+ }
+
+ return key, w.Rest, nil
+}
+
+func (k *skECDSAPublicKey) Marshal() []byte {
+ // See RFC 5656, section 3.1.
+ keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
+ w := struct {
+ Name string
+ ID string
+ Key []byte
+ Application string
+ }{
+ k.Type(),
+ k.nistID(),
+ keyBytes,
+ k.application,
+ }
+
+ return Marshal(&w)
+}
+
+func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
+ if sig.Format != k.Type() {
+ return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
+ }
+
+ h := hashFuncs[sig.Format].New()
+ h.Write([]byte(k.application))
+ appDigest := h.Sum(nil)
+
+ h.Reset()
+ h.Write(data)
+ dataDigest := h.Sum(nil)
+
+ var ecSig struct {
+ R *big.Int
+ S *big.Int
+ }
+ if err := Unmarshal(sig.Blob, &ecSig); err != nil {
+ return err
+ }
+
+ var skf skFields
+ if err := Unmarshal(sig.Rest, &skf); err != nil {
+ return err
+ }
+
+ blob := struct {
+ ApplicationDigest []byte `ssh:"rest"`
+ Flags byte
+ Counter uint32
+ MessageDigest []byte `ssh:"rest"`
+ }{
+ appDigest,
+ skf.Flags,
+ skf.Counter,
+ dataDigest,
+ }
+
+ original := Marshal(blob)
+
+ h.Reset()
+ h.Write(original)
+ digest := h.Sum(nil)
+
+ if ecdsa.Verify((*ecdsa.PublicKey)(&k.PublicKey), digest, ecSig.R, ecSig.S) {
+ return nil
+ }
+ return errors.New("ssh: signature did not verify")
+}
+
+func (k *skECDSAPublicKey) CryptoPublicKey() crypto.PublicKey {
+ return &k.PublicKey
+}
+
+type skEd25519PublicKey struct {
+ // application is a URL-like string, typically "ssh:" for SSH.
+ // see openssh/PROTOCOL.u2f for details.
+ application string
+ ed25519.PublicKey
+}
+
+func (k *skEd25519PublicKey) Type() string {
+ return KeyAlgoSKED25519
+}
+
+func parseSKEd25519(in []byte) (out PublicKey, rest []byte, err error) {
+ var w struct {
+ KeyBytes []byte
+ Application string
+ Rest []byte `ssh:"rest"`
+ }
+
+ if err := Unmarshal(in, &w); err != nil {
+ return nil, nil, err
+ }
+
+ if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
+ return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
+ }
+
+ key := new(skEd25519PublicKey)
+ key.application = w.Application
+ key.PublicKey = ed25519.PublicKey(w.KeyBytes)
+
+ return key, w.Rest, nil
+}
+
+func (k *skEd25519PublicKey) Marshal() []byte {
+ w := struct {
+ Name string
+ KeyBytes []byte
+ Application string
+ }{
+ KeyAlgoSKED25519,
+ []byte(k.PublicKey),
+ k.application,
+ }
+ return Marshal(&w)
+}
+
+func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
+ if sig.Format != k.Type() {
+ return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
+ }
+ if l := len(k.PublicKey); l != ed25519.PublicKeySize {
+ return fmt.Errorf("invalid size %d for Ed25519 public key", l)
+ }
+
+ h := hashFuncs[sig.Format].New()
+ h.Write([]byte(k.application))
+ appDigest := h.Sum(nil)
+
+ h.Reset()
+ h.Write(data)
+ dataDigest := h.Sum(nil)
+
+ var edSig struct {
+ Signature []byte `ssh:"rest"`
+ }
+
+ if err := Unmarshal(sig.Blob, &edSig); err != nil {
+ return err
+ }
+
+ var skf skFields
+ if err := Unmarshal(sig.Rest, &skf); err != nil {
+ return err
+ }
+
+ blob := struct {
+ ApplicationDigest []byte `ssh:"rest"`
+ Flags byte
+ Counter uint32
+ MessageDigest []byte `ssh:"rest"`
+ }{
+ appDigest,
+ skf.Flags,
+ skf.Counter,
+ dataDigest,
+ }
+
+ original := Marshal(blob)
+
+ if ok := ed25519.Verify(k.PublicKey, original, edSig.Signature); !ok {
+ return errors.New("ssh: signature did not verify")
+ }
+
+ return nil
+}
+
+func (k *skEd25519PublicKey) CryptoPublicKey() crypto.PublicKey {
+ return k.PublicKey
+}
+
+// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
+// *ecdsa.PrivateKey or any other crypto.Signer and returns a
+// corresponding Signer instance. ECDSA keys must use P-256, P-384 or
+// P-521. DSA keys must use parameter size L1024N160.
+func NewSignerFromKey(key interface{}) (Signer, error) {
+ switch key := key.(type) {
+ case crypto.Signer:
+ return NewSignerFromSigner(key)
+ case *dsa.PrivateKey:
+ return newDSAPrivateKey(key)
+ default:
+ return nil, fmt.Errorf("ssh: unsupported key type %T", key)
+ }
+}
+
+func newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {
+ if err := checkDSAParams(&key.PublicKey.Parameters); err != nil {
+ return nil, err
+ }
+
+ return &dsaPrivateKey{key}, nil
+}
+
+type wrappedSigner struct {
+ signer crypto.Signer
+ pubKey PublicKey
+}
+
+// NewSignerFromSigner takes any crypto.Signer implementation and
+// returns a corresponding Signer interface. This can be used, for
+// example, with keys kept in hardware modules.
+func NewSignerFromSigner(signer crypto.Signer) (Signer, error) {
+ pubKey, err := NewPublicKey(signer.Public())
+ if err != nil {
+ return nil, err
+ }
+
+ return &wrappedSigner{signer, pubKey}, nil
+}
+
+func (s *wrappedSigner) PublicKey() PublicKey {
+ return s.pubKey
+}
+
+func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
+ return s.SignWithAlgorithm(rand, data, s.pubKey.Type())
+}
+
+func (s *wrappedSigner) Algorithms() []string {
+ return algorithmsForKeyFormat(s.pubKey.Type())
+}
+
+func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
+ if algorithm == "" {
+ algorithm = s.pubKey.Type()
+ }
+
+ if !contains(s.Algorithms(), algorithm) {
+ return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type())
+ }
+
+ hashFunc := hashFuncs[algorithm]
+ var digest []byte
+ if hashFunc != 0 {
+ h := hashFunc.New()
+ h.Write(data)
+ digest = h.Sum(nil)
+ } else {
+ digest = data
+ }
+
+ signature, err := s.signer.Sign(rand, digest, hashFunc)
+ if err != nil {
+ return nil, err
+ }
+
+ // crypto.Signer.Sign is expected to return an ASN.1-encoded signature
+ // for ECDSA and DSA, but that's not the encoding expected by SSH, so
+ // re-encode.
+ switch s.pubKey.(type) {
+ case *ecdsaPublicKey, *dsaPublicKey:
+ type asn1Signature struct {
+ R, S *big.Int
+ }
+ asn1Sig := new(asn1Signature)
+ _, err := asn1.Unmarshal(signature, asn1Sig)
+ if err != nil {
+ return nil, err
+ }
+
+ switch s.pubKey.(type) {
+ case *ecdsaPublicKey:
+ signature = Marshal(asn1Sig)
+
+ case *dsaPublicKey:
+ signature = make([]byte, 40)
+ r := asn1Sig.R.Bytes()
+ s := asn1Sig.S.Bytes()
+ copy(signature[20-len(r):20], r)
+ copy(signature[40-len(s):40], s)
+ }
+ }
+
+ return &Signature{
+ Format: algorithm,
+ Blob: signature,
+ }, nil
+}
+
+// NewPublicKey takes an *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,
+// or ed25519.PublicKey returns a corresponding PublicKey instance.
+// ECDSA keys must use P-256, P-384 or P-521.
+func NewPublicKey(key interface{}) (PublicKey, error) {
+ switch key := key.(type) {
+ case *rsa.PublicKey:
+ return (*rsaPublicKey)(key), nil
+ case *ecdsa.PublicKey:
+ if !supportedEllipticCurve(key.Curve) {
+ return nil, errors.New("ssh: only P-256, P-384 and P-521 EC keys are supported")
+ }
+ return (*ecdsaPublicKey)(key), nil
+ case *dsa.PublicKey:
+ return (*dsaPublicKey)(key), nil
+ case ed25519.PublicKey:
+ if l := len(key); l != ed25519.PublicKeySize {
+ return nil, fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
+ }
+ return ed25519PublicKey(key), nil
+ default:
+ return nil, fmt.Errorf("ssh: unsupported key type %T", key)
+ }
+}
+
+// ParsePrivateKey returns a Signer from a PEM encoded private key. It supports
+// the same keys as ParseRawPrivateKey. If the private key is encrypted, it
+// will return a PassphraseMissingError.
+func ParsePrivateKey(pemBytes []byte) (Signer, error) {
+ key, err := ParseRawPrivateKey(pemBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ return NewSignerFromKey(key)
+}
+
+// ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private
+// key and passphrase. It supports the same keys as
+// ParseRawPrivateKeyWithPassphrase.
+func ParsePrivateKeyWithPassphrase(pemBytes, passphrase []byte) (Signer, error) {
+ key, err := ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase)
+ if err != nil {
+ return nil, err
+ }
+
+ return NewSignerFromKey(key)
+}
+
+// encryptedBlock tells whether a private key is
+// encrypted by examining its Proc-Type header
+// for a mention of ENCRYPTED
+// according to RFC 1421 Section 4.6.1.1.
+func encryptedBlock(block *pem.Block) bool {
+ return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
+}
+
+// A PassphraseMissingError indicates that parsing this private key requires a
+// passphrase. Use ParsePrivateKeyWithPassphrase.
+type PassphraseMissingError struct {
+ // PublicKey will be set if the private key format includes an unencrypted
+ // public key along with the encrypted private key.
+ PublicKey PublicKey
+}
+
+func (*PassphraseMissingError) Error() string {
+ return "ssh: this private key is passphrase protected"
+}
+
+// ParseRawPrivateKey returns a private key from a PEM encoded private key. It supports
+// RSA, DSA, ECDSA, and Ed25519 private keys in PKCS#1, PKCS#8, OpenSSL, and OpenSSH
+// formats. If the private key is encrypted, it will return a PassphraseMissingError.
+func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
+ block, _ := pem.Decode(pemBytes)
+ if block == nil {
+ return nil, errors.New("ssh: no key found")
+ }
+
+ if encryptedBlock(block) {
+ return nil, &PassphraseMissingError{}
+ }
+
+ switch block.Type {
+ case "RSA PRIVATE KEY":
+ return x509.ParsePKCS1PrivateKey(block.Bytes)
+ // RFC5208 - https://tools.ietf.org/html/rfc5208
+ case "PRIVATE KEY":
+ return x509.ParsePKCS8PrivateKey(block.Bytes)
+ case "EC PRIVATE KEY":
+ return x509.ParseECPrivateKey(block.Bytes)
+ case "DSA PRIVATE KEY":
+ return ParseDSAPrivateKey(block.Bytes)
+ case "OPENSSH PRIVATE KEY":
+ return parseOpenSSHPrivateKey(block.Bytes, unencryptedOpenSSHKey)
+ default:
+ return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
+ }
+}
+
+// ParseRawPrivateKeyWithPassphrase returns a private key decrypted with
+// passphrase from a PEM encoded private key. If the passphrase is wrong, it
+// will return x509.IncorrectPasswordError.
+func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{}, error) {
+ block, _ := pem.Decode(pemBytes)
+ if block == nil {
+ return nil, errors.New("ssh: no key found")
+ }
+
+ if block.Type == "OPENSSH PRIVATE KEY" {
+ return parseOpenSSHPrivateKey(block.Bytes, passphraseProtectedOpenSSHKey(passphrase))
+ }
+
+ if !encryptedBlock(block) || !x509.IsEncryptedPEMBlock(block) {
+ return nil, errors.New("ssh: not an encrypted key")
+ }
+
+ buf, err := x509.DecryptPEMBlock(block, passphrase)
+ if err != nil {
+ if err == x509.IncorrectPasswordError {
+ return nil, err
+ }
+ return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err)
+ }
+
+ var result interface{}
+
+ switch block.Type {
+ case "RSA PRIVATE KEY":
+ result, err = x509.ParsePKCS1PrivateKey(buf)
+ case "EC PRIVATE KEY":
+ result, err = x509.ParseECPrivateKey(buf)
+ case "DSA PRIVATE KEY":
+ result, err = ParseDSAPrivateKey(buf)
+ default:
+ err = fmt.Errorf("ssh: unsupported key type %q", block.Type)
+ }
+ // Because of deficiencies in the format, DecryptPEMBlock does not always
+ // detect an incorrect password. In these cases decrypted DER bytes is
+ // random noise. If the parsing of the key returns an asn1.StructuralError
+ // we return x509.IncorrectPasswordError.
+ if _, ok := err.(asn1.StructuralError); ok {
+ return nil, x509.IncorrectPasswordError
+ }
+
+ return result, err
+}
+
+// ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as
+// specified by the OpenSSL DSA man page.
+func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {
+ var k struct {
+ Version int
+ P *big.Int
+ Q *big.Int
+ G *big.Int
+ Pub *big.Int
+ Priv *big.Int
+ }
+ rest, err := asn1.Unmarshal(der, &k)
+ if err != nil {
+ return nil, errors.New("ssh: failed to parse DSA key: " + err.Error())
+ }
+ if len(rest) > 0 {
+ return nil, errors.New("ssh: garbage after DSA key")
+ }
+
+ return &dsa.PrivateKey{
+ PublicKey: dsa.PublicKey{
+ Parameters: dsa.Parameters{
+ P: k.P,
+ Q: k.Q,
+ G: k.G,
+ },
+ Y: k.Pub,
+ },
+ X: k.Priv,
+ }, nil
+}
+
+func unencryptedOpenSSHKey(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
+ if kdfName != "none" || cipherName != "none" {
+ return nil, &PassphraseMissingError{}
+ }
+ if kdfOpts != "" {
+ return nil, errors.New("ssh: invalid openssh private key")
+ }
+ return privKeyBlock, nil
+}
+
+func passphraseProtectedOpenSSHKey(passphrase []byte) openSSHDecryptFunc {
+ return func(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
+ if kdfName == "none" || cipherName == "none" {
+ return nil, errors.New("ssh: key is not password protected")
+ }
+ if kdfName != "bcrypt" {
+ return nil, fmt.Errorf("ssh: unknown KDF %q, only supports %q", kdfName, "bcrypt")
+ }
+
+ var opts struct {
+ Salt string
+ Rounds uint32
+ }
+ if err := Unmarshal([]byte(kdfOpts), &opts); err != nil {
+ return nil, err
+ }
+
+ k, err := bcrypt_pbkdf.Key(passphrase, []byte(opts.Salt), int(opts.Rounds), 32+16)
+ if err != nil {
+ return nil, err
+ }
+ key, iv := k[:32], k[32:]
+
+ c, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+ switch cipherName {
+ case "aes256-ctr":
+ ctr := cipher.NewCTR(c, iv)
+ ctr.XORKeyStream(privKeyBlock, privKeyBlock)
+ case "aes256-cbc":
+ if len(privKeyBlock)%c.BlockSize() != 0 {
+ return nil, fmt.Errorf("ssh: invalid encrypted private key length, not a multiple of the block size")
+ }
+ cbc := cipher.NewCBCDecrypter(c, iv)
+ cbc.CryptBlocks(privKeyBlock, privKeyBlock)
+ default:
+ return nil, fmt.Errorf("ssh: unknown cipher %q, only supports %q or %q", cipherName, "aes256-ctr", "aes256-cbc")
+ }
+
+ return privKeyBlock, nil
+ }
+}
+
+func unencryptedOpenSSHMarshaler(privKeyBlock []byte) ([]byte, string, string, string, error) {
+ key := generateOpenSSHPadding(privKeyBlock, 8)
+ return key, "none", "none", "", nil
+}
+
+func passphraseProtectedOpenSSHMarshaler(passphrase []byte) openSSHEncryptFunc {
+ return func(privKeyBlock []byte) ([]byte, string, string, string, error) {
+ salt := make([]byte, 16)
+ if _, err := rand.Read(salt); err != nil {
+ return nil, "", "", "", err
+ }
+
+ opts := struct {
+ Salt []byte
+ Rounds uint32
+ }{salt, 16}
+
+ // Derive key to encrypt the private key block.
+ k, err := bcrypt_pbkdf.Key(passphrase, salt, int(opts.Rounds), 32+aes.BlockSize)
+ if err != nil {
+ return nil, "", "", "", err
+ }
+
+ // Add padding matching the block size of AES.
+ keyBlock := generateOpenSSHPadding(privKeyBlock, aes.BlockSize)
+
+ // Encrypt the private key using the derived secret.
+
+ dst := make([]byte, len(keyBlock))
+ key, iv := k[:32], k[32:]
+ block, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, "", "", "", err
+ }
+
+ stream := cipher.NewCTR(block, iv)
+ stream.XORKeyStream(dst, keyBlock)
+
+ return dst, "aes256-ctr", "bcrypt", string(Marshal(opts)), nil
+ }
+}
+
+const privateKeyAuthMagic = "openssh-key-v1\x00"
+
+type openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error)
+type openSSHEncryptFunc func(PrivKeyBlock []byte) (ProtectedKeyBlock []byte, cipherName, kdfName, kdfOptions string, err error)
+
+type openSSHEncryptedPrivateKey struct {
+ CipherName string
+ KdfName string
+ KdfOpts string
+ NumKeys uint32
+ PubKey []byte
+ PrivKeyBlock []byte
+}
+
+type openSSHPrivateKey struct {
+ Check1 uint32
+ Check2 uint32
+ Keytype string
+ Rest []byte `ssh:"rest"`
+}
+
+type openSSHRSAPrivateKey struct {
+ N *big.Int
+ E *big.Int
+ D *big.Int
+ Iqmp *big.Int
+ P *big.Int
+ Q *big.Int
+ Comment string
+ Pad []byte `ssh:"rest"`
+}
+
+type openSSHEd25519PrivateKey struct {
+ Pub []byte
+ Priv []byte
+ Comment string
+ Pad []byte `ssh:"rest"`
+}
+
+type openSSHECDSAPrivateKey struct {
+ Curve string
+ Pub []byte
+ D *big.Int
+ Comment string
+ Pad []byte `ssh:"rest"`
+}
+
+// parseOpenSSHPrivateKey parses an OpenSSH private key, using the decrypt
+// function to unwrap the encrypted portion. unencryptedOpenSSHKey can be used
+// as the decrypt function to parse an unencrypted private key. See
+// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key.
+func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.PrivateKey, error) {
+ if len(key) < len(privateKeyAuthMagic) || string(key[:len(privateKeyAuthMagic)]) != privateKeyAuthMagic {
+ return nil, errors.New("ssh: invalid openssh private key format")
+ }
+ remaining := key[len(privateKeyAuthMagic):]
+
+ var w openSSHEncryptedPrivateKey
+ if err := Unmarshal(remaining, &w); err != nil {
+ return nil, err
+ }
+ if w.NumKeys != 1 {
+ // We only support single key files, and so does OpenSSH.
+ // https://github.com/openssh/openssh-portable/blob/4103a3ec7/sshkey.c#L4171
+ return nil, errors.New("ssh: multi-key files are not supported")
+ }
+
+ privKeyBlock, err := decrypt(w.CipherName, w.KdfName, w.KdfOpts, w.PrivKeyBlock)
+ if err != nil {
+ if err, ok := err.(*PassphraseMissingError); ok {
+ pub, errPub := ParsePublicKey(w.PubKey)
+ if errPub != nil {
+ return nil, fmt.Errorf("ssh: failed to parse embedded public key: %v", errPub)
+ }
+ err.PublicKey = pub
+ }
+ return nil, err
+ }
+
+ var pk1 openSSHPrivateKey
+ if err := Unmarshal(privKeyBlock, &pk1); err != nil || pk1.Check1 != pk1.Check2 {
+ if w.CipherName != "none" {
+ return nil, x509.IncorrectPasswordError
+ }
+ return nil, errors.New("ssh: malformed OpenSSH key")
+ }
+
+ switch pk1.Keytype {
+ case KeyAlgoRSA:
+ var key openSSHRSAPrivateKey
+ if err := Unmarshal(pk1.Rest, &key); err != nil {
+ return nil, err
+ }
+
+ if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
+ return nil, err
+ }
+
+ pk := &rsa.PrivateKey{
+ PublicKey: rsa.PublicKey{
+ N: key.N,
+ E: int(key.E.Int64()),
+ },
+ D: key.D,
+ Primes: []*big.Int{key.P, key.Q},
+ }
+
+ if err := pk.Validate(); err != nil {
+ return nil, err
+ }
+
+ pk.Precompute()
+
+ return pk, nil
+ case KeyAlgoED25519:
+ var key openSSHEd25519PrivateKey
+ if err := Unmarshal(pk1.Rest, &key); err != nil {
+ return nil, err
+ }
+
+ if len(key.Priv) != ed25519.PrivateKeySize {
+ return nil, errors.New("ssh: private key unexpected length")
+ }
+
+ if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
+ return nil, err
+ }
+
+ pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))
+ copy(pk, key.Priv)
+ return &pk, nil
+ case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
+ var key openSSHECDSAPrivateKey
+ if err := Unmarshal(pk1.Rest, &key); err != nil {
+ return nil, err
+ }
+
+ if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
+ return nil, err
+ }
+
+ var curve elliptic.Curve
+ switch key.Curve {
+ case "nistp256":
+ curve = elliptic.P256()
+ case "nistp384":
+ curve = elliptic.P384()
+ case "nistp521":
+ curve = elliptic.P521()
+ default:
+ return nil, errors.New("ssh: unhandled elliptic curve: " + key.Curve)
+ }
+
+ X, Y := elliptic.Unmarshal(curve, key.Pub)
+ if X == nil || Y == nil {
+ return nil, errors.New("ssh: failed to unmarshal public key")
+ }
+
+ if key.D.Cmp(curve.Params().N) >= 0 {
+ return nil, errors.New("ssh: scalar is out of range")
+ }
+
+ x, y := curve.ScalarBaseMult(key.D.Bytes())
+ if x.Cmp(X) != 0 || y.Cmp(Y) != 0 {
+ return nil, errors.New("ssh: public key does not match private key")
+ }
+
+ return &ecdsa.PrivateKey{
+ PublicKey: ecdsa.PublicKey{
+ Curve: curve,
+ X: X,
+ Y: Y,
+ },
+ D: key.D,
+ }, nil
+ default:
+ return nil, errors.New("ssh: unhandled key type")
+ }
+}
+
+func marshalOpenSSHPrivateKey(key crypto.PrivateKey, comment string, encrypt openSSHEncryptFunc) (*pem.Block, error) {
+ var w openSSHEncryptedPrivateKey
+ var pk1 openSSHPrivateKey
+
+ // Random check bytes.
+ var check uint32
+ if err := binary.Read(rand.Reader, binary.BigEndian, &check); err != nil {
+ return nil, err
+ }
+
+ pk1.Check1 = check
+ pk1.Check2 = check
+ w.NumKeys = 1
+
+ // Use a []byte directly on ed25519 keys.
+ if k, ok := key.(*ed25519.PrivateKey); ok {
+ key = *k
+ }
+
+ switch k := key.(type) {
+ case *rsa.PrivateKey:
+ E := new(big.Int).SetInt64(int64(k.PublicKey.E))
+ // Marshal public key:
+ // E and N are in reversed order in the public and private key.
+ pubKey := struct {
+ KeyType string
+ E *big.Int
+ N *big.Int
+ }{
+ KeyAlgoRSA,
+ E, k.PublicKey.N,
+ }
+ w.PubKey = Marshal(pubKey)
+
+ // Marshal private key.
+ key := openSSHRSAPrivateKey{
+ N: k.PublicKey.N,
+ E: E,
+ D: k.D,
+ Iqmp: k.Precomputed.Qinv,
+ P: k.Primes[0],
+ Q: k.Primes[1],
+ Comment: comment,
+ }
+ pk1.Keytype = KeyAlgoRSA
+ pk1.Rest = Marshal(key)
+ case ed25519.PrivateKey:
+ pub := make([]byte, ed25519.PublicKeySize)
+ priv := make([]byte, ed25519.PrivateKeySize)
+ copy(pub, k[32:])
+ copy(priv, k)
+
+ // Marshal public key.
+ pubKey := struct {
+ KeyType string
+ Pub []byte
+ }{
+ KeyAlgoED25519, pub,
+ }
+ w.PubKey = Marshal(pubKey)
+
+ // Marshal private key.
+ key := openSSHEd25519PrivateKey{
+ Pub: pub,
+ Priv: priv,
+ Comment: comment,
+ }
+ pk1.Keytype = KeyAlgoED25519
+ pk1.Rest = Marshal(key)
+ case *ecdsa.PrivateKey:
+ var curve, keyType string
+ switch name := k.Curve.Params().Name; name {
+ case "P-256":
+ curve = "nistp256"
+ keyType = KeyAlgoECDSA256
+ case "P-384":
+ curve = "nistp384"
+ keyType = KeyAlgoECDSA384
+ case "P-521":
+ curve = "nistp521"
+ keyType = KeyAlgoECDSA521
+ default:
+ return nil, errors.New("ssh: unhandled elliptic curve " + name)
+ }
+
+ pub := elliptic.Marshal(k.Curve, k.PublicKey.X, k.PublicKey.Y)
+
+ // Marshal public key.
+ pubKey := struct {
+ KeyType string
+ Curve string
+ Pub []byte
+ }{
+ keyType, curve, pub,
+ }
+ w.PubKey = Marshal(pubKey)
+
+ // Marshal private key.
+ key := openSSHECDSAPrivateKey{
+ Curve: curve,
+ Pub: pub,
+ D: k.D,
+ Comment: comment,
+ }
+ pk1.Keytype = keyType
+ pk1.Rest = Marshal(key)
+ default:
+ return nil, fmt.Errorf("ssh: unsupported key type %T", k)
+ }
+
+ var err error
+ // Add padding and encrypt the key if necessary.
+ w.PrivKeyBlock, w.CipherName, w.KdfName, w.KdfOpts, err = encrypt(Marshal(pk1))
+ if err != nil {
+ return nil, err
+ }
+
+ b := Marshal(w)
+ block := &pem.Block{
+ Type: "OPENSSH PRIVATE KEY",
+ Bytes: append([]byte(privateKeyAuthMagic), b...),
+ }
+ return block, nil
+}
+
+func checkOpenSSHKeyPadding(pad []byte) error {
+ for i, b := range pad {
+ if int(b) != i+1 {
+ return errors.New("ssh: padding not as expected")
+ }
+ }
+ return nil
+}
+
+func generateOpenSSHPadding(block []byte, blockSize int) []byte {
+ for i, l := 0, len(block); (l+i)%blockSize != 0; i++ {
+ block = append(block, byte(i+1))
+ }
+ return block
+}
+
+// FingerprintLegacyMD5 returns the user presentation of the key's
+// fingerprint as described by RFC 4716 section 4.
+func FingerprintLegacyMD5(pubKey PublicKey) string {
+ md5sum := md5.Sum(pubKey.Marshal())
+ hexarray := make([]string, len(md5sum))
+ for i, c := range md5sum {
+ hexarray[i] = hex.EncodeToString([]byte{c})
+ }
+ return strings.Join(hexarray, ":")
+}
+
+// FingerprintSHA256 returns the user presentation of the key's
+// fingerprint as unpadded base64 encoded sha256 hash.
+// This format was introduced from OpenSSH 6.8.
+// https://www.openssh.com/txt/release-6.8
+// https://tools.ietf.org/html/rfc4648#section-3.2 (unpadded base64 encoding)
+func FingerprintSHA256(pubKey PublicKey) string {
+ sha256sum := sha256.Sum256(pubKey.Marshal())
+ hash := base64.RawStdEncoding.EncodeToString(sha256sum[:])
+ return "SHA256:" + hash
+}
diff --git a/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go b/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go
new file mode 100644
index 00000000..7376a8df
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go
@@ -0,0 +1,540 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package knownhosts implements a parser for the OpenSSH known_hosts
+// host key database, and provides utility functions for writing
+// OpenSSH compliant known_hosts files.
+package knownhosts
+
+import (
+ "bufio"
+ "bytes"
+ "crypto/hmac"
+ "crypto/rand"
+ "crypto/sha1"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "strings"
+
+ "golang.org/x/crypto/ssh"
+)
+
+// See the sshd manpage
+// (http://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT) for
+// background.
+
+type addr struct{ host, port string }
+
+func (a *addr) String() string {
+ h := a.host
+ if strings.Contains(h, ":") {
+ h = "[" + h + "]"
+ }
+ return h + ":" + a.port
+}
+
+type matcher interface {
+ match(addr) bool
+}
+
+type hostPattern struct {
+ negate bool
+ addr addr
+}
+
+func (p *hostPattern) String() string {
+ n := ""
+ if p.negate {
+ n = "!"
+ }
+
+ return n + p.addr.String()
+}
+
+type hostPatterns []hostPattern
+
+func (ps hostPatterns) match(a addr) bool {
+ matched := false
+ for _, p := range ps {
+ if !p.match(a) {
+ continue
+ }
+ if p.negate {
+ return false
+ }
+ matched = true
+ }
+ return matched
+}
+
+// See
+// https://android.googlesource.com/platform/external/openssh/+/ab28f5495c85297e7a597c1ba62e996416da7c7e/addrmatch.c
+// The matching of * has no regard for separators, unlike filesystem globs
+func wildcardMatch(pat []byte, str []byte) bool {
+ for {
+ if len(pat) == 0 {
+ return len(str) == 0
+ }
+ if len(str) == 0 {
+ return false
+ }
+
+ if pat[0] == '*' {
+ if len(pat) == 1 {
+ return true
+ }
+
+ for j := range str {
+ if wildcardMatch(pat[1:], str[j:]) {
+ return true
+ }
+ }
+ return false
+ }
+
+ if pat[0] == '?' || pat[0] == str[0] {
+ pat = pat[1:]
+ str = str[1:]
+ } else {
+ return false
+ }
+ }
+}
+
+func (p *hostPattern) match(a addr) bool {
+ return wildcardMatch([]byte(p.addr.host), []byte(a.host)) && p.addr.port == a.port
+}
+
+type keyDBLine struct {
+ cert bool
+ matcher matcher
+ knownKey KnownKey
+}
+
+func serialize(k ssh.PublicKey) string {
+ return k.Type() + " " + base64.StdEncoding.EncodeToString(k.Marshal())
+}
+
+func (l *keyDBLine) match(a addr) bool {
+ return l.matcher.match(a)
+}
+
+type hostKeyDB struct {
+ // Serialized version of revoked keys
+ revoked map[string]*KnownKey
+ lines []keyDBLine
+}
+
+func newHostKeyDB() *hostKeyDB {
+ db := &hostKeyDB{
+ revoked: make(map[string]*KnownKey),
+ }
+
+ return db
+}
+
+func keyEq(a, b ssh.PublicKey) bool {
+ return bytes.Equal(a.Marshal(), b.Marshal())
+}
+
+// IsHostAuthority can be used as a callback in ssh.CertChecker
+func (db *hostKeyDB) IsHostAuthority(remote ssh.PublicKey, address string) bool {
+ h, p, err := net.SplitHostPort(address)
+ if err != nil {
+ return false
+ }
+ a := addr{host: h, port: p}
+
+ for _, l := range db.lines {
+ if l.cert && keyEq(l.knownKey.Key, remote) && l.match(a) {
+ return true
+ }
+ }
+ return false
+}
+
+// IsRevoked can be used as a callback in ssh.CertChecker
+func (db *hostKeyDB) IsRevoked(key *ssh.Certificate) bool {
+ _, ok := db.revoked[string(key.Marshal())]
+ return ok
+}
+
+const markerCert = "@cert-authority"
+const markerRevoked = "@revoked"
+
+func nextWord(line []byte) (string, []byte) {
+ i := bytes.IndexAny(line, "\t ")
+ if i == -1 {
+ return string(line), nil
+ }
+
+ return string(line[:i]), bytes.TrimSpace(line[i:])
+}
+
+func parseLine(line []byte) (marker, host string, key ssh.PublicKey, err error) {
+ if w, next := nextWord(line); w == markerCert || w == markerRevoked {
+ marker = w
+ line = next
+ }
+
+ host, line = nextWord(line)
+ if len(line) == 0 {
+ return "", "", nil, errors.New("knownhosts: missing host pattern")
+ }
+
+ // ignore the keytype as it's in the key blob anyway.
+ _, line = nextWord(line)
+ if len(line) == 0 {
+ return "", "", nil, errors.New("knownhosts: missing key type pattern")
+ }
+
+ keyBlob, _ := nextWord(line)
+
+ keyBytes, err := base64.StdEncoding.DecodeString(keyBlob)
+ if err != nil {
+ return "", "", nil, err
+ }
+ key, err = ssh.ParsePublicKey(keyBytes)
+ if err != nil {
+ return "", "", nil, err
+ }
+
+ return marker, host, key, nil
+}
+
+func (db *hostKeyDB) parseLine(line []byte, filename string, linenum int) error {
+ marker, pattern, key, err := parseLine(line)
+ if err != nil {
+ return err
+ }
+
+ if marker == markerRevoked {
+ db.revoked[string(key.Marshal())] = &KnownKey{
+ Key: key,
+ Filename: filename,
+ Line: linenum,
+ }
+
+ return nil
+ }
+
+ entry := keyDBLine{
+ cert: marker == markerCert,
+ knownKey: KnownKey{
+ Filename: filename,
+ Line: linenum,
+ Key: key,
+ },
+ }
+
+ if pattern[0] == '|' {
+ entry.matcher, err = newHashedHost(pattern)
+ } else {
+ entry.matcher, err = newHostnameMatcher(pattern)
+ }
+
+ if err != nil {
+ return err
+ }
+
+ db.lines = append(db.lines, entry)
+ return nil
+}
+
+func newHostnameMatcher(pattern string) (matcher, error) {
+ var hps hostPatterns
+ for _, p := range strings.Split(pattern, ",") {
+ if len(p) == 0 {
+ continue
+ }
+
+ var a addr
+ var negate bool
+ if p[0] == '!' {
+ negate = true
+ p = p[1:]
+ }
+
+ if len(p) == 0 {
+ return nil, errors.New("knownhosts: negation without following hostname")
+ }
+
+ var err error
+ if p[0] == '[' {
+ a.host, a.port, err = net.SplitHostPort(p)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ a.host, a.port, err = net.SplitHostPort(p)
+ if err != nil {
+ a.host = p
+ a.port = "22"
+ }
+ }
+ hps = append(hps, hostPattern{
+ negate: negate,
+ addr: a,
+ })
+ }
+ return hps, nil
+}
+
+// KnownKey represents a key declared in a known_hosts file.
+type KnownKey struct {
+ Key ssh.PublicKey
+ Filename string
+ Line int
+}
+
+func (k *KnownKey) String() string {
+ return fmt.Sprintf("%s:%d: %s", k.Filename, k.Line, serialize(k.Key))
+}
+
+// KeyError is returned if we did not find the key in the host key
+// database, or there was a mismatch. Typically, in batch
+// applications, this should be interpreted as failure. Interactive
+// applications can offer an interactive prompt to the user.
+type KeyError struct {
+ // Want holds the accepted host keys. For each key algorithm,
+ // there can be one hostkey. If Want is empty, the host is
+ // unknown. If Want is non-empty, there was a mismatch, which
+ // can signify a MITM attack.
+ Want []KnownKey
+}
+
+func (u *KeyError) Error() string {
+ if len(u.Want) == 0 {
+ return "knownhosts: key is unknown"
+ }
+ return "knownhosts: key mismatch"
+}
+
+// RevokedError is returned if we found a key that was revoked.
+type RevokedError struct {
+ Revoked KnownKey
+}
+
+func (r *RevokedError) Error() string {
+ return "knownhosts: key is revoked"
+}
+
+// check checks a key against the host database. This should not be
+// used for verifying certificates.
+func (db *hostKeyDB) check(address string, remote net.Addr, remoteKey ssh.PublicKey) error {
+ if revoked := db.revoked[string(remoteKey.Marshal())]; revoked != nil {
+ return &RevokedError{Revoked: *revoked}
+ }
+
+ host, port, err := net.SplitHostPort(remote.String())
+ if err != nil {
+ return fmt.Errorf("knownhosts: SplitHostPort(%s): %v", remote, err)
+ }
+
+ hostToCheck := addr{host, port}
+ if address != "" {
+ // Give preference to the hostname if available.
+ host, port, err := net.SplitHostPort(address)
+ if err != nil {
+ return fmt.Errorf("knownhosts: SplitHostPort(%s): %v", address, err)
+ }
+
+ hostToCheck = addr{host, port}
+ }
+
+ return db.checkAddr(hostToCheck, remoteKey)
+}
+
+// checkAddr checks if we can find the given public key for the
+// given address. If we only find an entry for the IP address,
+// or only the hostname, then this still succeeds.
+func (db *hostKeyDB) checkAddr(a addr, remoteKey ssh.PublicKey) error {
+ // TODO(hanwen): are these the right semantics? What if there
+ // is just a key for the IP address, but not for the
+ // hostname?
+
+ // Algorithm => key.
+ knownKeys := map[string]KnownKey{}
+ for _, l := range db.lines {
+ if l.match(a) {
+ typ := l.knownKey.Key.Type()
+ if _, ok := knownKeys[typ]; !ok {
+ knownKeys[typ] = l.knownKey
+ }
+ }
+ }
+
+ keyErr := &KeyError{}
+ for _, v := range knownKeys {
+ keyErr.Want = append(keyErr.Want, v)
+ }
+
+ // Unknown remote host.
+ if len(knownKeys) == 0 {
+ return keyErr
+ }
+
+ // If the remote host starts using a different, unknown key type, we
+ // also interpret that as a mismatch.
+ if known, ok := knownKeys[remoteKey.Type()]; !ok || !keyEq(known.Key, remoteKey) {
+ return keyErr
+ }
+
+ return nil
+}
+
+// The Read function parses file contents.
+func (db *hostKeyDB) Read(r io.Reader, filename string) error {
+ scanner := bufio.NewScanner(r)
+
+ lineNum := 0
+ for scanner.Scan() {
+ lineNum++
+ line := scanner.Bytes()
+ line = bytes.TrimSpace(line)
+ if len(line) == 0 || line[0] == '#' {
+ continue
+ }
+
+ if err := db.parseLine(line, filename, lineNum); err != nil {
+ return fmt.Errorf("knownhosts: %s:%d: %v", filename, lineNum, err)
+ }
+ }
+ return scanner.Err()
+}
+
+// New creates a host key callback from the given OpenSSH host key
+// files. The returned callback is for use in
+// ssh.ClientConfig.HostKeyCallback. By preference, the key check
+// operates on the hostname if available, i.e. if a server changes its
+// IP address, the host key check will still succeed, even though a
+// record of the new IP address is not available.
+func New(files ...string) (ssh.HostKeyCallback, error) {
+ db := newHostKeyDB()
+ for _, fn := range files {
+ f, err := os.Open(fn)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ if err := db.Read(f, fn); err != nil {
+ return nil, err
+ }
+ }
+
+ var certChecker ssh.CertChecker
+ certChecker.IsHostAuthority = db.IsHostAuthority
+ certChecker.IsRevoked = db.IsRevoked
+ certChecker.HostKeyFallback = db.check
+
+ return certChecker.CheckHostKey, nil
+}
+
+// Normalize normalizes an address into the form used in known_hosts
+func Normalize(address string) string {
+ host, port, err := net.SplitHostPort(address)
+ if err != nil {
+ host = address
+ port = "22"
+ }
+ entry := host
+ if port != "22" {
+ entry = "[" + entry + "]:" + port
+ } else if strings.Contains(host, ":") && !strings.HasPrefix(host, "[") {
+ entry = "[" + entry + "]"
+ }
+ return entry
+}
+
+// Line returns a line to add append to the known_hosts files.
+func Line(addresses []string, key ssh.PublicKey) string {
+ var trimmed []string
+ for _, a := range addresses {
+ trimmed = append(trimmed, Normalize(a))
+ }
+
+ return strings.Join(trimmed, ",") + " " + serialize(key)
+}
+
+// HashHostname hashes the given hostname. The hostname is not
+// normalized before hashing.
+func HashHostname(hostname string) string {
+ // TODO(hanwen): check if we can safely normalize this always.
+ salt := make([]byte, sha1.Size)
+
+ _, err := rand.Read(salt)
+ if err != nil {
+ panic(fmt.Sprintf("crypto/rand failure %v", err))
+ }
+
+ hash := hashHost(hostname, salt)
+ return encodeHash(sha1HashType, salt, hash)
+}
+
+func decodeHash(encoded string) (hashType string, salt, hash []byte, err error) {
+ if len(encoded) == 0 || encoded[0] != '|' {
+ err = errors.New("knownhosts: hashed host must start with '|'")
+ return
+ }
+ components := strings.Split(encoded, "|")
+ if len(components) != 4 {
+ err = fmt.Errorf("knownhosts: got %d components, want 3", len(components))
+ return
+ }
+
+ hashType = components[1]
+ if salt, err = base64.StdEncoding.DecodeString(components[2]); err != nil {
+ return
+ }
+ if hash, err = base64.StdEncoding.DecodeString(components[3]); err != nil {
+ return
+ }
+ return
+}
+
+func encodeHash(typ string, salt []byte, hash []byte) string {
+ return strings.Join([]string{"",
+ typ,
+ base64.StdEncoding.EncodeToString(salt),
+ base64.StdEncoding.EncodeToString(hash),
+ }, "|")
+}
+
+// See https://android.googlesource.com/platform/external/openssh/+/ab28f5495c85297e7a597c1ba62e996416da7c7e/hostfile.c#120
+func hashHost(hostname string, salt []byte) []byte {
+ mac := hmac.New(sha1.New, salt)
+ mac.Write([]byte(hostname))
+ return mac.Sum(nil)
+}
+
+type hashedHost struct {
+ salt []byte
+ hash []byte
+}
+
+const sha1HashType = "1"
+
+func newHashedHost(encoded string) (*hashedHost, error) {
+ typ, salt, hash, err := decodeHash(encoded)
+ if err != nil {
+ return nil, err
+ }
+
+ // The type field seems for future algorithm agility, but it's
+ // actually hardcoded in openssh currently, see
+ // https://android.googlesource.com/platform/external/openssh/+/ab28f5495c85297e7a597c1ba62e996416da7c7e/hostfile.c#120
+ if typ != sha1HashType {
+ return nil, fmt.Errorf("knownhosts: got hash type %s, must be '1'", typ)
+ }
+
+ return &hashedHost{salt: salt, hash: hash}, nil
+}
+
+func (h *hashedHost) match(a addr) bool {
+ return bytes.Equal(hashHost(Normalize(a.String()), h.salt), h.hash)
+}
diff --git a/vendor/golang.org/x/crypto/ssh/mac.go b/vendor/golang.org/x/crypto/ssh/mac.go
new file mode 100644
index 00000000..06a1b275
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/mac.go
@@ -0,0 +1,68 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+// Message authentication support
+
+import (
+ "crypto/hmac"
+ "crypto/sha1"
+ "crypto/sha256"
+ "crypto/sha512"
+ "hash"
+)
+
+type macMode struct {
+ keySize int
+ etm bool
+ new func(key []byte) hash.Hash
+}
+
+// truncatingMAC wraps around a hash.Hash and truncates the output digest to
+// a given size.
+type truncatingMAC struct {
+ length int
+ hmac hash.Hash
+}
+
+func (t truncatingMAC) Write(data []byte) (int, error) {
+ return t.hmac.Write(data)
+}
+
+func (t truncatingMAC) Sum(in []byte) []byte {
+ out := t.hmac.Sum(in)
+ return out[:len(in)+t.length]
+}
+
+func (t truncatingMAC) Reset() {
+ t.hmac.Reset()
+}
+
+func (t truncatingMAC) Size() int {
+ return t.length
+}
+
+func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() }
+
+var macModes = map[string]*macMode{
+ "hmac-sha2-512-etm@openssh.com": {64, true, func(key []byte) hash.Hash {
+ return hmac.New(sha512.New, key)
+ }},
+ "hmac-sha2-256-etm@openssh.com": {32, true, func(key []byte) hash.Hash {
+ return hmac.New(sha256.New, key)
+ }},
+ "hmac-sha2-512": {64, false, func(key []byte) hash.Hash {
+ return hmac.New(sha512.New, key)
+ }},
+ "hmac-sha2-256": {32, false, func(key []byte) hash.Hash {
+ return hmac.New(sha256.New, key)
+ }},
+ "hmac-sha1": {20, false, func(key []byte) hash.Hash {
+ return hmac.New(sha1.New, key)
+ }},
+ "hmac-sha1-96": {20, false, func(key []byte) hash.Hash {
+ return truncatingMAC{12, hmac.New(sha1.New, key)}
+ }},
+}
diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go
new file mode 100644
index 00000000..b55f8605
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/messages.go
@@ -0,0 +1,891 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "math/big"
+ "reflect"
+ "strconv"
+ "strings"
+)
+
+// These are SSH message type numbers. They are scattered around several
+// documents but many were taken from [SSH-PARAMETERS].
+const (
+ msgIgnore = 2
+ msgUnimplemented = 3
+ msgDebug = 4
+ msgNewKeys = 21
+)
+
+// SSH messages:
+//
+// These structures mirror the wire format of the corresponding SSH messages.
+// They are marshaled using reflection with the marshal and unmarshal functions
+// in this file. The only wrinkle is that a final member of type []byte with a
+// ssh tag of "rest" receives the remainder of a packet when unmarshaling.
+
+// See RFC 4253, section 11.1.
+const msgDisconnect = 1
+
+// disconnectMsg is the message that signals a disconnect. It is also
+// the error type returned from mux.Wait()
+type disconnectMsg struct {
+ Reason uint32 `sshtype:"1"`
+ Message string
+ Language string
+}
+
+func (d *disconnectMsg) Error() string {
+ return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message)
+}
+
+// See RFC 4253, section 7.1.
+const msgKexInit = 20
+
+type kexInitMsg struct {
+ Cookie [16]byte `sshtype:"20"`
+ KexAlgos []string
+ ServerHostKeyAlgos []string
+ CiphersClientServer []string
+ CiphersServerClient []string
+ MACsClientServer []string
+ MACsServerClient []string
+ CompressionClientServer []string
+ CompressionServerClient []string
+ LanguagesClientServer []string
+ LanguagesServerClient []string
+ FirstKexFollows bool
+ Reserved uint32
+}
+
+// See RFC 4253, section 8.
+
+// Diffie-Hellman
+const msgKexDHInit = 30
+
+type kexDHInitMsg struct {
+ X *big.Int `sshtype:"30"`
+}
+
+const msgKexECDHInit = 30
+
+type kexECDHInitMsg struct {
+ ClientPubKey []byte `sshtype:"30"`
+}
+
+const msgKexECDHReply = 31
+
+type kexECDHReplyMsg struct {
+ HostKey []byte `sshtype:"31"`
+ EphemeralPubKey []byte
+ Signature []byte
+}
+
+const msgKexDHReply = 31
+
+type kexDHReplyMsg struct {
+ HostKey []byte `sshtype:"31"`
+ Y *big.Int
+ Signature []byte
+}
+
+// See RFC 4419, section 5.
+const msgKexDHGexGroup = 31
+
+type kexDHGexGroupMsg struct {
+ P *big.Int `sshtype:"31"`
+ G *big.Int
+}
+
+const msgKexDHGexInit = 32
+
+type kexDHGexInitMsg struct {
+ X *big.Int `sshtype:"32"`
+}
+
+const msgKexDHGexReply = 33
+
+type kexDHGexReplyMsg struct {
+ HostKey []byte `sshtype:"33"`
+ Y *big.Int
+ Signature []byte
+}
+
+const msgKexDHGexRequest = 34
+
+type kexDHGexRequestMsg struct {
+ MinBits uint32 `sshtype:"34"`
+ PreferedBits uint32
+ MaxBits uint32
+}
+
+// See RFC 4253, section 10.
+const msgServiceRequest = 5
+
+type serviceRequestMsg struct {
+ Service string `sshtype:"5"`
+}
+
+// See RFC 4253, section 10.
+const msgServiceAccept = 6
+
+type serviceAcceptMsg struct {
+ Service string `sshtype:"6"`
+}
+
+// See RFC 8308, section 2.3
+const msgExtInfo = 7
+
+type extInfoMsg struct {
+ NumExtensions uint32 `sshtype:"7"`
+ Payload []byte `ssh:"rest"`
+}
+
+// See RFC 4252, section 5.
+const msgUserAuthRequest = 50
+
+type userAuthRequestMsg struct {
+ User string `sshtype:"50"`
+ Service string
+ Method string
+ Payload []byte `ssh:"rest"`
+}
+
+// Used for debug printouts of packets.
+type userAuthSuccessMsg struct {
+}
+
+// See RFC 4252, section 5.1
+const msgUserAuthFailure = 51
+
+type userAuthFailureMsg struct {
+ Methods []string `sshtype:"51"`
+ PartialSuccess bool
+}
+
+// See RFC 4252, section 5.1
+const msgUserAuthSuccess = 52
+
+// See RFC 4252, section 5.4
+const msgUserAuthBanner = 53
+
+type userAuthBannerMsg struct {
+ Message string `sshtype:"53"`
+ // unused, but required to allow message parsing
+ Language string
+}
+
+// See RFC 4256, section 3.2
+const msgUserAuthInfoRequest = 60
+const msgUserAuthInfoResponse = 61
+
+type userAuthInfoRequestMsg struct {
+ Name string `sshtype:"60"`
+ Instruction string
+ Language string
+ NumPrompts uint32
+ Prompts []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 5.1.
+const msgChannelOpen = 90
+
+type channelOpenMsg struct {
+ ChanType string `sshtype:"90"`
+ PeersID uint32
+ PeersWindow uint32
+ MaxPacketSize uint32
+ TypeSpecificData []byte `ssh:"rest"`
+}
+
+const msgChannelExtendedData = 95
+const msgChannelData = 94
+
+// Used for debug print outs of packets.
+type channelDataMsg struct {
+ PeersID uint32 `sshtype:"94"`
+ Length uint32
+ Rest []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 5.1.
+const msgChannelOpenConfirm = 91
+
+type channelOpenConfirmMsg struct {
+ PeersID uint32 `sshtype:"91"`
+ MyID uint32
+ MyWindow uint32
+ MaxPacketSize uint32
+ TypeSpecificData []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 5.1.
+const msgChannelOpenFailure = 92
+
+type channelOpenFailureMsg struct {
+ PeersID uint32 `sshtype:"92"`
+ Reason RejectionReason
+ Message string
+ Language string
+}
+
+const msgChannelRequest = 98
+
+type channelRequestMsg struct {
+ PeersID uint32 `sshtype:"98"`
+ Request string
+ WantReply bool
+ RequestSpecificData []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 5.4.
+const msgChannelSuccess = 99
+
+type channelRequestSuccessMsg struct {
+ PeersID uint32 `sshtype:"99"`
+}
+
+// See RFC 4254, section 5.4.
+const msgChannelFailure = 100
+
+type channelRequestFailureMsg struct {
+ PeersID uint32 `sshtype:"100"`
+}
+
+// See RFC 4254, section 5.3
+const msgChannelClose = 97
+
+type channelCloseMsg struct {
+ PeersID uint32 `sshtype:"97"`
+}
+
+// See RFC 4254, section 5.3
+const msgChannelEOF = 96
+
+type channelEOFMsg struct {
+ PeersID uint32 `sshtype:"96"`
+}
+
+// See RFC 4254, section 4
+const msgGlobalRequest = 80
+
+type globalRequestMsg struct {
+ Type string `sshtype:"80"`
+ WantReply bool
+ Data []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 4
+const msgRequestSuccess = 81
+
+type globalRequestSuccessMsg struct {
+ Data []byte `ssh:"rest" sshtype:"81"`
+}
+
+// See RFC 4254, section 4
+const msgRequestFailure = 82
+
+type globalRequestFailureMsg struct {
+ Data []byte `ssh:"rest" sshtype:"82"`
+}
+
+// See RFC 4254, section 5.2
+const msgChannelWindowAdjust = 93
+
+type windowAdjustMsg struct {
+ PeersID uint32 `sshtype:"93"`
+ AdditionalBytes uint32
+}
+
+// See RFC 4252, section 7
+const msgUserAuthPubKeyOk = 60
+
+type userAuthPubKeyOkMsg struct {
+ Algo string `sshtype:"60"`
+ PubKey []byte
+}
+
+// See RFC 4462, section 3
+const msgUserAuthGSSAPIResponse = 60
+
+type userAuthGSSAPIResponse struct {
+ SupportMech []byte `sshtype:"60"`
+}
+
+const msgUserAuthGSSAPIToken = 61
+
+type userAuthGSSAPIToken struct {
+ Token []byte `sshtype:"61"`
+}
+
+const msgUserAuthGSSAPIMIC = 66
+
+type userAuthGSSAPIMIC struct {
+ MIC []byte `sshtype:"66"`
+}
+
+// See RFC 4462, section 3.9
+const msgUserAuthGSSAPIErrTok = 64
+
+type userAuthGSSAPIErrTok struct {
+ ErrorToken []byte `sshtype:"64"`
+}
+
+// See RFC 4462, section 3.8
+const msgUserAuthGSSAPIError = 65
+
+type userAuthGSSAPIError struct {
+ MajorStatus uint32 `sshtype:"65"`
+ MinorStatus uint32
+ Message string
+ LanguageTag string
+}
+
+// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
+const msgPing = 192
+
+type pingMsg struct {
+ Data string `sshtype:"192"`
+}
+
+// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
+const msgPong = 193
+
+type pongMsg struct {
+ Data string `sshtype:"193"`
+}
+
+// typeTags returns the possible type bytes for the given reflect.Type, which
+// should be a struct. The possible values are separated by a '|' character.
+func typeTags(structType reflect.Type) (tags []byte) {
+ tagStr := structType.Field(0).Tag.Get("sshtype")
+
+ for _, tag := range strings.Split(tagStr, "|") {
+ i, err := strconv.Atoi(tag)
+ if err == nil {
+ tags = append(tags, byte(i))
+ }
+ }
+
+ return tags
+}
+
+func fieldError(t reflect.Type, field int, problem string) error {
+ if problem != "" {
+ problem = ": " + problem
+ }
+ return fmt.Errorf("ssh: unmarshal error for field %s of type %s%s", t.Field(field).Name, t.Name(), problem)
+}
+
+var errShortRead = errors.New("ssh: short read")
+
+// Unmarshal parses data in SSH wire format into a structure. The out
+// argument should be a pointer to struct. If the first member of the
+// struct has the "sshtype" tag set to a '|'-separated set of numbers
+// in decimal, the packet must start with one of those numbers. In
+// case of error, Unmarshal returns a ParseError or
+// UnexpectedMessageError.
+func Unmarshal(data []byte, out interface{}) error {
+ v := reflect.ValueOf(out).Elem()
+ structType := v.Type()
+ expectedTypes := typeTags(structType)
+
+ var expectedType byte
+ if len(expectedTypes) > 0 {
+ expectedType = expectedTypes[0]
+ }
+
+ if len(data) == 0 {
+ return parseError(expectedType)
+ }
+
+ if len(expectedTypes) > 0 {
+ goodType := false
+ for _, e := range expectedTypes {
+ if e > 0 && data[0] == e {
+ goodType = true
+ break
+ }
+ }
+ if !goodType {
+ return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes)
+ }
+ data = data[1:]
+ }
+
+ var ok bool
+ for i := 0; i < v.NumField(); i++ {
+ field := v.Field(i)
+ t := field.Type()
+ switch t.Kind() {
+ case reflect.Bool:
+ if len(data) < 1 {
+ return errShortRead
+ }
+ field.SetBool(data[0] != 0)
+ data = data[1:]
+ case reflect.Array:
+ if t.Elem().Kind() != reflect.Uint8 {
+ return fieldError(structType, i, "array of unsupported type")
+ }
+ if len(data) < t.Len() {
+ return errShortRead
+ }
+ for j, n := 0, t.Len(); j < n; j++ {
+ field.Index(j).Set(reflect.ValueOf(data[j]))
+ }
+ data = data[t.Len():]
+ case reflect.Uint64:
+ var u64 uint64
+ if u64, data, ok = parseUint64(data); !ok {
+ return errShortRead
+ }
+ field.SetUint(u64)
+ case reflect.Uint32:
+ var u32 uint32
+ if u32, data, ok = parseUint32(data); !ok {
+ return errShortRead
+ }
+ field.SetUint(uint64(u32))
+ case reflect.Uint8:
+ if len(data) < 1 {
+ return errShortRead
+ }
+ field.SetUint(uint64(data[0]))
+ data = data[1:]
+ case reflect.String:
+ var s []byte
+ if s, data, ok = parseString(data); !ok {
+ return fieldError(structType, i, "")
+ }
+ field.SetString(string(s))
+ case reflect.Slice:
+ switch t.Elem().Kind() {
+ case reflect.Uint8:
+ if structType.Field(i).Tag.Get("ssh") == "rest" {
+ field.Set(reflect.ValueOf(data))
+ data = nil
+ } else {
+ var s []byte
+ if s, data, ok = parseString(data); !ok {
+ return errShortRead
+ }
+ field.Set(reflect.ValueOf(s))
+ }
+ case reflect.String:
+ var nl []string
+ if nl, data, ok = parseNameList(data); !ok {
+ return errShortRead
+ }
+ field.Set(reflect.ValueOf(nl))
+ default:
+ return fieldError(structType, i, "slice of unsupported type")
+ }
+ case reflect.Ptr:
+ if t == bigIntType {
+ var n *big.Int
+ if n, data, ok = parseInt(data); !ok {
+ return errShortRead
+ }
+ field.Set(reflect.ValueOf(n))
+ } else {
+ return fieldError(structType, i, "pointer to unsupported type")
+ }
+ default:
+ return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t))
+ }
+ }
+
+ if len(data) != 0 {
+ return parseError(expectedType)
+ }
+
+ return nil
+}
+
+// Marshal serializes the message in msg to SSH wire format. The msg
+// argument should be a struct or pointer to struct. If the first
+// member has the "sshtype" tag set to a number in decimal, that
+// number is prepended to the result. If the last of member has the
+// "ssh" tag set to "rest", its contents are appended to the output.
+func Marshal(msg interface{}) []byte {
+ out := make([]byte, 0, 64)
+ return marshalStruct(out, msg)
+}
+
+func marshalStruct(out []byte, msg interface{}) []byte {
+ v := reflect.Indirect(reflect.ValueOf(msg))
+ msgTypes := typeTags(v.Type())
+ if len(msgTypes) > 0 {
+ out = append(out, msgTypes[0])
+ }
+
+ for i, n := 0, v.NumField(); i < n; i++ {
+ field := v.Field(i)
+ switch t := field.Type(); t.Kind() {
+ case reflect.Bool:
+ var v uint8
+ if field.Bool() {
+ v = 1
+ }
+ out = append(out, v)
+ case reflect.Array:
+ if t.Elem().Kind() != reflect.Uint8 {
+ panic(fmt.Sprintf("array of non-uint8 in field %d: %T", i, field.Interface()))
+ }
+ for j, l := 0, t.Len(); j < l; j++ {
+ out = append(out, uint8(field.Index(j).Uint()))
+ }
+ case reflect.Uint32:
+ out = appendU32(out, uint32(field.Uint()))
+ case reflect.Uint64:
+ out = appendU64(out, uint64(field.Uint()))
+ case reflect.Uint8:
+ out = append(out, uint8(field.Uint()))
+ case reflect.String:
+ s := field.String()
+ out = appendInt(out, len(s))
+ out = append(out, s...)
+ case reflect.Slice:
+ switch t.Elem().Kind() {
+ case reflect.Uint8:
+ if v.Type().Field(i).Tag.Get("ssh") != "rest" {
+ out = appendInt(out, field.Len())
+ }
+ out = append(out, field.Bytes()...)
+ case reflect.String:
+ offset := len(out)
+ out = appendU32(out, 0)
+ if n := field.Len(); n > 0 {
+ for j := 0; j < n; j++ {
+ f := field.Index(j)
+ if j != 0 {
+ out = append(out, ',')
+ }
+ out = append(out, f.String()...)
+ }
+ // overwrite length value
+ binary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4))
+ }
+ default:
+ panic(fmt.Sprintf("slice of unknown type in field %d: %T", i, field.Interface()))
+ }
+ case reflect.Ptr:
+ if t == bigIntType {
+ var n *big.Int
+ nValue := reflect.ValueOf(&n)
+ nValue.Elem().Set(field)
+ needed := intLength(n)
+ oldLength := len(out)
+
+ if cap(out)-len(out) < needed {
+ newOut := make([]byte, len(out), 2*(len(out)+needed))
+ copy(newOut, out)
+ out = newOut
+ }
+ out = out[:oldLength+needed]
+ marshalInt(out[oldLength:], n)
+ } else {
+ panic(fmt.Sprintf("pointer to unknown type in field %d: %T", i, field.Interface()))
+ }
+ }
+ }
+
+ return out
+}
+
+var bigOne = big.NewInt(1)
+
+func parseString(in []byte) (out, rest []byte, ok bool) {
+ if len(in) < 4 {
+ return
+ }
+ length := binary.BigEndian.Uint32(in)
+ in = in[4:]
+ if uint32(len(in)) < length {
+ return
+ }
+ out = in[:length]
+ rest = in[length:]
+ ok = true
+ return
+}
+
+var (
+ comma = []byte{','}
+ emptyNameList = []string{}
+)
+
+func parseNameList(in []byte) (out []string, rest []byte, ok bool) {
+ contents, rest, ok := parseString(in)
+ if !ok {
+ return
+ }
+ if len(contents) == 0 {
+ out = emptyNameList
+ return
+ }
+ parts := bytes.Split(contents, comma)
+ out = make([]string, len(parts))
+ for i, part := range parts {
+ out[i] = string(part)
+ }
+ return
+}
+
+func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) {
+ contents, rest, ok := parseString(in)
+ if !ok {
+ return
+ }
+ out = new(big.Int)
+
+ if len(contents) > 0 && contents[0]&0x80 == 0x80 {
+ // This is a negative number
+ notBytes := make([]byte, len(contents))
+ for i := range notBytes {
+ notBytes[i] = ^contents[i]
+ }
+ out.SetBytes(notBytes)
+ out.Add(out, bigOne)
+ out.Neg(out)
+ } else {
+ // Positive number
+ out.SetBytes(contents)
+ }
+ ok = true
+ return
+}
+
+func parseUint32(in []byte) (uint32, []byte, bool) {
+ if len(in) < 4 {
+ return 0, nil, false
+ }
+ return binary.BigEndian.Uint32(in), in[4:], true
+}
+
+func parseUint64(in []byte) (uint64, []byte, bool) {
+ if len(in) < 8 {
+ return 0, nil, false
+ }
+ return binary.BigEndian.Uint64(in), in[8:], true
+}
+
+func intLength(n *big.Int) int {
+ length := 4 /* length bytes */
+ if n.Sign() < 0 {
+ nMinus1 := new(big.Int).Neg(n)
+ nMinus1.Sub(nMinus1, bigOne)
+ bitLen := nMinus1.BitLen()
+ if bitLen%8 == 0 {
+ // The number will need 0xff padding
+ length++
+ }
+ length += (bitLen + 7) / 8
+ } else if n.Sign() == 0 {
+ // A zero is the zero length string
+ } else {
+ bitLen := n.BitLen()
+ if bitLen%8 == 0 {
+ // The number will need 0x00 padding
+ length++
+ }
+ length += (bitLen + 7) / 8
+ }
+
+ return length
+}
+
+func marshalUint32(to []byte, n uint32) []byte {
+ binary.BigEndian.PutUint32(to, n)
+ return to[4:]
+}
+
+func marshalUint64(to []byte, n uint64) []byte {
+ binary.BigEndian.PutUint64(to, n)
+ return to[8:]
+}
+
+func marshalInt(to []byte, n *big.Int) []byte {
+ lengthBytes := to
+ to = to[4:]
+ length := 0
+
+ if n.Sign() < 0 {
+ // A negative number has to be converted to two's-complement
+ // form. So we'll subtract 1 and invert. If the
+ // most-significant-bit isn't set then we'll need to pad the
+ // beginning with 0xff in order to keep the number negative.
+ nMinus1 := new(big.Int).Neg(n)
+ nMinus1.Sub(nMinus1, bigOne)
+ bytes := nMinus1.Bytes()
+ for i := range bytes {
+ bytes[i] ^= 0xff
+ }
+ if len(bytes) == 0 || bytes[0]&0x80 == 0 {
+ to[0] = 0xff
+ to = to[1:]
+ length++
+ }
+ nBytes := copy(to, bytes)
+ to = to[nBytes:]
+ length += nBytes
+ } else if n.Sign() == 0 {
+ // A zero is the zero length string
+ } else {
+ bytes := n.Bytes()
+ if len(bytes) > 0 && bytes[0]&0x80 != 0 {
+ // We'll have to pad this with a 0x00 in order to
+ // stop it looking like a negative number.
+ to[0] = 0
+ to = to[1:]
+ length++
+ }
+ nBytes := copy(to, bytes)
+ to = to[nBytes:]
+ length += nBytes
+ }
+
+ lengthBytes[0] = byte(length >> 24)
+ lengthBytes[1] = byte(length >> 16)
+ lengthBytes[2] = byte(length >> 8)
+ lengthBytes[3] = byte(length)
+ return to
+}
+
+func writeInt(w io.Writer, n *big.Int) {
+ length := intLength(n)
+ buf := make([]byte, length)
+ marshalInt(buf, n)
+ w.Write(buf)
+}
+
+func writeString(w io.Writer, s []byte) {
+ var lengthBytes [4]byte
+ lengthBytes[0] = byte(len(s) >> 24)
+ lengthBytes[1] = byte(len(s) >> 16)
+ lengthBytes[2] = byte(len(s) >> 8)
+ lengthBytes[3] = byte(len(s))
+ w.Write(lengthBytes[:])
+ w.Write(s)
+}
+
+func stringLength(n int) int {
+ return 4 + n
+}
+
+func marshalString(to []byte, s []byte) []byte {
+ to[0] = byte(len(s) >> 24)
+ to[1] = byte(len(s) >> 16)
+ to[2] = byte(len(s) >> 8)
+ to[3] = byte(len(s))
+ to = to[4:]
+ copy(to, s)
+ return to[len(s):]
+}
+
+var bigIntType = reflect.TypeOf((*big.Int)(nil))
+
+// Decode a packet into its corresponding message.
+func decode(packet []byte) (interface{}, error) {
+ var msg interface{}
+ switch packet[0] {
+ case msgDisconnect:
+ msg = new(disconnectMsg)
+ case msgServiceRequest:
+ msg = new(serviceRequestMsg)
+ case msgServiceAccept:
+ msg = new(serviceAcceptMsg)
+ case msgExtInfo:
+ msg = new(extInfoMsg)
+ case msgKexInit:
+ msg = new(kexInitMsg)
+ case msgKexDHInit:
+ msg = new(kexDHInitMsg)
+ case msgKexDHReply:
+ msg = new(kexDHReplyMsg)
+ case msgUserAuthRequest:
+ msg = new(userAuthRequestMsg)
+ case msgUserAuthSuccess:
+ return new(userAuthSuccessMsg), nil
+ case msgUserAuthFailure:
+ msg = new(userAuthFailureMsg)
+ case msgUserAuthPubKeyOk:
+ msg = new(userAuthPubKeyOkMsg)
+ case msgGlobalRequest:
+ msg = new(globalRequestMsg)
+ case msgRequestSuccess:
+ msg = new(globalRequestSuccessMsg)
+ case msgRequestFailure:
+ msg = new(globalRequestFailureMsg)
+ case msgChannelOpen:
+ msg = new(channelOpenMsg)
+ case msgChannelData:
+ msg = new(channelDataMsg)
+ case msgChannelOpenConfirm:
+ msg = new(channelOpenConfirmMsg)
+ case msgChannelOpenFailure:
+ msg = new(channelOpenFailureMsg)
+ case msgChannelWindowAdjust:
+ msg = new(windowAdjustMsg)
+ case msgChannelEOF:
+ msg = new(channelEOFMsg)
+ case msgChannelClose:
+ msg = new(channelCloseMsg)
+ case msgChannelRequest:
+ msg = new(channelRequestMsg)
+ case msgChannelSuccess:
+ msg = new(channelRequestSuccessMsg)
+ case msgChannelFailure:
+ msg = new(channelRequestFailureMsg)
+ case msgUserAuthGSSAPIToken:
+ msg = new(userAuthGSSAPIToken)
+ case msgUserAuthGSSAPIMIC:
+ msg = new(userAuthGSSAPIMIC)
+ case msgUserAuthGSSAPIErrTok:
+ msg = new(userAuthGSSAPIErrTok)
+ case msgUserAuthGSSAPIError:
+ msg = new(userAuthGSSAPIError)
+ default:
+ return nil, unexpectedMessageError(0, packet[0])
+ }
+ if err := Unmarshal(packet, msg); err != nil {
+ return nil, err
+ }
+ return msg, nil
+}
+
+var packetTypeNames = map[byte]string{
+ msgDisconnect: "disconnectMsg",
+ msgServiceRequest: "serviceRequestMsg",
+ msgServiceAccept: "serviceAcceptMsg",
+ msgExtInfo: "extInfoMsg",
+ msgKexInit: "kexInitMsg",
+ msgKexDHInit: "kexDHInitMsg",
+ msgKexDHReply: "kexDHReplyMsg",
+ msgUserAuthRequest: "userAuthRequestMsg",
+ msgUserAuthSuccess: "userAuthSuccessMsg",
+ msgUserAuthFailure: "userAuthFailureMsg",
+ msgUserAuthPubKeyOk: "userAuthPubKeyOkMsg",
+ msgGlobalRequest: "globalRequestMsg",
+ msgRequestSuccess: "globalRequestSuccessMsg",
+ msgRequestFailure: "globalRequestFailureMsg",
+ msgChannelOpen: "channelOpenMsg",
+ msgChannelData: "channelDataMsg",
+ msgChannelOpenConfirm: "channelOpenConfirmMsg",
+ msgChannelOpenFailure: "channelOpenFailureMsg",
+ msgChannelWindowAdjust: "windowAdjustMsg",
+ msgChannelEOF: "channelEOFMsg",
+ msgChannelClose: "channelCloseMsg",
+ msgChannelRequest: "channelRequestMsg",
+ msgChannelSuccess: "channelRequestSuccessMsg",
+ msgChannelFailure: "channelRequestFailureMsg",
+}
diff --git a/vendor/golang.org/x/crypto/ssh/mux.go b/vendor/golang.org/x/crypto/ssh/mux.go
new file mode 100644
index 00000000..d2d24c63
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/mux.go
@@ -0,0 +1,357 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "encoding/binary"
+ "fmt"
+ "io"
+ "log"
+ "sync"
+ "sync/atomic"
+)
+
+// debugMux, if set, causes messages in the connection protocol to be
+// logged.
+const debugMux = false
+
+// chanList is a thread safe channel list.
+type chanList struct {
+ // protects concurrent access to chans
+ sync.Mutex
+
+ // chans are indexed by the local id of the channel, which the
+ // other side should send in the PeersId field.
+ chans []*channel
+
+ // This is a debugging aid: it offsets all IDs by this
+ // amount. This helps distinguish otherwise identical
+ // server/client muxes
+ offset uint32
+}
+
+// Assigns a channel ID to the given channel.
+func (c *chanList) add(ch *channel) uint32 {
+ c.Lock()
+ defer c.Unlock()
+ for i := range c.chans {
+ if c.chans[i] == nil {
+ c.chans[i] = ch
+ return uint32(i) + c.offset
+ }
+ }
+ c.chans = append(c.chans, ch)
+ return uint32(len(c.chans)-1) + c.offset
+}
+
+// getChan returns the channel for the given ID.
+func (c *chanList) getChan(id uint32) *channel {
+ id -= c.offset
+
+ c.Lock()
+ defer c.Unlock()
+ if id < uint32(len(c.chans)) {
+ return c.chans[id]
+ }
+ return nil
+}
+
+func (c *chanList) remove(id uint32) {
+ id -= c.offset
+ c.Lock()
+ if id < uint32(len(c.chans)) {
+ c.chans[id] = nil
+ }
+ c.Unlock()
+}
+
+// dropAll forgets all channels it knows, returning them in a slice.
+func (c *chanList) dropAll() []*channel {
+ c.Lock()
+ defer c.Unlock()
+ var r []*channel
+
+ for _, ch := range c.chans {
+ if ch == nil {
+ continue
+ }
+ r = append(r, ch)
+ }
+ c.chans = nil
+ return r
+}
+
+// mux represents the state for the SSH connection protocol, which
+// multiplexes many channels onto a single packet transport.
+type mux struct {
+ conn packetConn
+ chanList chanList
+
+ incomingChannels chan NewChannel
+
+ globalSentMu sync.Mutex
+ globalResponses chan interface{}
+ incomingRequests chan *Request
+
+ errCond *sync.Cond
+ err error
+}
+
+// When debugging, each new chanList instantiation has a different
+// offset.
+var globalOff uint32
+
+func (m *mux) Wait() error {
+ m.errCond.L.Lock()
+ defer m.errCond.L.Unlock()
+ for m.err == nil {
+ m.errCond.Wait()
+ }
+ return m.err
+}
+
+// newMux returns a mux that runs over the given connection.
+func newMux(p packetConn) *mux {
+ m := &mux{
+ conn: p,
+ incomingChannels: make(chan NewChannel, chanSize),
+ globalResponses: make(chan interface{}, 1),
+ incomingRequests: make(chan *Request, chanSize),
+ errCond: newCond(),
+ }
+ if debugMux {
+ m.chanList.offset = atomic.AddUint32(&globalOff, 1)
+ }
+
+ go m.loop()
+ return m
+}
+
+func (m *mux) sendMessage(msg interface{}) error {
+ p := Marshal(msg)
+ if debugMux {
+ log.Printf("send global(%d): %#v", m.chanList.offset, msg)
+ }
+ return m.conn.writePacket(p)
+}
+
+func (m *mux) SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) {
+ if wantReply {
+ m.globalSentMu.Lock()
+ defer m.globalSentMu.Unlock()
+ }
+
+ if err := m.sendMessage(globalRequestMsg{
+ Type: name,
+ WantReply: wantReply,
+ Data: payload,
+ }); err != nil {
+ return false, nil, err
+ }
+
+ if !wantReply {
+ return false, nil, nil
+ }
+
+ msg, ok := <-m.globalResponses
+ if !ok {
+ return false, nil, io.EOF
+ }
+ switch msg := msg.(type) {
+ case *globalRequestFailureMsg:
+ return false, msg.Data, nil
+ case *globalRequestSuccessMsg:
+ return true, msg.Data, nil
+ default:
+ return false, nil, fmt.Errorf("ssh: unexpected response to request: %#v", msg)
+ }
+}
+
+// ackRequest must be called after processing a global request that
+// has WantReply set.
+func (m *mux) ackRequest(ok bool, data []byte) error {
+ if ok {
+ return m.sendMessage(globalRequestSuccessMsg{Data: data})
+ }
+ return m.sendMessage(globalRequestFailureMsg{Data: data})
+}
+
+func (m *mux) Close() error {
+ return m.conn.Close()
+}
+
+// loop runs the connection machine. It will process packets until an
+// error is encountered. To synchronize on loop exit, use mux.Wait.
+func (m *mux) loop() {
+ var err error
+ for err == nil {
+ err = m.onePacket()
+ }
+
+ for _, ch := range m.chanList.dropAll() {
+ ch.close()
+ }
+
+ close(m.incomingChannels)
+ close(m.incomingRequests)
+ close(m.globalResponses)
+
+ m.conn.Close()
+
+ m.errCond.L.Lock()
+ m.err = err
+ m.errCond.Broadcast()
+ m.errCond.L.Unlock()
+
+ if debugMux {
+ log.Println("loop exit", err)
+ }
+}
+
+// onePacket reads and processes one packet.
+func (m *mux) onePacket() error {
+ packet, err := m.conn.readPacket()
+ if err != nil {
+ return err
+ }
+
+ if debugMux {
+ if packet[0] == msgChannelData || packet[0] == msgChannelExtendedData {
+ log.Printf("decoding(%d): data packet - %d bytes", m.chanList.offset, len(packet))
+ } else {
+ p, _ := decode(packet)
+ log.Printf("decoding(%d): %d %#v - %d bytes", m.chanList.offset, packet[0], p, len(packet))
+ }
+ }
+
+ switch packet[0] {
+ case msgChannelOpen:
+ return m.handleChannelOpen(packet)
+ case msgGlobalRequest, msgRequestSuccess, msgRequestFailure:
+ return m.handleGlobalPacket(packet)
+ case msgPing:
+ var msg pingMsg
+ if err := Unmarshal(packet, &msg); err != nil {
+ return fmt.Errorf("failed to unmarshal ping@openssh.com message: %w", err)
+ }
+ return m.sendMessage(pongMsg(msg))
+ }
+
+ // assume a channel packet.
+ if len(packet) < 5 {
+ return parseError(packet[0])
+ }
+ id := binary.BigEndian.Uint32(packet[1:])
+ ch := m.chanList.getChan(id)
+ if ch == nil {
+ return m.handleUnknownChannelPacket(id, packet)
+ }
+
+ return ch.handlePacket(packet)
+}
+
+func (m *mux) handleGlobalPacket(packet []byte) error {
+ msg, err := decode(packet)
+ if err != nil {
+ return err
+ }
+
+ switch msg := msg.(type) {
+ case *globalRequestMsg:
+ m.incomingRequests <- &Request{
+ Type: msg.Type,
+ WantReply: msg.WantReply,
+ Payload: msg.Data,
+ mux: m,
+ }
+ case *globalRequestSuccessMsg, *globalRequestFailureMsg:
+ m.globalResponses <- msg
+ default:
+ panic(fmt.Sprintf("not a global message %#v", msg))
+ }
+
+ return nil
+}
+
+// handleChannelOpen schedules a channel to be Accept()ed.
+func (m *mux) handleChannelOpen(packet []byte) error {
+ var msg channelOpenMsg
+ if err := Unmarshal(packet, &msg); err != nil {
+ return err
+ }
+
+ if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
+ failMsg := channelOpenFailureMsg{
+ PeersID: msg.PeersID,
+ Reason: ConnectionFailed,
+ Message: "invalid request",
+ Language: "en_US.UTF-8",
+ }
+ return m.sendMessage(failMsg)
+ }
+
+ c := m.newChannel(msg.ChanType, channelInbound, msg.TypeSpecificData)
+ c.remoteId = msg.PeersID
+ c.maxRemotePayload = msg.MaxPacketSize
+ c.remoteWin.add(msg.PeersWindow)
+ m.incomingChannels <- c
+ return nil
+}
+
+func (m *mux) OpenChannel(chanType string, extra []byte) (Channel, <-chan *Request, error) {
+ ch, err := m.openChannel(chanType, extra)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return ch, ch.incomingRequests, nil
+}
+
+func (m *mux) openChannel(chanType string, extra []byte) (*channel, error) {
+ ch := m.newChannel(chanType, channelOutbound, extra)
+
+ ch.maxIncomingPayload = channelMaxPacket
+
+ open := channelOpenMsg{
+ ChanType: chanType,
+ PeersWindow: ch.myWindow,
+ MaxPacketSize: ch.maxIncomingPayload,
+ TypeSpecificData: extra,
+ PeersID: ch.localId,
+ }
+ if err := m.sendMessage(open); err != nil {
+ return nil, err
+ }
+
+ switch msg := (<-ch.msg).(type) {
+ case *channelOpenConfirmMsg:
+ return ch, nil
+ case *channelOpenFailureMsg:
+ return nil, &OpenChannelError{msg.Reason, msg.Message}
+ default:
+ return nil, fmt.Errorf("ssh: unexpected packet in response to channel open: %T", msg)
+ }
+}
+
+func (m *mux) handleUnknownChannelPacket(id uint32, packet []byte) error {
+ msg, err := decode(packet)
+ if err != nil {
+ return err
+ }
+
+ switch msg := msg.(type) {
+ // RFC 4254 section 5.4 says unrecognized channel requests should
+ // receive a failure response.
+ case *channelRequestMsg:
+ if msg.WantReply {
+ return m.sendMessage(channelRequestFailureMsg{
+ PeersID: msg.PeersID,
+ })
+ }
+ return nil
+ default:
+ return fmt.Errorf("ssh: invalid channel %d", id)
+ }
+}
diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go
new file mode 100644
index 00000000..3ca9e89e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/server.go
@@ -0,0 +1,902 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "strings"
+)
+
+// The Permissions type holds fine-grained permissions that are
+// specific to a user or a specific authentication method for a user.
+// The Permissions value for a successful authentication attempt is
+// available in ServerConn, so it can be used to pass information from
+// the user-authentication phase to the application layer.
+type Permissions struct {
+ // CriticalOptions indicate restrictions to the default
+ // permissions, and are typically used in conjunction with
+ // user certificates. The standard for SSH certificates
+ // defines "force-command" (only allow the given command to
+ // execute) and "source-address" (only allow connections from
+ // the given address). The SSH package currently only enforces
+ // the "source-address" critical option. It is up to server
+ // implementations to enforce other critical options, such as
+ // "force-command", by checking them after the SSH handshake
+ // is successful. In general, SSH servers should reject
+ // connections that specify critical options that are unknown
+ // or not supported.
+ CriticalOptions map[string]string
+
+ // Extensions are extra functionality that the server may
+ // offer on authenticated connections. Lack of support for an
+ // extension does not preclude authenticating a user. Common
+ // extensions are "permit-agent-forwarding",
+ // "permit-X11-forwarding". The Go SSH library currently does
+ // not act on any extension, and it is up to server
+ // implementations to honor them. Extensions can be used to
+ // pass data from the authentication callbacks to the server
+ // application layer.
+ Extensions map[string]string
+}
+
+type GSSAPIWithMICConfig struct {
+ // AllowLogin, must be set, is called when gssapi-with-mic
+ // authentication is selected (RFC 4462 section 3). The srcName is from the
+ // results of the GSS-API authentication. The format is username@DOMAIN.
+ // GSSAPI just guarantees to the server who the user is, but not if they can log in, and with what permissions.
+ // This callback is called after the user identity is established with GSSAPI to decide if the user can login with
+ // which permissions. If the user is allowed to login, it should return a nil error.
+ AllowLogin func(conn ConnMetadata, srcName string) (*Permissions, error)
+
+ // Server must be set. It's the implementation
+ // of the GSSAPIServer interface. See GSSAPIServer interface for details.
+ Server GSSAPIServer
+}
+
+// ServerConfig holds server specific configuration data.
+type ServerConfig struct {
+ // Config contains configuration shared between client and server.
+ Config
+
+ // PublicKeyAuthAlgorithms specifies the supported client public key
+ // authentication algorithms. Note that this should not include certificate
+ // types since those use the underlying algorithm. This list is sent to the
+ // client if it supports the server-sig-algs extension. Order is irrelevant.
+ // If unspecified then a default set of algorithms is used.
+ PublicKeyAuthAlgorithms []string
+
+ hostKeys []Signer
+
+ // NoClientAuth is true if clients are allowed to connect without
+ // authenticating.
+ // To determine NoClientAuth at runtime, set NoClientAuth to true
+ // and the optional NoClientAuthCallback to a non-nil value.
+ NoClientAuth bool
+
+ // NoClientAuthCallback, if non-nil, is called when a user
+ // attempts to authenticate with auth method "none".
+ // NoClientAuth must also be set to true for this be used, or
+ // this func is unused.
+ NoClientAuthCallback func(ConnMetadata) (*Permissions, error)
+
+ // MaxAuthTries specifies the maximum number of authentication attempts
+ // permitted per connection. If set to a negative number, the number of
+ // attempts are unlimited. If set to zero, the number of attempts are limited
+ // to 6.
+ MaxAuthTries int
+
+ // PasswordCallback, if non-nil, is called when a user
+ // attempts to authenticate using a password.
+ PasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error)
+
+ // PublicKeyCallback, if non-nil, is called when a client
+ // offers a public key for authentication. It must return a nil error
+ // if the given public key can be used to authenticate the
+ // given user. For example, see CertChecker.Authenticate. A
+ // call to this function does not guarantee that the key
+ // offered is in fact used to authenticate. To record any data
+ // depending on the public key, store it inside a
+ // Permissions.Extensions entry.
+ PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
+
+ // KeyboardInteractiveCallback, if non-nil, is called when
+ // keyboard-interactive authentication is selected (RFC
+ // 4256). The client object's Challenge function should be
+ // used to query the user. The callback may offer multiple
+ // Challenge rounds. To avoid information leaks, the client
+ // should be presented a challenge even if the user is
+ // unknown.
+ KeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Permissions, error)
+
+ // AuthLogCallback, if non-nil, is called to log all authentication
+ // attempts.
+ AuthLogCallback func(conn ConnMetadata, method string, err error)
+
+ // ServerVersion is the version identification string to announce in
+ // the public handshake.
+ // If empty, a reasonable default is used.
+ // Note that RFC 4253 section 4.2 requires that this string start with
+ // "SSH-2.0-".
+ ServerVersion string
+
+ // BannerCallback, if present, is called and the return string is sent to
+ // the client after key exchange completed but before authentication.
+ BannerCallback func(conn ConnMetadata) string
+
+ // GSSAPIWithMICConfig includes gssapi server and callback, which if both non-nil, is used
+ // when gssapi-with-mic authentication is selected (RFC 4462 section 3).
+ GSSAPIWithMICConfig *GSSAPIWithMICConfig
+}
+
+// AddHostKey adds a private key as a host key. If an existing host
+// key exists with the same public key format, it is replaced. Each server
+// config must have at least one host key.
+func (s *ServerConfig) AddHostKey(key Signer) {
+ for i, k := range s.hostKeys {
+ if k.PublicKey().Type() == key.PublicKey().Type() {
+ s.hostKeys[i] = key
+ return
+ }
+ }
+
+ s.hostKeys = append(s.hostKeys, key)
+}
+
+// cachedPubKey contains the results of querying whether a public key is
+// acceptable for a user.
+type cachedPubKey struct {
+ user string
+ pubKeyData []byte
+ result error
+ perms *Permissions
+}
+
+const maxCachedPubKeys = 16
+
+// pubKeyCache caches tests for public keys. Since SSH clients
+// will query whether a public key is acceptable before attempting to
+// authenticate with it, we end up with duplicate queries for public
+// key validity. The cache only applies to a single ServerConn.
+type pubKeyCache struct {
+ keys []cachedPubKey
+}
+
+// get returns the result for a given user/algo/key tuple.
+func (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) {
+ for _, k := range c.keys {
+ if k.user == user && bytes.Equal(k.pubKeyData, pubKeyData) {
+ return k, true
+ }
+ }
+ return cachedPubKey{}, false
+}
+
+// add adds the given tuple to the cache.
+func (c *pubKeyCache) add(candidate cachedPubKey) {
+ if len(c.keys) < maxCachedPubKeys {
+ c.keys = append(c.keys, candidate)
+ }
+}
+
+// ServerConn is an authenticated SSH connection, as seen from the
+// server
+type ServerConn struct {
+ Conn
+
+ // If the succeeding authentication callback returned a
+ // non-nil Permissions pointer, it is stored here.
+ Permissions *Permissions
+}
+
+// NewServerConn starts a new SSH server with c as the underlying
+// transport. It starts with a handshake and, if the handshake is
+// unsuccessful, it closes the connection and returns an error. The
+// Request and NewChannel channels must be serviced, or the connection
+// will hang.
+//
+// The returned error may be of type *ServerAuthError for
+// authentication errors.
+func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewChannel, <-chan *Request, error) {
+ fullConf := *config
+ fullConf.SetDefaults()
+ if fullConf.MaxAuthTries == 0 {
+ fullConf.MaxAuthTries = 6
+ }
+ if len(fullConf.PublicKeyAuthAlgorithms) == 0 {
+ fullConf.PublicKeyAuthAlgorithms = supportedPubKeyAuthAlgos
+ } else {
+ for _, algo := range fullConf.PublicKeyAuthAlgorithms {
+ if !contains(supportedPubKeyAuthAlgos, algo) {
+ c.Close()
+ return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo)
+ }
+ }
+ }
+ // Check if the config contains any unsupported key exchanges
+ for _, kex := range fullConf.KeyExchanges {
+ if _, ok := serverForbiddenKexAlgos[kex]; ok {
+ c.Close()
+ return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex)
+ }
+ }
+
+ s := &connection{
+ sshConn: sshConn{conn: c},
+ }
+ perms, err := s.serverHandshake(&fullConf)
+ if err != nil {
+ c.Close()
+ return nil, nil, nil, err
+ }
+ return &ServerConn{s, perms}, s.mux.incomingChannels, s.mux.incomingRequests, nil
+}
+
+// signAndMarshal signs the data with the appropriate algorithm,
+// and serializes the result in SSH wire format. algo is the negotiate
+// algorithm and may be a certificate type.
+func signAndMarshal(k AlgorithmSigner, rand io.Reader, data []byte, algo string) ([]byte, error) {
+ sig, err := k.SignWithAlgorithm(rand, data, underlyingAlgo(algo))
+ if err != nil {
+ return nil, err
+ }
+
+ return Marshal(sig), nil
+}
+
+// handshake performs key exchange and user authentication.
+func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) {
+ if len(config.hostKeys) == 0 {
+ return nil, errors.New("ssh: server has no host keys")
+ }
+
+ if !config.NoClientAuth && config.PasswordCallback == nil && config.PublicKeyCallback == nil &&
+ config.KeyboardInteractiveCallback == nil && (config.GSSAPIWithMICConfig == nil ||
+ config.GSSAPIWithMICConfig.AllowLogin == nil || config.GSSAPIWithMICConfig.Server == nil) {
+ return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
+ }
+
+ if config.ServerVersion != "" {
+ s.serverVersion = []byte(config.ServerVersion)
+ } else {
+ s.serverVersion = []byte(packageVersion)
+ }
+ var err error
+ s.clientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion)
+ if err != nil {
+ return nil, err
+ }
+
+ tr := newTransport(s.sshConn.conn, config.Rand, false /* not client */)
+ s.transport = newServerTransport(tr, s.clientVersion, s.serverVersion, config)
+
+ if err := s.transport.waitSession(); err != nil {
+ return nil, err
+ }
+
+ // We just did the key change, so the session ID is established.
+ s.sessionID = s.transport.getSessionID()
+
+ var packet []byte
+ if packet, err = s.transport.readPacket(); err != nil {
+ return nil, err
+ }
+
+ var serviceRequest serviceRequestMsg
+ if err = Unmarshal(packet, &serviceRequest); err != nil {
+ return nil, err
+ }
+ if serviceRequest.Service != serviceUserAuth {
+ return nil, errors.New("ssh: requested service '" + serviceRequest.Service + "' before authenticating")
+ }
+ serviceAccept := serviceAcceptMsg{
+ Service: serviceUserAuth,
+ }
+ if err := s.transport.writePacket(Marshal(&serviceAccept)); err != nil {
+ return nil, err
+ }
+
+ perms, err := s.serverAuthenticate(config)
+ if err != nil {
+ return nil, err
+ }
+ s.mux = newMux(s.transport)
+ return perms, err
+}
+
+func checkSourceAddress(addr net.Addr, sourceAddrs string) error {
+ if addr == nil {
+ return errors.New("ssh: no address known for client, but source-address match required")
+ }
+
+ tcpAddr, ok := addr.(*net.TCPAddr)
+ if !ok {
+ return fmt.Errorf("ssh: remote address %v is not an TCP address when checking source-address match", addr)
+ }
+
+ for _, sourceAddr := range strings.Split(sourceAddrs, ",") {
+ if allowedIP := net.ParseIP(sourceAddr); allowedIP != nil {
+ if allowedIP.Equal(tcpAddr.IP) {
+ return nil
+ }
+ } else {
+ _, ipNet, err := net.ParseCIDR(sourceAddr)
+ if err != nil {
+ return fmt.Errorf("ssh: error parsing source-address restriction %q: %v", sourceAddr, err)
+ }
+
+ if ipNet.Contains(tcpAddr.IP) {
+ return nil
+ }
+ }
+ }
+
+ return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr)
+}
+
+func gssExchangeToken(gssapiConfig *GSSAPIWithMICConfig, token []byte, s *connection,
+ sessionID []byte, userAuthReq userAuthRequestMsg) (authErr error, perms *Permissions, err error) {
+ gssAPIServer := gssapiConfig.Server
+ defer gssAPIServer.DeleteSecContext()
+ var srcName string
+ for {
+ var (
+ outToken []byte
+ needContinue bool
+ )
+ outToken, srcName, needContinue, err = gssAPIServer.AcceptSecContext(token)
+ if err != nil {
+ return err, nil, nil
+ }
+ if len(outToken) != 0 {
+ if err := s.transport.writePacket(Marshal(&userAuthGSSAPIToken{
+ Token: outToken,
+ })); err != nil {
+ return nil, nil, err
+ }
+ }
+ if !needContinue {
+ break
+ }
+ packet, err := s.transport.readPacket()
+ if err != nil {
+ return nil, nil, err
+ }
+ userAuthGSSAPITokenReq := &userAuthGSSAPIToken{}
+ if err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {
+ return nil, nil, err
+ }
+ token = userAuthGSSAPITokenReq.Token
+ }
+ packet, err := s.transport.readPacket()
+ if err != nil {
+ return nil, nil, err
+ }
+ userAuthGSSAPIMICReq := &userAuthGSSAPIMIC{}
+ if err := Unmarshal(packet, userAuthGSSAPIMICReq); err != nil {
+ return nil, nil, err
+ }
+ mic := buildMIC(string(sessionID), userAuthReq.User, userAuthReq.Service, userAuthReq.Method)
+ if err := gssAPIServer.VerifyMIC(mic, userAuthGSSAPIMICReq.MIC); err != nil {
+ return err, nil, nil
+ }
+ perms, authErr = gssapiConfig.AllowLogin(s, srcName)
+ return authErr, perms, nil
+}
+
+// isAlgoCompatible checks if the signature format is compatible with the
+// selected algorithm taking into account edge cases that occur with old
+// clients.
+func isAlgoCompatible(algo, sigFormat string) bool {
+ // Compatibility for old clients.
+ //
+ // For certificate authentication with OpenSSH 7.2-7.7 signature format can
+ // be rsa-sha2-256 or rsa-sha2-512 for the algorithm
+ // ssh-rsa-cert-v01@openssh.com.
+ //
+ // With gpg-agent < 2.2.6 the algorithm can be rsa-sha2-256 or rsa-sha2-512
+ // for signature format ssh-rsa.
+ if isRSA(algo) && isRSA(sigFormat) {
+ return true
+ }
+ // Standard case: the underlying algorithm must match the signature format.
+ return underlyingAlgo(algo) == sigFormat
+}
+
+// ServerAuthError represents server authentication errors and is
+// sometimes returned by NewServerConn. It appends any authentication
+// errors that may occur, and is returned if all of the authentication
+// methods provided by the user failed to authenticate.
+type ServerAuthError struct {
+ // Errors contains authentication errors returned by the authentication
+ // callback methods. The first entry is typically ErrNoAuth.
+ Errors []error
+}
+
+func (l ServerAuthError) Error() string {
+ var errs []string
+ for _, err := range l.Errors {
+ errs = append(errs, err.Error())
+ }
+ return "[" + strings.Join(errs, ", ") + "]"
+}
+
+// ServerAuthCallbacks defines server-side authentication callbacks.
+type ServerAuthCallbacks struct {
+ // PasswordCallback behaves like [ServerConfig.PasswordCallback].
+ PasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error)
+
+ // PublicKeyCallback behaves like [ServerConfig.PublicKeyCallback].
+ PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
+
+ // KeyboardInteractiveCallback behaves like [ServerConfig.KeyboardInteractiveCallback].
+ KeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Permissions, error)
+
+ // GSSAPIWithMICConfig behaves like [ServerConfig.GSSAPIWithMICConfig].
+ GSSAPIWithMICConfig *GSSAPIWithMICConfig
+}
+
+// PartialSuccessError can be returned by any of the [ServerConfig]
+// authentication callbacks to indicate to the client that authentication has
+// partially succeeded, but further steps are required.
+type PartialSuccessError struct {
+ // Next defines the authentication callbacks to apply to further steps. The
+ // available methods communicated to the client are based on the non-nil
+ // ServerAuthCallbacks fields.
+ Next ServerAuthCallbacks
+}
+
+func (p *PartialSuccessError) Error() string {
+ return "ssh: authenticated with partial success"
+}
+
+// ErrNoAuth is the error value returned if no
+// authentication method has been passed yet. This happens as a normal
+// part of the authentication loop, since the client first tries
+// 'none' authentication to discover available methods.
+// It is returned in ServerAuthError.Errors from NewServerConn.
+var ErrNoAuth = errors.New("ssh: no auth passed yet")
+
+// BannerError is an error that can be returned by authentication handlers in
+// ServerConfig to send a banner message to the client.
+type BannerError struct {
+ Err error
+ Message string
+}
+
+func (b *BannerError) Unwrap() error {
+ return b.Err
+}
+
+func (b *BannerError) Error() string {
+ if b.Err == nil {
+ return b.Message
+ }
+ return b.Err.Error()
+}
+
+func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
+ sessionID := s.transport.getSessionID()
+ var cache pubKeyCache
+ var perms *Permissions
+
+ authFailures := 0
+ noneAuthCount := 0
+ var authErrs []error
+ var displayedBanner bool
+ partialSuccessReturned := false
+ // Set the initial authentication callbacks from the config. They can be
+ // changed if a PartialSuccessError is returned.
+ authConfig := ServerAuthCallbacks{
+ PasswordCallback: config.PasswordCallback,
+ PublicKeyCallback: config.PublicKeyCallback,
+ KeyboardInteractiveCallback: config.KeyboardInteractiveCallback,
+ GSSAPIWithMICConfig: config.GSSAPIWithMICConfig,
+ }
+
+userAuthLoop:
+ for {
+ if authFailures >= config.MaxAuthTries && config.MaxAuthTries > 0 {
+ discMsg := &disconnectMsg{
+ Reason: 2,
+ Message: "too many authentication failures",
+ }
+
+ if err := s.transport.writePacket(Marshal(discMsg)); err != nil {
+ return nil, err
+ }
+
+ return nil, discMsg
+ }
+
+ var userAuthReq userAuthRequestMsg
+ if packet, err := s.transport.readPacket(); err != nil {
+ if err == io.EOF {
+ return nil, &ServerAuthError{Errors: authErrs}
+ }
+ return nil, err
+ } else if err = Unmarshal(packet, &userAuthReq); err != nil {
+ return nil, err
+ }
+
+ if userAuthReq.Service != serviceSSH {
+ return nil, errors.New("ssh: client attempted to negotiate for unknown service: " + userAuthReq.Service)
+ }
+
+ if s.user != userAuthReq.User && partialSuccessReturned {
+ return nil, fmt.Errorf("ssh: client changed the user after a partial success authentication, previous user %q, current user %q",
+ s.user, userAuthReq.User)
+ }
+
+ s.user = userAuthReq.User
+
+ if !displayedBanner && config.BannerCallback != nil {
+ displayedBanner = true
+ msg := config.BannerCallback(s)
+ if msg != "" {
+ bannerMsg := &userAuthBannerMsg{
+ Message: msg,
+ }
+ if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ perms = nil
+ authErr := ErrNoAuth
+
+ switch userAuthReq.Method {
+ case "none":
+ noneAuthCount++
+ // We don't allow none authentication after a partial success
+ // response.
+ if config.NoClientAuth && !partialSuccessReturned {
+ if config.NoClientAuthCallback != nil {
+ perms, authErr = config.NoClientAuthCallback(s)
+ } else {
+ authErr = nil
+ }
+ }
+ case "password":
+ if authConfig.PasswordCallback == nil {
+ authErr = errors.New("ssh: password auth not configured")
+ break
+ }
+ payload := userAuthReq.Payload
+ if len(payload) < 1 || payload[0] != 0 {
+ return nil, parseError(msgUserAuthRequest)
+ }
+ payload = payload[1:]
+ password, payload, ok := parseString(payload)
+ if !ok || len(payload) > 0 {
+ return nil, parseError(msgUserAuthRequest)
+ }
+
+ perms, authErr = authConfig.PasswordCallback(s, password)
+ case "keyboard-interactive":
+ if authConfig.KeyboardInteractiveCallback == nil {
+ authErr = errors.New("ssh: keyboard-interactive auth not configured")
+ break
+ }
+
+ prompter := &sshClientKeyboardInteractive{s}
+ perms, authErr = authConfig.KeyboardInteractiveCallback(s, prompter.Challenge)
+ case "publickey":
+ if authConfig.PublicKeyCallback == nil {
+ authErr = errors.New("ssh: publickey auth not configured")
+ break
+ }
+ payload := userAuthReq.Payload
+ if len(payload) < 1 {
+ return nil, parseError(msgUserAuthRequest)
+ }
+ isQuery := payload[0] == 0
+ payload = payload[1:]
+ algoBytes, payload, ok := parseString(payload)
+ if !ok {
+ return nil, parseError(msgUserAuthRequest)
+ }
+ algo := string(algoBytes)
+ if !contains(config.PublicKeyAuthAlgorithms, underlyingAlgo(algo)) {
+ authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo)
+ break
+ }
+
+ pubKeyData, payload, ok := parseString(payload)
+ if !ok {
+ return nil, parseError(msgUserAuthRequest)
+ }
+
+ pubKey, err := ParsePublicKey(pubKeyData)
+ if err != nil {
+ return nil, err
+ }
+
+ candidate, ok := cache.get(s.user, pubKeyData)
+ if !ok {
+ candidate.user = s.user
+ candidate.pubKeyData = pubKeyData
+ candidate.perms, candidate.result = authConfig.PublicKeyCallback(s, pubKey)
+ _, isPartialSuccessError := candidate.result.(*PartialSuccessError)
+
+ if (candidate.result == nil || isPartialSuccessError) &&
+ candidate.perms != nil &&
+ candidate.perms.CriticalOptions != nil &&
+ candidate.perms.CriticalOptions[sourceAddressCriticalOption] != "" {
+ if err := checkSourceAddress(
+ s.RemoteAddr(),
+ candidate.perms.CriticalOptions[sourceAddressCriticalOption]); err != nil {
+ candidate.result = err
+ }
+ }
+ cache.add(candidate)
+ }
+
+ if isQuery {
+ // The client can query if the given public key
+ // would be okay.
+
+ if len(payload) > 0 {
+ return nil, parseError(msgUserAuthRequest)
+ }
+ _, isPartialSuccessError := candidate.result.(*PartialSuccessError)
+ if candidate.result == nil || isPartialSuccessError {
+ okMsg := userAuthPubKeyOkMsg{
+ Algo: algo,
+ PubKey: pubKeyData,
+ }
+ if err = s.transport.writePacket(Marshal(&okMsg)); err != nil {
+ return nil, err
+ }
+ continue userAuthLoop
+ }
+ authErr = candidate.result
+ } else {
+ sig, payload, ok := parseSignature(payload)
+ if !ok || len(payload) > 0 {
+ return nil, parseError(msgUserAuthRequest)
+ }
+ // Ensure the declared public key algo is compatible with the
+ // decoded one. This check will ensure we don't accept e.g.
+ // ssh-rsa-cert-v01@openssh.com algorithm with ssh-rsa public
+ // key type. The algorithm and public key type must be
+ // consistent: both must be certificate algorithms, or neither.
+ if !contains(algorithmsForKeyFormat(pubKey.Type()), algo) {
+ authErr = fmt.Errorf("ssh: public key type %q not compatible with selected algorithm %q",
+ pubKey.Type(), algo)
+ break
+ }
+ // Ensure the public key algo and signature algo
+ // are supported. Compare the private key
+ // algorithm name that corresponds to algo with
+ // sig.Format. This is usually the same, but
+ // for certs, the names differ.
+ if !contains(config.PublicKeyAuthAlgorithms, sig.Format) {
+ authErr = fmt.Errorf("ssh: algorithm %q not accepted", sig.Format)
+ break
+ }
+ if !isAlgoCompatible(algo, sig.Format) {
+ authErr = fmt.Errorf("ssh: signature %q not compatible with selected algorithm %q", sig.Format, algo)
+ break
+ }
+
+ signedData := buildDataSignedForAuth(sessionID, userAuthReq, algo, pubKeyData)
+
+ if err := pubKey.Verify(signedData, sig); err != nil {
+ return nil, err
+ }
+
+ authErr = candidate.result
+ perms = candidate.perms
+ }
+ case "gssapi-with-mic":
+ if authConfig.GSSAPIWithMICConfig == nil {
+ authErr = errors.New("ssh: gssapi-with-mic auth not configured")
+ break
+ }
+ gssapiConfig := authConfig.GSSAPIWithMICConfig
+ userAuthRequestGSSAPI, err := parseGSSAPIPayload(userAuthReq.Payload)
+ if err != nil {
+ return nil, parseError(msgUserAuthRequest)
+ }
+ // OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication.
+ if userAuthRequestGSSAPI.N == 0 {
+ authErr = fmt.Errorf("ssh: Mechanism negotiation is not supported")
+ break
+ }
+ var i uint32
+ present := false
+ for i = 0; i < userAuthRequestGSSAPI.N; i++ {
+ if userAuthRequestGSSAPI.OIDS[i].Equal(krb5Mesh) {
+ present = true
+ break
+ }
+ }
+ if !present {
+ authErr = fmt.Errorf("ssh: GSSAPI authentication must use the Kerberos V5 mechanism")
+ break
+ }
+ // Initial server response, see RFC 4462 section 3.3.
+ if err := s.transport.writePacket(Marshal(&userAuthGSSAPIResponse{
+ SupportMech: krb5OID,
+ })); err != nil {
+ return nil, err
+ }
+ // Exchange token, see RFC 4462 section 3.4.
+ packet, err := s.transport.readPacket()
+ if err != nil {
+ return nil, err
+ }
+ userAuthGSSAPITokenReq := &userAuthGSSAPIToken{}
+ if err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {
+ return nil, err
+ }
+ authErr, perms, err = gssExchangeToken(gssapiConfig, userAuthGSSAPITokenReq.Token, s, sessionID,
+ userAuthReq)
+ if err != nil {
+ return nil, err
+ }
+ default:
+ authErr = fmt.Errorf("ssh: unknown method %q", userAuthReq.Method)
+ }
+
+ authErrs = append(authErrs, authErr)
+
+ if config.AuthLogCallback != nil {
+ config.AuthLogCallback(s, userAuthReq.Method, authErr)
+ }
+
+ var bannerErr *BannerError
+ if errors.As(authErr, &bannerErr) {
+ if bannerErr.Message != "" {
+ bannerMsg := &userAuthBannerMsg{
+ Message: bannerErr.Message,
+ }
+ if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ if authErr == nil {
+ break userAuthLoop
+ }
+
+ var failureMsg userAuthFailureMsg
+
+ if partialSuccess, ok := authErr.(*PartialSuccessError); ok {
+ // After a partial success error we don't allow changing the user
+ // name and execute the NoClientAuthCallback.
+ partialSuccessReturned = true
+
+ // In case a partial success is returned, the server may send
+ // a new set of authentication methods.
+ authConfig = partialSuccess.Next
+
+ // Reset pubkey cache, as the new PublicKeyCallback might
+ // accept a different set of public keys.
+ cache = pubKeyCache{}
+
+ // Send back a partial success message to the user.
+ failureMsg.PartialSuccess = true
+ } else {
+ // Allow initial attempt of 'none' without penalty.
+ if authFailures > 0 || userAuthReq.Method != "none" || noneAuthCount != 1 {
+ authFailures++
+ }
+ if config.MaxAuthTries > 0 && authFailures >= config.MaxAuthTries {
+ // If we have hit the max attempts, don't bother sending the
+ // final SSH_MSG_USERAUTH_FAILURE message, since there are
+ // no more authentication methods which can be attempted,
+ // and this message may cause the client to re-attempt
+ // authentication while we send the disconnect message.
+ // Continue, and trigger the disconnect at the start of
+ // the loop.
+ //
+ // The SSH specification is somewhat confusing about this,
+ // RFC 4252 Section 5.1 requires each authentication failure
+ // be responded to with a respective SSH_MSG_USERAUTH_FAILURE
+ // message, but Section 4 says the server should disconnect
+ // after some number of attempts, but it isn't explicit which
+ // message should take precedence (i.e. should there be a failure
+ // message than a disconnect message, or if we are going to
+ // disconnect, should we only send that message.)
+ //
+ // Either way, OpenSSH disconnects immediately after the last
+ // failed authentication attempt, and given they are typically
+ // considered the golden implementation it seems reasonable
+ // to match that behavior.
+ continue
+ }
+ }
+
+ if authConfig.PasswordCallback != nil {
+ failureMsg.Methods = append(failureMsg.Methods, "password")
+ }
+ if authConfig.PublicKeyCallback != nil {
+ failureMsg.Methods = append(failureMsg.Methods, "publickey")
+ }
+ if authConfig.KeyboardInteractiveCallback != nil {
+ failureMsg.Methods = append(failureMsg.Methods, "keyboard-interactive")
+ }
+ if authConfig.GSSAPIWithMICConfig != nil && authConfig.GSSAPIWithMICConfig.Server != nil &&
+ authConfig.GSSAPIWithMICConfig.AllowLogin != nil {
+ failureMsg.Methods = append(failureMsg.Methods, "gssapi-with-mic")
+ }
+
+ if len(failureMsg.Methods) == 0 {
+ return nil, errors.New("ssh: no authentication methods available")
+ }
+
+ if err := s.transport.writePacket(Marshal(&failureMsg)); err != nil {
+ return nil, err
+ }
+ }
+
+ if err := s.transport.writePacket([]byte{msgUserAuthSuccess}); err != nil {
+ return nil, err
+ }
+ return perms, nil
+}
+
+// sshClientKeyboardInteractive implements a ClientKeyboardInteractive by
+// asking the client on the other side of a ServerConn.
+type sshClientKeyboardInteractive struct {
+ *connection
+}
+
+func (c *sshClientKeyboardInteractive) Challenge(name, instruction string, questions []string, echos []bool) (answers []string, err error) {
+ if len(questions) != len(echos) {
+ return nil, errors.New("ssh: echos and questions must have equal length")
+ }
+
+ var prompts []byte
+ for i := range questions {
+ prompts = appendString(prompts, questions[i])
+ prompts = appendBool(prompts, echos[i])
+ }
+
+ if err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{
+ Name: name,
+ Instruction: instruction,
+ NumPrompts: uint32(len(questions)),
+ Prompts: prompts,
+ })); err != nil {
+ return nil, err
+ }
+
+ packet, err := c.transport.readPacket()
+ if err != nil {
+ return nil, err
+ }
+ if packet[0] != msgUserAuthInfoResponse {
+ return nil, unexpectedMessageError(msgUserAuthInfoResponse, packet[0])
+ }
+ packet = packet[1:]
+
+ n, packet, ok := parseUint32(packet)
+ if !ok || int(n) != len(questions) {
+ return nil, parseError(msgUserAuthInfoResponse)
+ }
+
+ for i := uint32(0); i < n; i++ {
+ ans, rest, ok := parseString(packet)
+ if !ok {
+ return nil, parseError(msgUserAuthInfoResponse)
+ }
+
+ answers = append(answers, string(ans))
+ packet = rest
+ }
+ if len(packet) != 0 {
+ return nil, errors.New("ssh: junk at end of message")
+ }
+
+ return answers, nil
+}
diff --git a/vendor/golang.org/x/crypto/ssh/session.go b/vendor/golang.org/x/crypto/ssh/session.go
new file mode 100644
index 00000000..acef6225
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/session.go
@@ -0,0 +1,647 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+// Session implements an interactive session described in
+// "RFC 4254, section 6".
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "sync"
+)
+
+type Signal string
+
+// POSIX signals as listed in RFC 4254 Section 6.10.
+const (
+ SIGABRT Signal = "ABRT"
+ SIGALRM Signal = "ALRM"
+ SIGFPE Signal = "FPE"
+ SIGHUP Signal = "HUP"
+ SIGILL Signal = "ILL"
+ SIGINT Signal = "INT"
+ SIGKILL Signal = "KILL"
+ SIGPIPE Signal = "PIPE"
+ SIGQUIT Signal = "QUIT"
+ SIGSEGV Signal = "SEGV"
+ SIGTERM Signal = "TERM"
+ SIGUSR1 Signal = "USR1"
+ SIGUSR2 Signal = "USR2"
+)
+
+var signals = map[Signal]int{
+ SIGABRT: 6,
+ SIGALRM: 14,
+ SIGFPE: 8,
+ SIGHUP: 1,
+ SIGILL: 4,
+ SIGINT: 2,
+ SIGKILL: 9,
+ SIGPIPE: 13,
+ SIGQUIT: 3,
+ SIGSEGV: 11,
+ SIGTERM: 15,
+}
+
+type TerminalModes map[uint8]uint32
+
+// POSIX terminal mode flags as listed in RFC 4254 Section 8.
+const (
+ tty_OP_END = 0
+ VINTR = 1
+ VQUIT = 2
+ VERASE = 3
+ VKILL = 4
+ VEOF = 5
+ VEOL = 6
+ VEOL2 = 7
+ VSTART = 8
+ VSTOP = 9
+ VSUSP = 10
+ VDSUSP = 11
+ VREPRINT = 12
+ VWERASE = 13
+ VLNEXT = 14
+ VFLUSH = 15
+ VSWTCH = 16
+ VSTATUS = 17
+ VDISCARD = 18
+ IGNPAR = 30
+ PARMRK = 31
+ INPCK = 32
+ ISTRIP = 33
+ INLCR = 34
+ IGNCR = 35
+ ICRNL = 36
+ IUCLC = 37
+ IXON = 38
+ IXANY = 39
+ IXOFF = 40
+ IMAXBEL = 41
+ IUTF8 = 42 // RFC 8160
+ ISIG = 50
+ ICANON = 51
+ XCASE = 52
+ ECHO = 53
+ ECHOE = 54
+ ECHOK = 55
+ ECHONL = 56
+ NOFLSH = 57
+ TOSTOP = 58
+ IEXTEN = 59
+ ECHOCTL = 60
+ ECHOKE = 61
+ PENDIN = 62
+ OPOST = 70
+ OLCUC = 71
+ ONLCR = 72
+ OCRNL = 73
+ ONOCR = 74
+ ONLRET = 75
+ CS7 = 90
+ CS8 = 91
+ PARENB = 92
+ PARODD = 93
+ TTY_OP_ISPEED = 128
+ TTY_OP_OSPEED = 129
+)
+
+// A Session represents a connection to a remote command or shell.
+type Session struct {
+ // Stdin specifies the remote process's standard input.
+ // If Stdin is nil, the remote process reads from an empty
+ // bytes.Buffer.
+ Stdin io.Reader
+
+ // Stdout and Stderr specify the remote process's standard
+ // output and error.
+ //
+ // If either is nil, Run connects the corresponding file
+ // descriptor to an instance of io.Discard. There is a
+ // fixed amount of buffering that is shared for the two streams.
+ // If either blocks it may eventually cause the remote
+ // command to block.
+ Stdout io.Writer
+ Stderr io.Writer
+
+ ch Channel // the channel backing this session
+ started bool // true once Start, Run or Shell is invoked.
+ copyFuncs []func() error
+ errors chan error // one send per copyFunc
+
+ // true if pipe method is active
+ stdinpipe, stdoutpipe, stderrpipe bool
+
+ // stdinPipeWriter is non-nil if StdinPipe has not been called
+ // and Stdin was specified by the user; it is the write end of
+ // a pipe connecting Session.Stdin to the stdin channel.
+ stdinPipeWriter io.WriteCloser
+
+ exitStatus chan error
+}
+
+// SendRequest sends an out-of-band channel request on the SSH channel
+// underlying the session.
+func (s *Session) SendRequest(name string, wantReply bool, payload []byte) (bool, error) {
+ return s.ch.SendRequest(name, wantReply, payload)
+}
+
+func (s *Session) Close() error {
+ return s.ch.Close()
+}
+
+// RFC 4254 Section 6.4.
+type setenvRequest struct {
+ Name string
+ Value string
+}
+
+// Setenv sets an environment variable that will be applied to any
+// command executed by Shell or Run.
+func (s *Session) Setenv(name, value string) error {
+ msg := setenvRequest{
+ Name: name,
+ Value: value,
+ }
+ ok, err := s.ch.SendRequest("env", true, Marshal(&msg))
+ if err == nil && !ok {
+ err = errors.New("ssh: setenv failed")
+ }
+ return err
+}
+
+// RFC 4254 Section 6.2.
+type ptyRequestMsg struct {
+ Term string
+ Columns uint32
+ Rows uint32
+ Width uint32
+ Height uint32
+ Modelist string
+}
+
+// RequestPty requests the association of a pty with the session on the remote host.
+func (s *Session) RequestPty(term string, h, w int, termmodes TerminalModes) error {
+ var tm []byte
+ for k, v := range termmodes {
+ kv := struct {
+ Key byte
+ Val uint32
+ }{k, v}
+
+ tm = append(tm, Marshal(&kv)...)
+ }
+ tm = append(tm, tty_OP_END)
+ req := ptyRequestMsg{
+ Term: term,
+ Columns: uint32(w),
+ Rows: uint32(h),
+ Width: uint32(w * 8),
+ Height: uint32(h * 8),
+ Modelist: string(tm),
+ }
+ ok, err := s.ch.SendRequest("pty-req", true, Marshal(&req))
+ if err == nil && !ok {
+ err = errors.New("ssh: pty-req failed")
+ }
+ return err
+}
+
+// RFC 4254 Section 6.5.
+type subsystemRequestMsg struct {
+ Subsystem string
+}
+
+// RequestSubsystem requests the association of a subsystem with the session on the remote host.
+// A subsystem is a predefined command that runs in the background when the ssh session is initiated
+func (s *Session) RequestSubsystem(subsystem string) error {
+ msg := subsystemRequestMsg{
+ Subsystem: subsystem,
+ }
+ ok, err := s.ch.SendRequest("subsystem", true, Marshal(&msg))
+ if err == nil && !ok {
+ err = errors.New("ssh: subsystem request failed")
+ }
+ return err
+}
+
+// RFC 4254 Section 6.7.
+type ptyWindowChangeMsg struct {
+ Columns uint32
+ Rows uint32
+ Width uint32
+ Height uint32
+}
+
+// WindowChange informs the remote host about a terminal window dimension change to h rows and w columns.
+func (s *Session) WindowChange(h, w int) error {
+ req := ptyWindowChangeMsg{
+ Columns: uint32(w),
+ Rows: uint32(h),
+ Width: uint32(w * 8),
+ Height: uint32(h * 8),
+ }
+ _, err := s.ch.SendRequest("window-change", false, Marshal(&req))
+ return err
+}
+
+// RFC 4254 Section 6.9.
+type signalMsg struct {
+ Signal string
+}
+
+// Signal sends the given signal to the remote process.
+// sig is one of the SIG* constants.
+func (s *Session) Signal(sig Signal) error {
+ msg := signalMsg{
+ Signal: string(sig),
+ }
+
+ _, err := s.ch.SendRequest("signal", false, Marshal(&msg))
+ return err
+}
+
+// RFC 4254 Section 6.5.
+type execMsg struct {
+ Command string
+}
+
+// Start runs cmd on the remote host. Typically, the remote
+// server passes cmd to the shell for interpretation.
+// A Session only accepts one call to Run, Start or Shell.
+func (s *Session) Start(cmd string) error {
+ if s.started {
+ return errors.New("ssh: session already started")
+ }
+ req := execMsg{
+ Command: cmd,
+ }
+
+ ok, err := s.ch.SendRequest("exec", true, Marshal(&req))
+ if err == nil && !ok {
+ err = fmt.Errorf("ssh: command %v failed", cmd)
+ }
+ if err != nil {
+ return err
+ }
+ return s.start()
+}
+
+// Run runs cmd on the remote host. Typically, the remote
+// server passes cmd to the shell for interpretation.
+// A Session only accepts one call to Run, Start, Shell, Output,
+// or CombinedOutput.
+//
+// The returned error is nil if the command runs, has no problems
+// copying stdin, stdout, and stderr, and exits with a zero exit
+// status.
+//
+// If the remote server does not send an exit status, an error of type
+// *ExitMissingError is returned. If the command completes
+// unsuccessfully or is interrupted by a signal, the error is of type
+// *ExitError. Other error types may be returned for I/O problems.
+func (s *Session) Run(cmd string) error {
+ err := s.Start(cmd)
+ if err != nil {
+ return err
+ }
+ return s.Wait()
+}
+
+// Output runs cmd on the remote host and returns its standard output.
+func (s *Session) Output(cmd string) ([]byte, error) {
+ if s.Stdout != nil {
+ return nil, errors.New("ssh: Stdout already set")
+ }
+ var b bytes.Buffer
+ s.Stdout = &b
+ err := s.Run(cmd)
+ return b.Bytes(), err
+}
+
+type singleWriter struct {
+ b bytes.Buffer
+ mu sync.Mutex
+}
+
+func (w *singleWriter) Write(p []byte) (int, error) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ return w.b.Write(p)
+}
+
+// CombinedOutput runs cmd on the remote host and returns its combined
+// standard output and standard error.
+func (s *Session) CombinedOutput(cmd string) ([]byte, error) {
+ if s.Stdout != nil {
+ return nil, errors.New("ssh: Stdout already set")
+ }
+ if s.Stderr != nil {
+ return nil, errors.New("ssh: Stderr already set")
+ }
+ var b singleWriter
+ s.Stdout = &b
+ s.Stderr = &b
+ err := s.Run(cmd)
+ return b.b.Bytes(), err
+}
+
+// Shell starts a login shell on the remote host. A Session only
+// accepts one call to Run, Start, Shell, Output, or CombinedOutput.
+func (s *Session) Shell() error {
+ if s.started {
+ return errors.New("ssh: session already started")
+ }
+
+ ok, err := s.ch.SendRequest("shell", true, nil)
+ if err == nil && !ok {
+ return errors.New("ssh: could not start shell")
+ }
+ if err != nil {
+ return err
+ }
+ return s.start()
+}
+
+func (s *Session) start() error {
+ s.started = true
+
+ type F func(*Session)
+ for _, setupFd := range []F{(*Session).stdin, (*Session).stdout, (*Session).stderr} {
+ setupFd(s)
+ }
+
+ s.errors = make(chan error, len(s.copyFuncs))
+ for _, fn := range s.copyFuncs {
+ go func(fn func() error) {
+ s.errors <- fn()
+ }(fn)
+ }
+ return nil
+}
+
+// Wait waits for the remote command to exit.
+//
+// The returned error is nil if the command runs, has no problems
+// copying stdin, stdout, and stderr, and exits with a zero exit
+// status.
+//
+// If the remote server does not send an exit status, an error of type
+// *ExitMissingError is returned. If the command completes
+// unsuccessfully or is interrupted by a signal, the error is of type
+// *ExitError. Other error types may be returned for I/O problems.
+func (s *Session) Wait() error {
+ if !s.started {
+ return errors.New("ssh: session not started")
+ }
+ waitErr := <-s.exitStatus
+
+ if s.stdinPipeWriter != nil {
+ s.stdinPipeWriter.Close()
+ }
+ var copyError error
+ for range s.copyFuncs {
+ if err := <-s.errors; err != nil && copyError == nil {
+ copyError = err
+ }
+ }
+ if waitErr != nil {
+ return waitErr
+ }
+ return copyError
+}
+
+func (s *Session) wait(reqs <-chan *Request) error {
+ wm := Waitmsg{status: -1}
+ // Wait for msg channel to be closed before returning.
+ for msg := range reqs {
+ switch msg.Type {
+ case "exit-status":
+ wm.status = int(binary.BigEndian.Uint32(msg.Payload))
+ case "exit-signal":
+ var sigval struct {
+ Signal string
+ CoreDumped bool
+ Error string
+ Lang string
+ }
+ if err := Unmarshal(msg.Payload, &sigval); err != nil {
+ return err
+ }
+
+ // Must sanitize strings?
+ wm.signal = sigval.Signal
+ wm.msg = sigval.Error
+ wm.lang = sigval.Lang
+ default:
+ // This handles keepalives and matches
+ // OpenSSH's behaviour.
+ if msg.WantReply {
+ msg.Reply(false, nil)
+ }
+ }
+ }
+ if wm.status == 0 {
+ return nil
+ }
+ if wm.status == -1 {
+ // exit-status was never sent from server
+ if wm.signal == "" {
+ // signal was not sent either. RFC 4254
+ // section 6.10 recommends against this
+ // behavior, but it is allowed, so we let
+ // clients handle it.
+ return &ExitMissingError{}
+ }
+ wm.status = 128
+ if _, ok := signals[Signal(wm.signal)]; ok {
+ wm.status += signals[Signal(wm.signal)]
+ }
+ }
+
+ return &ExitError{wm}
+}
+
+// ExitMissingError is returned if a session is torn down cleanly, but
+// the server sends no confirmation of the exit status.
+type ExitMissingError struct{}
+
+func (e *ExitMissingError) Error() string {
+ return "wait: remote command exited without exit status or exit signal"
+}
+
+func (s *Session) stdin() {
+ if s.stdinpipe {
+ return
+ }
+ var stdin io.Reader
+ if s.Stdin == nil {
+ stdin = new(bytes.Buffer)
+ } else {
+ r, w := io.Pipe()
+ go func() {
+ _, err := io.Copy(w, s.Stdin)
+ w.CloseWithError(err)
+ }()
+ stdin, s.stdinPipeWriter = r, w
+ }
+ s.copyFuncs = append(s.copyFuncs, func() error {
+ _, err := io.Copy(s.ch, stdin)
+ if err1 := s.ch.CloseWrite(); err == nil && err1 != io.EOF {
+ err = err1
+ }
+ return err
+ })
+}
+
+func (s *Session) stdout() {
+ if s.stdoutpipe {
+ return
+ }
+ if s.Stdout == nil {
+ s.Stdout = io.Discard
+ }
+ s.copyFuncs = append(s.copyFuncs, func() error {
+ _, err := io.Copy(s.Stdout, s.ch)
+ return err
+ })
+}
+
+func (s *Session) stderr() {
+ if s.stderrpipe {
+ return
+ }
+ if s.Stderr == nil {
+ s.Stderr = io.Discard
+ }
+ s.copyFuncs = append(s.copyFuncs, func() error {
+ _, err := io.Copy(s.Stderr, s.ch.Stderr())
+ return err
+ })
+}
+
+// sessionStdin reroutes Close to CloseWrite.
+type sessionStdin struct {
+ io.Writer
+ ch Channel
+}
+
+func (s *sessionStdin) Close() error {
+ return s.ch.CloseWrite()
+}
+
+// StdinPipe returns a pipe that will be connected to the
+// remote command's standard input when the command starts.
+func (s *Session) StdinPipe() (io.WriteCloser, error) {
+ if s.Stdin != nil {
+ return nil, errors.New("ssh: Stdin already set")
+ }
+ if s.started {
+ return nil, errors.New("ssh: StdinPipe after process started")
+ }
+ s.stdinpipe = true
+ return &sessionStdin{s.ch, s.ch}, nil
+}
+
+// StdoutPipe returns a pipe that will be connected to the
+// remote command's standard output when the command starts.
+// There is a fixed amount of buffering that is shared between
+// stdout and stderr streams. If the StdoutPipe reader is
+// not serviced fast enough it may eventually cause the
+// remote command to block.
+func (s *Session) StdoutPipe() (io.Reader, error) {
+ if s.Stdout != nil {
+ return nil, errors.New("ssh: Stdout already set")
+ }
+ if s.started {
+ return nil, errors.New("ssh: StdoutPipe after process started")
+ }
+ s.stdoutpipe = true
+ return s.ch, nil
+}
+
+// StderrPipe returns a pipe that will be connected to the
+// remote command's standard error when the command starts.
+// There is a fixed amount of buffering that is shared between
+// stdout and stderr streams. If the StderrPipe reader is
+// not serviced fast enough it may eventually cause the
+// remote command to block.
+func (s *Session) StderrPipe() (io.Reader, error) {
+ if s.Stderr != nil {
+ return nil, errors.New("ssh: Stderr already set")
+ }
+ if s.started {
+ return nil, errors.New("ssh: StderrPipe after process started")
+ }
+ s.stderrpipe = true
+ return s.ch.Stderr(), nil
+}
+
+// newSession returns a new interactive session on the remote host.
+func newSession(ch Channel, reqs <-chan *Request) (*Session, error) {
+ s := &Session{
+ ch: ch,
+ }
+ s.exitStatus = make(chan error, 1)
+ go func() {
+ s.exitStatus <- s.wait(reqs)
+ }()
+
+ return s, nil
+}
+
+// An ExitError reports unsuccessful completion of a remote command.
+type ExitError struct {
+ Waitmsg
+}
+
+func (e *ExitError) Error() string {
+ return e.Waitmsg.String()
+}
+
+// Waitmsg stores the information about an exited remote command
+// as reported by Wait.
+type Waitmsg struct {
+ status int
+ signal string
+ msg string
+ lang string
+}
+
+// ExitStatus returns the exit status of the remote command.
+func (w Waitmsg) ExitStatus() int {
+ return w.status
+}
+
+// Signal returns the exit signal of the remote command if
+// it was terminated violently.
+func (w Waitmsg) Signal() string {
+ return w.signal
+}
+
+// Msg returns the exit message given by the remote command
+func (w Waitmsg) Msg() string {
+ return w.msg
+}
+
+// Lang returns the language tag. See RFC 3066
+func (w Waitmsg) Lang() string {
+ return w.lang
+}
+
+func (w Waitmsg) String() string {
+ str := fmt.Sprintf("Process exited with status %v", w.status)
+ if w.signal != "" {
+ str += fmt.Sprintf(" from signal %v", w.signal)
+ }
+ if w.msg != "" {
+ str += fmt.Sprintf(". Reason was: %v", w.msg)
+ }
+ return str
+}
diff --git a/vendor/golang.org/x/crypto/ssh/ssh_gss.go b/vendor/golang.org/x/crypto/ssh/ssh_gss.go
new file mode 100644
index 00000000..24bd7c8e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/ssh_gss.go
@@ -0,0 +1,139 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "encoding/asn1"
+ "errors"
+)
+
+var krb5OID []byte
+
+func init() {
+ krb5OID, _ = asn1.Marshal(krb5Mesh)
+}
+
+// GSSAPIClient provides the API to plug-in GSSAPI authentication for client logins.
+type GSSAPIClient interface {
+ // InitSecContext initiates the establishment of a security context for GSS-API between the
+ // ssh client and ssh server. Initially the token parameter should be specified as nil.
+ // The routine may return a outputToken which should be transferred to
+ // the ssh server, where the ssh server will present it to
+ // AcceptSecContext. If no token need be sent, InitSecContext will indicate this by setting
+ // needContinue to false. To complete the context
+ // establishment, one or more reply tokens may be required from the ssh
+ // server;if so, InitSecContext will return a needContinue which is true.
+ // In this case, InitSecContext should be called again when the
+ // reply token is received from the ssh server, passing the reply
+ // token to InitSecContext via the token parameters.
+ // See RFC 2743 section 2.2.1 and RFC 4462 section 3.4.
+ InitSecContext(target string, token []byte, isGSSDelegCreds bool) (outputToken []byte, needContinue bool, err error)
+ // GetMIC generates a cryptographic MIC for the SSH2 message, and places
+ // the MIC in a token for transfer to the ssh server.
+ // The contents of the MIC field are obtained by calling GSS_GetMIC()
+ // over the following, using the GSS-API context that was just
+ // established:
+ // string session identifier
+ // byte SSH_MSG_USERAUTH_REQUEST
+ // string user name
+ // string service
+ // string "gssapi-with-mic"
+ // See RFC 2743 section 2.3.1 and RFC 4462 3.5.
+ GetMIC(micFiled []byte) ([]byte, error)
+ // Whenever possible, it should be possible for
+ // DeleteSecContext() calls to be successfully processed even
+ // if other calls cannot succeed, thereby enabling context-related
+ // resources to be released.
+ // In addition to deleting established security contexts,
+ // gss_delete_sec_context must also be able to delete "half-built"
+ // security contexts resulting from an incomplete sequence of
+ // InitSecContext()/AcceptSecContext() calls.
+ // See RFC 2743 section 2.2.3.
+ DeleteSecContext() error
+}
+
+// GSSAPIServer provides the API to plug in GSSAPI authentication for server logins.
+type GSSAPIServer interface {
+ // AcceptSecContext allows a remotely initiated security context between the application
+ // and a remote peer to be established by the ssh client. The routine may return a
+ // outputToken which should be transferred to the ssh client,
+ // where the ssh client will present it to InitSecContext.
+ // If no token need be sent, AcceptSecContext will indicate this
+ // by setting the needContinue to false. To
+ // complete the context establishment, one or more reply tokens may be
+ // required from the ssh client. if so, AcceptSecContext
+ // will return a needContinue which is true, in which case it
+ // should be called again when the reply token is received from the ssh
+ // client, passing the token to AcceptSecContext via the
+ // token parameters.
+ // The srcName return value is the authenticated username.
+ // See RFC 2743 section 2.2.2 and RFC 4462 section 3.4.
+ AcceptSecContext(token []byte) (outputToken []byte, srcName string, needContinue bool, err error)
+ // VerifyMIC verifies that a cryptographic MIC, contained in the token parameter,
+ // fits the supplied message is received from the ssh client.
+ // See RFC 2743 section 2.3.2.
+ VerifyMIC(micField []byte, micToken []byte) error
+ // Whenever possible, it should be possible for
+ // DeleteSecContext() calls to be successfully processed even
+ // if other calls cannot succeed, thereby enabling context-related
+ // resources to be released.
+ // In addition to deleting established security contexts,
+ // gss_delete_sec_context must also be able to delete "half-built"
+ // security contexts resulting from an incomplete sequence of
+ // InitSecContext()/AcceptSecContext() calls.
+ // See RFC 2743 section 2.2.3.
+ DeleteSecContext() error
+}
+
+var (
+ // OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication,
+ // so we also support the krb5 mechanism only.
+ // See RFC 1964 section 1.
+ krb5Mesh = asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}
+)
+
+// The GSS-API authentication method is initiated when the client sends an SSH_MSG_USERAUTH_REQUEST
+// See RFC 4462 section 3.2.
+type userAuthRequestGSSAPI struct {
+ N uint32
+ OIDS []asn1.ObjectIdentifier
+}
+
+func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) {
+ n, rest, ok := parseUint32(payload)
+ if !ok {
+ return nil, errors.New("parse uint32 failed")
+ }
+ s := &userAuthRequestGSSAPI{
+ N: n,
+ OIDS: make([]asn1.ObjectIdentifier, n),
+ }
+ for i := 0; i < int(n); i++ {
+ var (
+ desiredMech []byte
+ err error
+ )
+ desiredMech, rest, ok = parseString(rest)
+ if !ok {
+ return nil, errors.New("parse string failed")
+ }
+ if rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil {
+ return nil, err
+ }
+
+ }
+ return s, nil
+}
+
+// See RFC 4462 section 3.6.
+func buildMIC(sessionID string, username string, service string, authMethod string) []byte {
+ out := make([]byte, 0, 0)
+ out = appendString(out, sessionID)
+ out = append(out, msgUserAuthRequest)
+ out = appendString(out, username)
+ out = appendString(out, service)
+ out = appendString(out, authMethod)
+ return out
+}
diff --git a/vendor/golang.org/x/crypto/ssh/streamlocal.go b/vendor/golang.org/x/crypto/ssh/streamlocal.go
new file mode 100644
index 00000000..b171b330
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/streamlocal.go
@@ -0,0 +1,116 @@
+package ssh
+
+import (
+ "errors"
+ "io"
+ "net"
+)
+
+// streamLocalChannelOpenDirectMsg is a struct used for SSH_MSG_CHANNEL_OPEN message
+// with "direct-streamlocal@openssh.com" string.
+//
+// See openssh-portable/PROTOCOL, section 2.4. connection: Unix domain socket forwarding
+// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL#L235
+type streamLocalChannelOpenDirectMsg struct {
+ socketPath string
+ reserved0 string
+ reserved1 uint32
+}
+
+// forwardedStreamLocalPayload is a struct used for SSH_MSG_CHANNEL_OPEN message
+// with "forwarded-streamlocal@openssh.com" string.
+type forwardedStreamLocalPayload struct {
+ SocketPath string
+ Reserved0 string
+}
+
+// streamLocalChannelForwardMsg is a struct used for SSH2_MSG_GLOBAL_REQUEST message
+// with "streamlocal-forward@openssh.com"/"cancel-streamlocal-forward@openssh.com" string.
+type streamLocalChannelForwardMsg struct {
+ socketPath string
+}
+
+// ListenUnix is similar to ListenTCP but uses a Unix domain socket.
+func (c *Client) ListenUnix(socketPath string) (net.Listener, error) {
+ c.handleForwardsOnce.Do(c.handleForwards)
+ m := streamLocalChannelForwardMsg{
+ socketPath,
+ }
+ // send message
+ ok, _, err := c.SendRequest("streamlocal-forward@openssh.com", true, Marshal(&m))
+ if err != nil {
+ return nil, err
+ }
+ if !ok {
+ return nil, errors.New("ssh: streamlocal-forward@openssh.com request denied by peer")
+ }
+ ch := c.forwards.add(&net.UnixAddr{Name: socketPath, Net: "unix"})
+
+ return &unixListener{socketPath, c, ch}, nil
+}
+
+func (c *Client) dialStreamLocal(socketPath string) (Channel, error) {
+ msg := streamLocalChannelOpenDirectMsg{
+ socketPath: socketPath,
+ }
+ ch, in, err := c.OpenChannel("direct-streamlocal@openssh.com", Marshal(&msg))
+ if err != nil {
+ return nil, err
+ }
+ go DiscardRequests(in)
+ return ch, err
+}
+
+type unixListener struct {
+ socketPath string
+
+ conn *Client
+ in <-chan forward
+}
+
+// Accept waits for and returns the next connection to the listener.
+func (l *unixListener) Accept() (net.Conn, error) {
+ s, ok := <-l.in
+ if !ok {
+ return nil, io.EOF
+ }
+ ch, incoming, err := s.newCh.Accept()
+ if err != nil {
+ return nil, err
+ }
+ go DiscardRequests(incoming)
+
+ return &chanConn{
+ Channel: ch,
+ laddr: &net.UnixAddr{
+ Name: l.socketPath,
+ Net: "unix",
+ },
+ raddr: &net.UnixAddr{
+ Name: "@",
+ Net: "unix",
+ },
+ }, nil
+}
+
+// Close closes the listener.
+func (l *unixListener) Close() error {
+ // this also closes the listener.
+ l.conn.forwards.remove(&net.UnixAddr{Name: l.socketPath, Net: "unix"})
+ m := streamLocalChannelForwardMsg{
+ l.socketPath,
+ }
+ ok, _, err := l.conn.SendRequest("cancel-streamlocal-forward@openssh.com", true, Marshal(&m))
+ if err == nil && !ok {
+ err = errors.New("ssh: cancel-streamlocal-forward@openssh.com failed")
+ }
+ return err
+}
+
+// Addr returns the listener's network address.
+func (l *unixListener) Addr() net.Addr {
+ return &net.UnixAddr{
+ Name: l.socketPath,
+ Net: "unix",
+ }
+}
diff --git a/vendor/golang.org/x/crypto/ssh/tcpip.go b/vendor/golang.org/x/crypto/ssh/tcpip.go
new file mode 100644
index 00000000..ef5059a1
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/tcpip.go
@@ -0,0 +1,509 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "math/rand"
+ "net"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+)
+
+// Listen requests the remote peer open a listening socket on
+// addr. Incoming connections will be available by calling Accept on
+// the returned net.Listener. The listener must be serviced, or the
+// SSH connection may hang.
+// N must be "tcp", "tcp4", "tcp6", or "unix".
+func (c *Client) Listen(n, addr string) (net.Listener, error) {
+ switch n {
+ case "tcp", "tcp4", "tcp6":
+ laddr, err := net.ResolveTCPAddr(n, addr)
+ if err != nil {
+ return nil, err
+ }
+ return c.ListenTCP(laddr)
+ case "unix":
+ return c.ListenUnix(addr)
+ default:
+ return nil, fmt.Errorf("ssh: unsupported protocol: %s", n)
+ }
+}
+
+// Automatic port allocation is broken with OpenSSH before 6.0. See
+// also https://bugzilla.mindrot.org/show_bug.cgi?id=2017. In
+// particular, OpenSSH 5.9 sends a channelOpenMsg with port number 0,
+// rather than the actual port number. This means you can never open
+// two different listeners with auto allocated ports. We work around
+// this by trying explicit ports until we succeed.
+
+const openSSHPrefix = "OpenSSH_"
+
+var portRandomizer = rand.New(rand.NewSource(time.Now().UnixNano()))
+
+// isBrokenOpenSSHVersion returns true if the given version string
+// specifies a version of OpenSSH that is known to have a bug in port
+// forwarding.
+func isBrokenOpenSSHVersion(versionStr string) bool {
+ i := strings.Index(versionStr, openSSHPrefix)
+ if i < 0 {
+ return false
+ }
+ i += len(openSSHPrefix)
+ j := i
+ for ; j < len(versionStr); j++ {
+ if versionStr[j] < '0' || versionStr[j] > '9' {
+ break
+ }
+ }
+ version, _ := strconv.Atoi(versionStr[i:j])
+ return version < 6
+}
+
+// autoPortListenWorkaround simulates automatic port allocation by
+// trying random ports repeatedly.
+func (c *Client) autoPortListenWorkaround(laddr *net.TCPAddr) (net.Listener, error) {
+ var sshListener net.Listener
+ var err error
+ const tries = 10
+ for i := 0; i < tries; i++ {
+ addr := *laddr
+ addr.Port = 1024 + portRandomizer.Intn(60000)
+ sshListener, err = c.ListenTCP(&addr)
+ if err == nil {
+ laddr.Port = addr.Port
+ return sshListener, err
+ }
+ }
+ return nil, fmt.Errorf("ssh: listen on random port failed after %d tries: %v", tries, err)
+}
+
+// RFC 4254 7.1
+type channelForwardMsg struct {
+ addr string
+ rport uint32
+}
+
+// handleForwards starts goroutines handling forwarded connections.
+// It's called on first use by (*Client).ListenTCP to not launch
+// goroutines until needed.
+func (c *Client) handleForwards() {
+ go c.forwards.handleChannels(c.HandleChannelOpen("forwarded-tcpip"))
+ go c.forwards.handleChannels(c.HandleChannelOpen("forwarded-streamlocal@openssh.com"))
+}
+
+// ListenTCP requests the remote peer open a listening socket
+// on laddr. Incoming connections will be available by calling
+// Accept on the returned net.Listener.
+func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
+ c.handleForwardsOnce.Do(c.handleForwards)
+ if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
+ return c.autoPortListenWorkaround(laddr)
+ }
+
+ m := channelForwardMsg{
+ laddr.IP.String(),
+ uint32(laddr.Port),
+ }
+ // send message
+ ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m))
+ if err != nil {
+ return nil, err
+ }
+ if !ok {
+ return nil, errors.New("ssh: tcpip-forward request denied by peer")
+ }
+
+ // If the original port was 0, then the remote side will
+ // supply a real port number in the response.
+ if laddr.Port == 0 {
+ var p struct {
+ Port uint32
+ }
+ if err := Unmarshal(resp, &p); err != nil {
+ return nil, err
+ }
+ laddr.Port = int(p.Port)
+ }
+
+ // Register this forward, using the port number we obtained.
+ ch := c.forwards.add(laddr)
+
+ return &tcpListener{laddr, c, ch}, nil
+}
+
+// forwardList stores a mapping between remote
+// forward requests and the tcpListeners.
+type forwardList struct {
+ sync.Mutex
+ entries []forwardEntry
+}
+
+// forwardEntry represents an established mapping of a laddr on a
+// remote ssh server to a channel connected to a tcpListener.
+type forwardEntry struct {
+ laddr net.Addr
+ c chan forward
+}
+
+// forward represents an incoming forwarded tcpip connection. The
+// arguments to add/remove/lookup should be address as specified in
+// the original forward-request.
+type forward struct {
+ newCh NewChannel // the ssh client channel underlying this forward
+ raddr net.Addr // the raddr of the incoming connection
+}
+
+func (l *forwardList) add(addr net.Addr) chan forward {
+ l.Lock()
+ defer l.Unlock()
+ f := forwardEntry{
+ laddr: addr,
+ c: make(chan forward, 1),
+ }
+ l.entries = append(l.entries, f)
+ return f.c
+}
+
+// See RFC 4254, section 7.2
+type forwardedTCPPayload struct {
+ Addr string
+ Port uint32
+ OriginAddr string
+ OriginPort uint32
+}
+
+// parseTCPAddr parses the originating address from the remote into a *net.TCPAddr.
+func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) {
+ if port == 0 || port > 65535 {
+ return nil, fmt.Errorf("ssh: port number out of range: %d", port)
+ }
+ ip := net.ParseIP(string(addr))
+ if ip == nil {
+ return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr)
+ }
+ return &net.TCPAddr{IP: ip, Port: int(port)}, nil
+}
+
+func (l *forwardList) handleChannels(in <-chan NewChannel) {
+ for ch := range in {
+ var (
+ laddr net.Addr
+ raddr net.Addr
+ err error
+ )
+ switch channelType := ch.ChannelType(); channelType {
+ case "forwarded-tcpip":
+ var payload forwardedTCPPayload
+ if err = Unmarshal(ch.ExtraData(), &payload); err != nil {
+ ch.Reject(ConnectionFailed, "could not parse forwarded-tcpip payload: "+err.Error())
+ continue
+ }
+
+ // RFC 4254 section 7.2 specifies that incoming
+ // addresses should list the address, in string
+ // format. It is implied that this should be an IP
+ // address, as it would be impossible to connect to it
+ // otherwise.
+ laddr, err = parseTCPAddr(payload.Addr, payload.Port)
+ if err != nil {
+ ch.Reject(ConnectionFailed, err.Error())
+ continue
+ }
+ raddr, err = parseTCPAddr(payload.OriginAddr, payload.OriginPort)
+ if err != nil {
+ ch.Reject(ConnectionFailed, err.Error())
+ continue
+ }
+
+ case "forwarded-streamlocal@openssh.com":
+ var payload forwardedStreamLocalPayload
+ if err = Unmarshal(ch.ExtraData(), &payload); err != nil {
+ ch.Reject(ConnectionFailed, "could not parse forwarded-streamlocal@openssh.com payload: "+err.Error())
+ continue
+ }
+ laddr = &net.UnixAddr{
+ Name: payload.SocketPath,
+ Net: "unix",
+ }
+ raddr = &net.UnixAddr{
+ Name: "@",
+ Net: "unix",
+ }
+ default:
+ panic(fmt.Errorf("ssh: unknown channel type %s", channelType))
+ }
+ if ok := l.forward(laddr, raddr, ch); !ok {
+ // Section 7.2, implementations MUST reject spurious incoming
+ // connections.
+ ch.Reject(Prohibited, "no forward for address")
+ continue
+ }
+
+ }
+}
+
+// remove removes the forward entry, and the channel feeding its
+// listener.
+func (l *forwardList) remove(addr net.Addr) {
+ l.Lock()
+ defer l.Unlock()
+ for i, f := range l.entries {
+ if addr.Network() == f.laddr.Network() && addr.String() == f.laddr.String() {
+ l.entries = append(l.entries[:i], l.entries[i+1:]...)
+ close(f.c)
+ return
+ }
+ }
+}
+
+// closeAll closes and clears all forwards.
+func (l *forwardList) closeAll() {
+ l.Lock()
+ defer l.Unlock()
+ for _, f := range l.entries {
+ close(f.c)
+ }
+ l.entries = nil
+}
+
+func (l *forwardList) forward(laddr, raddr net.Addr, ch NewChannel) bool {
+ l.Lock()
+ defer l.Unlock()
+ for _, f := range l.entries {
+ if laddr.Network() == f.laddr.Network() && laddr.String() == f.laddr.String() {
+ f.c <- forward{newCh: ch, raddr: raddr}
+ return true
+ }
+ }
+ return false
+}
+
+type tcpListener struct {
+ laddr *net.TCPAddr
+
+ conn *Client
+ in <-chan forward
+}
+
+// Accept waits for and returns the next connection to the listener.
+func (l *tcpListener) Accept() (net.Conn, error) {
+ s, ok := <-l.in
+ if !ok {
+ return nil, io.EOF
+ }
+ ch, incoming, err := s.newCh.Accept()
+ if err != nil {
+ return nil, err
+ }
+ go DiscardRequests(incoming)
+
+ return &chanConn{
+ Channel: ch,
+ laddr: l.laddr,
+ raddr: s.raddr,
+ }, nil
+}
+
+// Close closes the listener.
+func (l *tcpListener) Close() error {
+ m := channelForwardMsg{
+ l.laddr.IP.String(),
+ uint32(l.laddr.Port),
+ }
+
+ // this also closes the listener.
+ l.conn.forwards.remove(l.laddr)
+ ok, _, err := l.conn.SendRequest("cancel-tcpip-forward", true, Marshal(&m))
+ if err == nil && !ok {
+ err = errors.New("ssh: cancel-tcpip-forward failed")
+ }
+ return err
+}
+
+// Addr returns the listener's network address.
+func (l *tcpListener) Addr() net.Addr {
+ return l.laddr
+}
+
+// DialContext initiates a connection to the addr from the remote host.
+//
+// The provided Context must be non-nil. If the context expires before the
+// connection is complete, an error is returned. Once successfully connected,
+// any expiration of the context will not affect the connection.
+//
+// See func Dial for additional information.
+func (c *Client) DialContext(ctx context.Context, n, addr string) (net.Conn, error) {
+ if err := ctx.Err(); err != nil {
+ return nil, err
+ }
+ type connErr struct {
+ conn net.Conn
+ err error
+ }
+ ch := make(chan connErr)
+ go func() {
+ conn, err := c.Dial(n, addr)
+ select {
+ case ch <- connErr{conn, err}:
+ case <-ctx.Done():
+ if conn != nil {
+ conn.Close()
+ }
+ }
+ }()
+ select {
+ case res := <-ch:
+ return res.conn, res.err
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ }
+}
+
+// Dial initiates a connection to the addr from the remote host.
+// The resulting connection has a zero LocalAddr() and RemoteAddr().
+func (c *Client) Dial(n, addr string) (net.Conn, error) {
+ var ch Channel
+ switch n {
+ case "tcp", "tcp4", "tcp6":
+ // Parse the address into host and numeric port.
+ host, portString, err := net.SplitHostPort(addr)
+ if err != nil {
+ return nil, err
+ }
+ port, err := strconv.ParseUint(portString, 10, 16)
+ if err != nil {
+ return nil, err
+ }
+ ch, err = c.dial(net.IPv4zero.String(), 0, host, int(port))
+ if err != nil {
+ return nil, err
+ }
+ // Use a zero address for local and remote address.
+ zeroAddr := &net.TCPAddr{
+ IP: net.IPv4zero,
+ Port: 0,
+ }
+ return &chanConn{
+ Channel: ch,
+ laddr: zeroAddr,
+ raddr: zeroAddr,
+ }, nil
+ case "unix":
+ var err error
+ ch, err = c.dialStreamLocal(addr)
+ if err != nil {
+ return nil, err
+ }
+ return &chanConn{
+ Channel: ch,
+ laddr: &net.UnixAddr{
+ Name: "@",
+ Net: "unix",
+ },
+ raddr: &net.UnixAddr{
+ Name: addr,
+ Net: "unix",
+ },
+ }, nil
+ default:
+ return nil, fmt.Errorf("ssh: unsupported protocol: %s", n)
+ }
+}
+
+// DialTCP connects to the remote address raddr on the network net,
+// which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used
+// as the local address for the connection.
+func (c *Client) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, error) {
+ if laddr == nil {
+ laddr = &net.TCPAddr{
+ IP: net.IPv4zero,
+ Port: 0,
+ }
+ }
+ ch, err := c.dial(laddr.IP.String(), laddr.Port, raddr.IP.String(), raddr.Port)
+ if err != nil {
+ return nil, err
+ }
+ return &chanConn{
+ Channel: ch,
+ laddr: laddr,
+ raddr: raddr,
+ }, nil
+}
+
+// RFC 4254 7.2
+type channelOpenDirectMsg struct {
+ raddr string
+ rport uint32
+ laddr string
+ lport uint32
+}
+
+func (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel, error) {
+ msg := channelOpenDirectMsg{
+ raddr: raddr,
+ rport: uint32(rport),
+ laddr: laddr,
+ lport: uint32(lport),
+ }
+ ch, in, err := c.OpenChannel("direct-tcpip", Marshal(&msg))
+ if err != nil {
+ return nil, err
+ }
+ go DiscardRequests(in)
+ return ch, err
+}
+
+type tcpChan struct {
+ Channel // the backing channel
+}
+
+// chanConn fulfills the net.Conn interface without
+// the tcpChan having to hold laddr or raddr directly.
+type chanConn struct {
+ Channel
+ laddr, raddr net.Addr
+}
+
+// LocalAddr returns the local network address.
+func (t *chanConn) LocalAddr() net.Addr {
+ return t.laddr
+}
+
+// RemoteAddr returns the remote network address.
+func (t *chanConn) RemoteAddr() net.Addr {
+ return t.raddr
+}
+
+// SetDeadline sets the read and write deadlines associated
+// with the connection.
+func (t *chanConn) SetDeadline(deadline time.Time) error {
+ if err := t.SetReadDeadline(deadline); err != nil {
+ return err
+ }
+ return t.SetWriteDeadline(deadline)
+}
+
+// SetReadDeadline sets the read deadline.
+// A zero value for t means Read will not time out.
+// After the deadline, the error from Read will implement net.Error
+// with Timeout() == true.
+func (t *chanConn) SetReadDeadline(deadline time.Time) error {
+ // for compatibility with previous version,
+ // the error message contains "tcpChan"
+ return errors.New("ssh: tcpChan: deadline not supported")
+}
+
+// SetWriteDeadline exists to satisfy the net.Conn interface
+// but is not implemented by this type. It always returns an error.
+func (t *chanConn) SetWriteDeadline(deadline time.Time) error {
+ return errors.New("ssh: tcpChan: deadline not supported")
+}
diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go
new file mode 100644
index 00000000..0424d2d3
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/transport.go
@@ -0,0 +1,380 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "io"
+ "log"
+)
+
+// debugTransport if set, will print packet types as they go over the
+// wire. No message decoding is done, to minimize the impact on timing.
+const debugTransport = false
+
+const (
+ gcm128CipherID = "aes128-gcm@openssh.com"
+ gcm256CipherID = "aes256-gcm@openssh.com"
+ aes128cbcID = "aes128-cbc"
+ tripledescbcID = "3des-cbc"
+)
+
+// packetConn represents a transport that implements packet based
+// operations.
+type packetConn interface {
+ // Encrypt and send a packet of data to the remote peer.
+ writePacket(packet []byte) error
+
+ // Read a packet from the connection. The read is blocking,
+ // i.e. if error is nil, then the returned byte slice is
+ // always non-empty.
+ readPacket() ([]byte, error)
+
+ // Close closes the write-side of the connection.
+ Close() error
+}
+
+// transport is the keyingTransport that implements the SSH packet
+// protocol.
+type transport struct {
+ reader connectionState
+ writer connectionState
+
+ bufReader *bufio.Reader
+ bufWriter *bufio.Writer
+ rand io.Reader
+ isClient bool
+ io.Closer
+
+ strictMode bool
+ initialKEXDone bool
+}
+
+// packetCipher represents a combination of SSH encryption/MAC
+// protocol. A single instance should be used for one direction only.
+type packetCipher interface {
+ // writeCipherPacket encrypts the packet and writes it to w. The
+ // contents of the packet are generally scrambled.
+ writeCipherPacket(seqnum uint32, w io.Writer, rand io.Reader, packet []byte) error
+
+ // readCipherPacket reads and decrypts a packet of data. The
+ // returned packet may be overwritten by future calls of
+ // readPacket.
+ readCipherPacket(seqnum uint32, r io.Reader) ([]byte, error)
+}
+
+// connectionState represents one side (read or write) of the
+// connection. This is necessary because each direction has its own
+// keys, and can even have its own algorithms
+type connectionState struct {
+ packetCipher
+ seqNum uint32
+ dir direction
+ pendingKeyChange chan packetCipher
+}
+
+func (t *transport) setStrictMode() error {
+ if t.reader.seqNum != 1 {
+ return errors.New("ssh: sequence number != 1 when strict KEX mode requested")
+ }
+ t.strictMode = true
+ return nil
+}
+
+func (t *transport) setInitialKEXDone() {
+ t.initialKEXDone = true
+}
+
+// prepareKeyChange sets up key material for a keychange. The key changes in
+// both directions are triggered by reading and writing a msgNewKey packet
+// respectively.
+func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error {
+ ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult)
+ if err != nil {
+ return err
+ }
+ t.reader.pendingKeyChange <- ciph
+
+ ciph, err = newPacketCipher(t.writer.dir, algs.w, kexResult)
+ if err != nil {
+ return err
+ }
+ t.writer.pendingKeyChange <- ciph
+
+ return nil
+}
+
+func (t *transport) printPacket(p []byte, write bool) {
+ if len(p) == 0 {
+ return
+ }
+ who := "server"
+ if t.isClient {
+ who = "client"
+ }
+ what := "read"
+ if write {
+ what = "write"
+ }
+
+ log.Println(what, who, p[0])
+}
+
+// Read and decrypt next packet.
+func (t *transport) readPacket() (p []byte, err error) {
+ for {
+ p, err = t.reader.readPacket(t.bufReader, t.strictMode)
+ if err != nil {
+ break
+ }
+ // in strict mode we pass through DEBUG and IGNORE packets only during the initial KEX
+ if len(p) == 0 || (t.strictMode && !t.initialKEXDone) || (p[0] != msgIgnore && p[0] != msgDebug) {
+ break
+ }
+ }
+ if debugTransport {
+ t.printPacket(p, false)
+ }
+
+ return p, err
+}
+
+func (s *connectionState) readPacket(r *bufio.Reader, strictMode bool) ([]byte, error) {
+ packet, err := s.packetCipher.readCipherPacket(s.seqNum, r)
+ s.seqNum++
+ if err == nil && len(packet) == 0 {
+ err = errors.New("ssh: zero length packet")
+ }
+
+ if len(packet) > 0 {
+ switch packet[0] {
+ case msgNewKeys:
+ select {
+ case cipher := <-s.pendingKeyChange:
+ s.packetCipher = cipher
+ if strictMode {
+ s.seqNum = 0
+ }
+ default:
+ return nil, errors.New("ssh: got bogus newkeys message")
+ }
+
+ case msgDisconnect:
+ // Transform a disconnect message into an
+ // error. Since this is lowest level at which
+ // we interpret message types, doing it here
+ // ensures that we don't have to handle it
+ // elsewhere.
+ var msg disconnectMsg
+ if err := Unmarshal(packet, &msg); err != nil {
+ return nil, err
+ }
+ return nil, &msg
+ }
+ }
+
+ // The packet may point to an internal buffer, so copy the
+ // packet out here.
+ fresh := make([]byte, len(packet))
+ copy(fresh, packet)
+
+ return fresh, err
+}
+
+func (t *transport) writePacket(packet []byte) error {
+ if debugTransport {
+ t.printPacket(packet, true)
+ }
+ return t.writer.writePacket(t.bufWriter, t.rand, packet, t.strictMode)
+}
+
+func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte, strictMode bool) error {
+ changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
+
+ err := s.packetCipher.writeCipherPacket(s.seqNum, w, rand, packet)
+ if err != nil {
+ return err
+ }
+ if err = w.Flush(); err != nil {
+ return err
+ }
+ s.seqNum++
+ if changeKeys {
+ select {
+ case cipher := <-s.pendingKeyChange:
+ s.packetCipher = cipher
+ if strictMode {
+ s.seqNum = 0
+ }
+ default:
+ panic("ssh: no key material for msgNewKeys")
+ }
+ }
+ return err
+}
+
+func newTransport(rwc io.ReadWriteCloser, rand io.Reader, isClient bool) *transport {
+ t := &transport{
+ bufReader: bufio.NewReader(rwc),
+ bufWriter: bufio.NewWriter(rwc),
+ rand: rand,
+ reader: connectionState{
+ packetCipher: &streamPacketCipher{cipher: noneCipher{}},
+ pendingKeyChange: make(chan packetCipher, 1),
+ },
+ writer: connectionState{
+ packetCipher: &streamPacketCipher{cipher: noneCipher{}},
+ pendingKeyChange: make(chan packetCipher, 1),
+ },
+ Closer: rwc,
+ }
+ t.isClient = isClient
+
+ if isClient {
+ t.reader.dir = serverKeys
+ t.writer.dir = clientKeys
+ } else {
+ t.reader.dir = clientKeys
+ t.writer.dir = serverKeys
+ }
+
+ return t
+}
+
+type direction struct {
+ ivTag []byte
+ keyTag []byte
+ macKeyTag []byte
+}
+
+var (
+ serverKeys = direction{[]byte{'B'}, []byte{'D'}, []byte{'F'}}
+ clientKeys = direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}}
+)
+
+// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as
+// described in RFC 4253, section 6.4. direction should either be serverKeys
+// (to setup server->client keys) or clientKeys (for client->server keys).
+func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
+ cipherMode := cipherModes[algs.Cipher]
+
+ iv := make([]byte, cipherMode.ivSize)
+ key := make([]byte, cipherMode.keySize)
+
+ generateKeyMaterial(iv, d.ivTag, kex)
+ generateKeyMaterial(key, d.keyTag, kex)
+
+ var macKey []byte
+ if !aeadCiphers[algs.Cipher] {
+ macMode := macModes[algs.MAC]
+ macKey = make([]byte, macMode.keySize)
+ generateKeyMaterial(macKey, d.macKeyTag, kex)
+ }
+
+ return cipherModes[algs.Cipher].create(key, iv, macKey, algs)
+}
+
+// generateKeyMaterial fills out with key material generated from tag, K, H
+// and sessionId, as specified in RFC 4253, section 7.2.
+func generateKeyMaterial(out, tag []byte, r *kexResult) {
+ var digestsSoFar []byte
+
+ h := r.Hash.New()
+ for len(out) > 0 {
+ h.Reset()
+ h.Write(r.K)
+ h.Write(r.H)
+
+ if len(digestsSoFar) == 0 {
+ h.Write(tag)
+ h.Write(r.SessionID)
+ } else {
+ h.Write(digestsSoFar)
+ }
+
+ digest := h.Sum(nil)
+ n := copy(out, digest)
+ out = out[n:]
+ if len(out) > 0 {
+ digestsSoFar = append(digestsSoFar, digest...)
+ }
+ }
+}
+
+const packageVersion = "SSH-2.0-Go"
+
+// Sends and receives a version line. The versionLine string should
+// be US ASCII, start with "SSH-2.0-", and should not include a
+// newline. exchangeVersions returns the other side's version line.
+func exchangeVersions(rw io.ReadWriter, versionLine []byte) (them []byte, err error) {
+ // Contrary to the RFC, we do not ignore lines that don't
+ // start with "SSH-2.0-" to make the library usable with
+ // nonconforming servers.
+ for _, c := range versionLine {
+ // The spec disallows non US-ASCII chars, and
+ // specifically forbids null chars.
+ if c < 32 {
+ return nil, errors.New("ssh: junk character in version line")
+ }
+ }
+ if _, err = rw.Write(append(versionLine, '\r', '\n')); err != nil {
+ return
+ }
+
+ them, err = readVersion(rw)
+ return them, err
+}
+
+// maxVersionStringBytes is the maximum number of bytes that we'll
+// accept as a version string. RFC 4253 section 4.2 limits this at 255
+// chars
+const maxVersionStringBytes = 255
+
+// Read version string as specified by RFC 4253, section 4.2.
+func readVersion(r io.Reader) ([]byte, error) {
+ versionString := make([]byte, 0, 64)
+ var ok bool
+ var buf [1]byte
+
+ for length := 0; length < maxVersionStringBytes; length++ {
+ _, err := io.ReadFull(r, buf[:])
+ if err != nil {
+ return nil, err
+ }
+ // The RFC says that the version should be terminated with \r\n
+ // but several SSH servers actually only send a \n.
+ if buf[0] == '\n' {
+ if !bytes.HasPrefix(versionString, []byte("SSH-")) {
+ // RFC 4253 says we need to ignore all version string lines
+ // except the one containing the SSH version (provided that
+ // all the lines do not exceed 255 bytes in total).
+ versionString = versionString[:0]
+ continue
+ }
+ ok = true
+ break
+ }
+
+ // non ASCII chars are disallowed, but we are lenient,
+ // since Go doesn't use null-terminated strings.
+
+ // The RFC allows a comment after a space, however,
+ // all of it (version and comments) goes into the
+ // session hash.
+ versionString = append(versionString, buf[0])
+ }
+
+ if !ok {
+ return nil, errors.New("ssh: overflow reading version string")
+ }
+
+ // There might be a '\r' on the end which we should remove.
+ if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' {
+ versionString = versionString[:len(versionString)-1]
+ }
+ return versionString, nil
+}
diff --git a/vendor/golang.org/x/mod/LICENSE b/vendor/golang.org/x/mod/LICENSE
new file mode 100644
index 00000000..6a66aea5
--- /dev/null
+++ b/vendor/golang.org/x/mod/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/mod/PATENTS b/vendor/golang.org/x/mod/PATENTS
new file mode 100644
index 00000000..73309904
--- /dev/null
+++ b/vendor/golang.org/x/mod/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/mod/semver/semver.go b/vendor/golang.org/x/mod/semver/semver.go
new file mode 100644
index 00000000..9a2dfd33
--- /dev/null
+++ b/vendor/golang.org/x/mod/semver/semver.go
@@ -0,0 +1,401 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package semver implements comparison of semantic version strings.
+// In this package, semantic version strings must begin with a leading "v",
+// as in "v1.0.0".
+//
+// The general form of a semantic version string accepted by this package is
+//
+// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]
+//
+// where square brackets indicate optional parts of the syntax;
+// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;
+// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers
+// using only alphanumeric characters and hyphens; and
+// all-numeric PRERELEASE identifiers must not have leading zeros.
+//
+// This package follows Semantic Versioning 2.0.0 (see semver.org)
+// with two exceptions. First, it requires the "v" prefix. Second, it recognizes
+// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)
+// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
+package semver
+
+import "sort"
+
+// parsed returns the parsed form of a semantic version string.
+type parsed struct {
+ major string
+ minor string
+ patch string
+ short string
+ prerelease string
+ build string
+}
+
+// IsValid reports whether v is a valid semantic version string.
+func IsValid(v string) bool {
+ _, ok := parse(v)
+ return ok
+}
+
+// Canonical returns the canonical formatting of the semantic version v.
+// It fills in any missing .MINOR or .PATCH and discards build metadata.
+// Two semantic versions compare equal only if their canonical formattings
+// are identical strings.
+// The canonical invalid semantic version is the empty string.
+func Canonical(v string) string {
+ p, ok := parse(v)
+ if !ok {
+ return ""
+ }
+ if p.build != "" {
+ return v[:len(v)-len(p.build)]
+ }
+ if p.short != "" {
+ return v + p.short
+ }
+ return v
+}
+
+// Major returns the major version prefix of the semantic version v.
+// For example, Major("v2.1.0") == "v2".
+// If v is an invalid semantic version string, Major returns the empty string.
+func Major(v string) string {
+ pv, ok := parse(v)
+ if !ok {
+ return ""
+ }
+ return v[:1+len(pv.major)]
+}
+
+// MajorMinor returns the major.minor version prefix of the semantic version v.
+// For example, MajorMinor("v2.1.0") == "v2.1".
+// If v is an invalid semantic version string, MajorMinor returns the empty string.
+func MajorMinor(v string) string {
+ pv, ok := parse(v)
+ if !ok {
+ return ""
+ }
+ i := 1 + len(pv.major)
+ if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {
+ return v[:j]
+ }
+ return v[:i] + "." + pv.minor
+}
+
+// Prerelease returns the prerelease suffix of the semantic version v.
+// For example, Prerelease("v2.1.0-pre+meta") == "-pre".
+// If v is an invalid semantic version string, Prerelease returns the empty string.
+func Prerelease(v string) string {
+ pv, ok := parse(v)
+ if !ok {
+ return ""
+ }
+ return pv.prerelease
+}
+
+// Build returns the build suffix of the semantic version v.
+// For example, Build("v2.1.0+meta") == "+meta".
+// If v is an invalid semantic version string, Build returns the empty string.
+func Build(v string) string {
+ pv, ok := parse(v)
+ if !ok {
+ return ""
+ }
+ return pv.build
+}
+
+// Compare returns an integer comparing two versions according to
+// semantic version precedence.
+// The result will be 0 if v == w, -1 if v < w, or +1 if v > w.
+//
+// An invalid semantic version string is considered less than a valid one.
+// All invalid semantic version strings compare equal to each other.
+func Compare(v, w string) int {
+ pv, ok1 := parse(v)
+ pw, ok2 := parse(w)
+ if !ok1 && !ok2 {
+ return 0
+ }
+ if !ok1 {
+ return -1
+ }
+ if !ok2 {
+ return +1
+ }
+ if c := compareInt(pv.major, pw.major); c != 0 {
+ return c
+ }
+ if c := compareInt(pv.minor, pw.minor); c != 0 {
+ return c
+ }
+ if c := compareInt(pv.patch, pw.patch); c != 0 {
+ return c
+ }
+ return comparePrerelease(pv.prerelease, pw.prerelease)
+}
+
+// Max canonicalizes its arguments and then returns the version string
+// that compares greater.
+//
+// Deprecated: use [Compare] instead. In most cases, returning a canonicalized
+// version is not expected or desired.
+func Max(v, w string) string {
+ v = Canonical(v)
+ w = Canonical(w)
+ if Compare(v, w) > 0 {
+ return v
+ }
+ return w
+}
+
+// ByVersion implements [sort.Interface] for sorting semantic version strings.
+type ByVersion []string
+
+func (vs ByVersion) Len() int { return len(vs) }
+func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
+func (vs ByVersion) Less(i, j int) bool {
+ cmp := Compare(vs[i], vs[j])
+ if cmp != 0 {
+ return cmp < 0
+ }
+ return vs[i] < vs[j]
+}
+
+// Sort sorts a list of semantic version strings using [ByVersion].
+func Sort(list []string) {
+ sort.Sort(ByVersion(list))
+}
+
+func parse(v string) (p parsed, ok bool) {
+ if v == "" || v[0] != 'v' {
+ return
+ }
+ p.major, v, ok = parseInt(v[1:])
+ if !ok {
+ return
+ }
+ if v == "" {
+ p.minor = "0"
+ p.patch = "0"
+ p.short = ".0.0"
+ return
+ }
+ if v[0] != '.' {
+ ok = false
+ return
+ }
+ p.minor, v, ok = parseInt(v[1:])
+ if !ok {
+ return
+ }
+ if v == "" {
+ p.patch = "0"
+ p.short = ".0"
+ return
+ }
+ if v[0] != '.' {
+ ok = false
+ return
+ }
+ p.patch, v, ok = parseInt(v[1:])
+ if !ok {
+ return
+ }
+ if len(v) > 0 && v[0] == '-' {
+ p.prerelease, v, ok = parsePrerelease(v)
+ if !ok {
+ return
+ }
+ }
+ if len(v) > 0 && v[0] == '+' {
+ p.build, v, ok = parseBuild(v)
+ if !ok {
+ return
+ }
+ }
+ if v != "" {
+ ok = false
+ return
+ }
+ ok = true
+ return
+}
+
+func parseInt(v string) (t, rest string, ok bool) {
+ if v == "" {
+ return
+ }
+ if v[0] < '0' || '9' < v[0] {
+ return
+ }
+ i := 1
+ for i < len(v) && '0' <= v[i] && v[i] <= '9' {
+ i++
+ }
+ if v[0] == '0' && i != 1 {
+ return
+ }
+ return v[:i], v[i:], true
+}
+
+func parsePrerelease(v string) (t, rest string, ok bool) {
+ // "A pre-release version MAY be denoted by appending a hyphen and
+ // a series of dot separated identifiers immediately following the patch version.
+ // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
+ // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes."
+ if v == "" || v[0] != '-' {
+ return
+ }
+ i := 1
+ start := 1
+ for i < len(v) && v[i] != '+' {
+ if !isIdentChar(v[i]) && v[i] != '.' {
+ return
+ }
+ if v[i] == '.' {
+ if start == i || isBadNum(v[start:i]) {
+ return
+ }
+ start = i + 1
+ }
+ i++
+ }
+ if start == i || isBadNum(v[start:i]) {
+ return
+ }
+ return v[:i], v[i:], true
+}
+
+func parseBuild(v string) (t, rest string, ok bool) {
+ if v == "" || v[0] != '+' {
+ return
+ }
+ i := 1
+ start := 1
+ for i < len(v) {
+ if !isIdentChar(v[i]) && v[i] != '.' {
+ return
+ }
+ if v[i] == '.' {
+ if start == i {
+ return
+ }
+ start = i + 1
+ }
+ i++
+ }
+ if start == i {
+ return
+ }
+ return v[:i], v[i:], true
+}
+
+func isIdentChar(c byte) bool {
+ return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'
+}
+
+func isBadNum(v string) bool {
+ i := 0
+ for i < len(v) && '0' <= v[i] && v[i] <= '9' {
+ i++
+ }
+ return i == len(v) && i > 1 && v[0] == '0'
+}
+
+func isNum(v string) bool {
+ i := 0
+ for i < len(v) && '0' <= v[i] && v[i] <= '9' {
+ i++
+ }
+ return i == len(v)
+}
+
+func compareInt(x, y string) int {
+ if x == y {
+ return 0
+ }
+ if len(x) < len(y) {
+ return -1
+ }
+ if len(x) > len(y) {
+ return +1
+ }
+ if x < y {
+ return -1
+ } else {
+ return +1
+ }
+}
+
+func comparePrerelease(x, y string) int {
+ // "When major, minor, and patch are equal, a pre-release version has
+ // lower precedence than a normal version.
+ // Example: 1.0.0-alpha < 1.0.0.
+ // Precedence for two pre-release versions with the same major, minor,
+ // and patch version MUST be determined by comparing each dot separated
+ // identifier from left to right until a difference is found as follows:
+ // identifiers consisting of only digits are compared numerically and
+ // identifiers with letters or hyphens are compared lexically in ASCII
+ // sort order. Numeric identifiers always have lower precedence than
+ // non-numeric identifiers. A larger set of pre-release fields has a
+ // higher precedence than a smaller set, if all of the preceding
+ // identifiers are equal.
+ // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <
+ // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0."
+ if x == y {
+ return 0
+ }
+ if x == "" {
+ return +1
+ }
+ if y == "" {
+ return -1
+ }
+ for x != "" && y != "" {
+ x = x[1:] // skip - or .
+ y = y[1:] // skip - or .
+ var dx, dy string
+ dx, x = nextIdent(x)
+ dy, y = nextIdent(y)
+ if dx != dy {
+ ix := isNum(dx)
+ iy := isNum(dy)
+ if ix != iy {
+ if ix {
+ return -1
+ } else {
+ return +1
+ }
+ }
+ if ix {
+ if len(dx) < len(dy) {
+ return -1
+ }
+ if len(dx) > len(dy) {
+ return +1
+ }
+ }
+ if dx < dy {
+ return -1
+ } else {
+ return +1
+ }
+ }
+ }
+ if x == "" {
+ return -1
+ } else {
+ return +1
+ }
+}
+
+func nextIdent(x string) (dx, rest string) {
+ i := 0
+ for i < len(x) && x[i] != '.' {
+ i++
+ }
+ return x[:i], x[i:]
+}
diff --git a/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s b/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s
new file mode 100644
index 00000000..269e173c
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s
@@ -0,0 +1,17 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc
+
+#include "textflag.h"
+
+//
+// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
+//
+
+TEXT ·syscall6(SB),NOSPLIT,$0-88
+ JMP syscall·syscall6(SB)
+
+TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
+ JMP syscall·rawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/cpu/byteorder.go b/vendor/golang.org/x/sys/cpu/byteorder.go
new file mode 100644
index 00000000..271055be
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/byteorder.go
@@ -0,0 +1,66 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+import (
+ "runtime"
+)
+
+// byteOrder is a subset of encoding/binary.ByteOrder.
+type byteOrder interface {
+ Uint32([]byte) uint32
+ Uint64([]byte) uint64
+}
+
+type littleEndian struct{}
+type bigEndian struct{}
+
+func (littleEndian) Uint32(b []byte) uint32 {
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+}
+
+func (littleEndian) Uint64(b []byte) uint64 {
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+ uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+}
+
+func (bigEndian) Uint32(b []byte) uint32 {
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+}
+
+func (bigEndian) Uint64(b []byte) uint64 {
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+}
+
+// hostByteOrder returns littleEndian on little-endian machines and
+// bigEndian on big-endian machines.
+func hostByteOrder() byteOrder {
+ switch runtime.GOARCH {
+ case "386", "amd64", "amd64p32",
+ "alpha",
+ "arm", "arm64",
+ "loong64",
+ "mipsle", "mips64le", "mips64p32le",
+ "nios2",
+ "ppc64le",
+ "riscv", "riscv64",
+ "sh":
+ return littleEndian{}
+ case "armbe", "arm64be",
+ "m68k",
+ "mips", "mips64", "mips64p32",
+ "ppc", "ppc64",
+ "s390", "s390x",
+ "shbe",
+ "sparc", "sparc64":
+ return bigEndian{}
+ }
+ panic("unknown architecture")
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go
new file mode 100644
index 00000000..8fa707aa
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu.go
@@ -0,0 +1,291 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cpu implements processor feature detection for
+// various CPU architectures.
+package cpu
+
+import (
+ "os"
+ "strings"
+)
+
+// Initialized reports whether the CPU features were initialized.
+//
+// For some GOOS/GOARCH combinations initialization of the CPU features depends
+// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm
+// Initialized will report false if reading the file fails.
+var Initialized bool
+
+// CacheLinePad is used to pad structs to avoid false sharing.
+type CacheLinePad struct{ _ [cacheLineSize]byte }
+
+// X86 contains the supported CPU features of the
+// current X86/AMD64 platform. If the current platform
+// is not X86/AMD64 then all feature flags are false.
+//
+// X86 is padded to avoid false sharing. Further the HasAVX
+// and HasAVX2 are only set if the OS supports XMM and YMM
+// registers in addition to the CPUID feature bit being set.
+var X86 struct {
+ _ CacheLinePad
+ HasAES bool // AES hardware implementation (AES NI)
+ HasADX bool // Multi-precision add-carry instruction extensions
+ HasAVX bool // Advanced vector extension
+ HasAVX2 bool // Advanced vector extension 2
+ HasAVX512 bool // Advanced vector extension 512
+ HasAVX512F bool // Advanced vector extension 512 Foundation Instructions
+ HasAVX512CD bool // Advanced vector extension 512 Conflict Detection Instructions
+ HasAVX512ER bool // Advanced vector extension 512 Exponential and Reciprocal Instructions
+ HasAVX512PF bool // Advanced vector extension 512 Prefetch Instructions
+ HasAVX512VL bool // Advanced vector extension 512 Vector Length Extensions
+ HasAVX512BW bool // Advanced vector extension 512 Byte and Word Instructions
+ HasAVX512DQ bool // Advanced vector extension 512 Doubleword and Quadword Instructions
+ HasAVX512IFMA bool // Advanced vector extension 512 Integer Fused Multiply Add
+ HasAVX512VBMI bool // Advanced vector extension 512 Vector Byte Manipulation Instructions
+ HasAVX5124VNNIW bool // Advanced vector extension 512 Vector Neural Network Instructions Word variable precision
+ HasAVX5124FMAPS bool // Advanced vector extension 512 Fused Multiply Accumulation Packed Single precision
+ HasAVX512VPOPCNTDQ bool // Advanced vector extension 512 Double and quad word population count instructions
+ HasAVX512VPCLMULQDQ bool // Advanced vector extension 512 Vector carry-less multiply operations
+ HasAVX512VNNI bool // Advanced vector extension 512 Vector Neural Network Instructions
+ HasAVX512GFNI bool // Advanced vector extension 512 Galois field New Instructions
+ HasAVX512VAES bool // Advanced vector extension 512 Vector AES instructions
+ HasAVX512VBMI2 bool // Advanced vector extension 512 Vector Byte Manipulation Instructions 2
+ HasAVX512BITALG bool // Advanced vector extension 512 Bit Algorithms
+ HasAVX512BF16 bool // Advanced vector extension 512 BFloat16 Instructions
+ HasAMXTile bool // Advanced Matrix Extension Tile instructions
+ HasAMXInt8 bool // Advanced Matrix Extension Int8 instructions
+ HasAMXBF16 bool // Advanced Matrix Extension BFloat16 instructions
+ HasBMI1 bool // Bit manipulation instruction set 1
+ HasBMI2 bool // Bit manipulation instruction set 2
+ HasCX16 bool // Compare and exchange 16 Bytes
+ HasERMS bool // Enhanced REP for MOVSB and STOSB
+ HasFMA bool // Fused-multiply-add instructions
+ HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
+ HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
+ HasPOPCNT bool // Hamming weight instruction POPCNT.
+ HasRDRAND bool // RDRAND instruction (on-chip random number generator)
+ HasRDSEED bool // RDSEED instruction (on-chip random number generator)
+ HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
+ HasSSE3 bool // Streaming SIMD extension 3
+ HasSSSE3 bool // Supplemental streaming SIMD extension 3
+ HasSSE41 bool // Streaming SIMD extension 4 and 4.1
+ HasSSE42 bool // Streaming SIMD extension 4 and 4.2
+ _ CacheLinePad
+}
+
+// ARM64 contains the supported CPU features of the
+// current ARMv8(aarch64) platform. If the current platform
+// is not arm64 then all feature flags are false.
+var ARM64 struct {
+ _ CacheLinePad
+ HasFP bool // Floating-point instruction set (always available)
+ HasASIMD bool // Advanced SIMD (always available)
+ HasEVTSTRM bool // Event stream support
+ HasAES bool // AES hardware implementation
+ HasPMULL bool // Polynomial multiplication instruction set
+ HasSHA1 bool // SHA1 hardware implementation
+ HasSHA2 bool // SHA2 hardware implementation
+ HasCRC32 bool // CRC32 hardware implementation
+ HasATOMICS bool // Atomic memory operation instruction set
+ HasFPHP bool // Half precision floating-point instruction set
+ HasASIMDHP bool // Advanced SIMD half precision instruction set
+ HasCPUID bool // CPUID identification scheme registers
+ HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
+ HasJSCVT bool // Javascript conversion from floating-point to integer
+ HasFCMA bool // Floating-point multiplication and addition of complex numbers
+ HasLRCPC bool // Release Consistent processor consistent support
+ HasDCPOP bool // Persistent memory support
+ HasSHA3 bool // SHA3 hardware implementation
+ HasSM3 bool // SM3 hardware implementation
+ HasSM4 bool // SM4 hardware implementation
+ 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
+}
+
+// ARM contains the supported CPU features of the current ARM (32-bit) platform.
+// All feature flags are false if:
+// 1. the current platform is not arm, or
+// 2. the current operating system is not Linux.
+var ARM struct {
+ _ CacheLinePad
+ HasSWP bool // SWP instruction support
+ HasHALF bool // Half-word load and store support
+ HasTHUMB bool // ARM Thumb instruction set
+ Has26BIT bool // Address space limited to 26-bits
+ HasFASTMUL bool // 32-bit operand, 64-bit result multiplication support
+ HasFPA bool // Floating point arithmetic support
+ HasVFP bool // Vector floating point support
+ HasEDSP bool // DSP Extensions support
+ HasJAVA bool // Java instruction set
+ HasIWMMXT bool // Intel Wireless MMX technology support
+ HasCRUNCH bool // MaverickCrunch context switching and handling
+ HasTHUMBEE bool // Thumb EE instruction set
+ HasNEON bool // NEON instruction set
+ HasVFPv3 bool // Vector floating point version 3 support
+ HasVFPv3D16 bool // Vector floating point version 3 D8-D15
+ HasTLS bool // Thread local storage support
+ HasVFPv4 bool // Vector floating point version 4 support
+ HasIDIVA bool // Integer divide instruction support in ARM mode
+ HasIDIVT bool // Integer divide instruction support in Thumb mode
+ HasVFPD32 bool // Vector floating point version 3 D15-D31
+ HasLPAE bool // Large Physical Address Extensions
+ HasEVTSTRM bool // Event stream support
+ HasAES bool // AES hardware implementation
+ HasPMULL bool // Polynomial multiplication instruction set
+ HasSHA1 bool // SHA1 hardware implementation
+ HasSHA2 bool // SHA2 hardware implementation
+ HasCRC32 bool // CRC32 hardware implementation
+ _ CacheLinePad
+}
+
+// MIPS64X contains the supported CPU features of the current mips64/mips64le
+// platforms. If the current platform is not mips64/mips64le or the current
+// operating system is not Linux then all feature flags are false.
+var MIPS64X struct {
+ _ CacheLinePad
+ HasMSA bool // MIPS SIMD architecture
+ _ CacheLinePad
+}
+
+// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
+// If the current platform is not ppc64/ppc64le then all feature flags are false.
+//
+// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
+// since there are no optional categories. There are some exceptions that also
+// require kernel support to work (DARN, SCV), so there are feature bits for
+// those as well. The struct is padded to avoid false sharing.
+var PPC64 struct {
+ _ CacheLinePad
+ HasDARN bool // Hardware random number generator (requires kernel enablement)
+ HasSCV bool // Syscall vectored (requires kernel enablement)
+ IsPOWER8 bool // ISA v2.07 (POWER8)
+ IsPOWER9 bool // ISA v3.00 (POWER9), implies IsPOWER8
+ _ CacheLinePad
+}
+
+// S390X contains the supported CPU features of the current IBM Z
+// (s390x) platform. If the current platform is not IBM Z then all
+// feature flags are false.
+//
+// S390X is padded to avoid false sharing. Further HasVX is only set
+// if the OS supports vector registers in addition to the STFLE
+// feature bit being set.
+var S390X struct {
+ _ CacheLinePad
+ HasZARCH bool // z/Architecture mode is active [mandatory]
+ HasSTFLE bool // store facility list extended
+ HasLDISP bool // long (20-bit) displacements
+ HasEIMM bool // 32-bit immediates
+ HasDFP bool // decimal floating point
+ HasETF3EH bool // ETF-3 enhanced
+ HasMSA bool // message security assist (CPACF)
+ HasAES bool // KM-AES{128,192,256} functions
+ HasAESCBC bool // KMC-AES{128,192,256} functions
+ HasAESCTR bool // KMCTR-AES{128,192,256} functions
+ HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
+ HasGHASH bool // KIMD-GHASH function
+ HasSHA1 bool // K{I,L}MD-SHA-1 functions
+ HasSHA256 bool // K{I,L}MD-SHA-256 functions
+ HasSHA512 bool // K{I,L}MD-SHA-512 functions
+ HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
+ HasVX bool // vector facility
+ HasVXE bool // vector-enhancements facility 1
+ _ CacheLinePad
+}
+
+func init() {
+ archInit()
+ initOptions()
+ processOptions()
+}
+
+// options contains the cpu debug options that can be used in GODEBUG.
+// Options are arch dependent and are added by the arch specific initOptions functions.
+// Features that are mandatory for the specific GOARCH should have the Required field set
+// (e.g. SSE2 on amd64).
+var options []option
+
+// Option names should be lower case. e.g. avx instead of AVX.
+type option struct {
+ Name string
+ Feature *bool
+ Specified bool // whether feature value was specified in GODEBUG
+ Enable bool // whether feature should be enabled
+ Required bool // whether feature is mandatory and can not be disabled
+}
+
+func processOptions() {
+ env := os.Getenv("GODEBUG")
+field:
+ for env != "" {
+ field := ""
+ i := strings.IndexByte(env, ',')
+ if i < 0 {
+ field, env = env, ""
+ } else {
+ field, env = env[:i], env[i+1:]
+ }
+ if len(field) < 4 || field[:4] != "cpu." {
+ continue
+ }
+ i = strings.IndexByte(field, '=')
+ if i < 0 {
+ print("GODEBUG sys/cpu: no value specified for \"", field, "\"\n")
+ continue
+ }
+ key, value := field[4:i], field[i+1:] // e.g. "SSE2", "on"
+
+ var enable bool
+ switch value {
+ case "on":
+ enable = true
+ case "off":
+ enable = false
+ default:
+ print("GODEBUG sys/cpu: value \"", value, "\" not supported for cpu option \"", key, "\"\n")
+ continue field
+ }
+
+ if key == "all" {
+ for i := range options {
+ options[i].Specified = true
+ options[i].Enable = enable || options[i].Required
+ }
+ continue field
+ }
+
+ for i := range options {
+ if options[i].Name == key {
+ options[i].Specified = true
+ options[i].Enable = enable
+ continue field
+ }
+ }
+
+ print("GODEBUG sys/cpu: unknown cpu feature \"", key, "\"\n")
+ }
+
+ for _, o := range options {
+ if !o.Specified {
+ continue
+ }
+
+ if o.Enable && !*o.Feature {
+ print("GODEBUG sys/cpu: can not enable \"", o.Name, "\", missing CPU support\n")
+ continue
+ }
+
+ if !o.Enable && o.Required {
+ print("GODEBUG sys/cpu: can not disable \"", o.Name, "\", required CPU feature\n")
+ continue
+ }
+
+ *o.Feature = o.Enable
+ }
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_aix.go b/vendor/golang.org/x/sys/cpu/cpu_aix.go
new file mode 100644
index 00000000..9bf0c32e
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_aix.go
@@ -0,0 +1,33 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix
+
+package cpu
+
+const (
+ // getsystemcfg constants
+ _SC_IMPL = 2
+ _IMPL_POWER8 = 0x10000
+ _IMPL_POWER9 = 0x20000
+)
+
+func archInit() {
+ impl := getsystemcfg(_SC_IMPL)
+ if impl&_IMPL_POWER8 != 0 {
+ PPC64.IsPOWER8 = true
+ }
+ if impl&_IMPL_POWER9 != 0 {
+ PPC64.IsPOWER8 = true
+ PPC64.IsPOWER9 = true
+ }
+
+ Initialized = true
+}
+
+func getsystemcfg(label int) (n uint64) {
+ r0, _ := callgetsystemcfg(label)
+ n = uint64(r0)
+ return
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm.go b/vendor/golang.org/x/sys/cpu/cpu_arm.go
new file mode 100644
index 00000000..301b752e
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_arm.go
@@ -0,0 +1,73 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+const cacheLineSize = 32
+
+// HWCAP/HWCAP2 bits.
+// These are specific to Linux.
+const (
+ hwcap_SWP = 1 << 0
+ hwcap_HALF = 1 << 1
+ hwcap_THUMB = 1 << 2
+ hwcap_26BIT = 1 << 3
+ hwcap_FAST_MULT = 1 << 4
+ hwcap_FPA = 1 << 5
+ hwcap_VFP = 1 << 6
+ hwcap_EDSP = 1 << 7
+ hwcap_JAVA = 1 << 8
+ hwcap_IWMMXT = 1 << 9
+ hwcap_CRUNCH = 1 << 10
+ hwcap_THUMBEE = 1 << 11
+ hwcap_NEON = 1 << 12
+ hwcap_VFPv3 = 1 << 13
+ hwcap_VFPv3D16 = 1 << 14
+ hwcap_TLS = 1 << 15
+ hwcap_VFPv4 = 1 << 16
+ hwcap_IDIVA = 1 << 17
+ hwcap_IDIVT = 1 << 18
+ hwcap_VFPD32 = 1 << 19
+ hwcap_LPAE = 1 << 20
+ hwcap_EVTSTRM = 1 << 21
+
+ hwcap2_AES = 1 << 0
+ hwcap2_PMULL = 1 << 1
+ hwcap2_SHA1 = 1 << 2
+ hwcap2_SHA2 = 1 << 3
+ hwcap2_CRC32 = 1 << 4
+)
+
+func initOptions() {
+ options = []option{
+ {Name: "pmull", Feature: &ARM.HasPMULL},
+ {Name: "sha1", Feature: &ARM.HasSHA1},
+ {Name: "sha2", Feature: &ARM.HasSHA2},
+ {Name: "swp", Feature: &ARM.HasSWP},
+ {Name: "thumb", Feature: &ARM.HasTHUMB},
+ {Name: "thumbee", Feature: &ARM.HasTHUMBEE},
+ {Name: "tls", Feature: &ARM.HasTLS},
+ {Name: "vfp", Feature: &ARM.HasVFP},
+ {Name: "vfpd32", Feature: &ARM.HasVFPD32},
+ {Name: "vfpv3", Feature: &ARM.HasVFPv3},
+ {Name: "vfpv3d16", Feature: &ARM.HasVFPv3D16},
+ {Name: "vfpv4", Feature: &ARM.HasVFPv4},
+ {Name: "half", Feature: &ARM.HasHALF},
+ {Name: "26bit", Feature: &ARM.Has26BIT},
+ {Name: "fastmul", Feature: &ARM.HasFASTMUL},
+ {Name: "fpa", Feature: &ARM.HasFPA},
+ {Name: "edsp", Feature: &ARM.HasEDSP},
+ {Name: "java", Feature: &ARM.HasJAVA},
+ {Name: "iwmmxt", Feature: &ARM.HasIWMMXT},
+ {Name: "crunch", Feature: &ARM.HasCRUNCH},
+ {Name: "neon", Feature: &ARM.HasNEON},
+ {Name: "idivt", Feature: &ARM.HasIDIVT},
+ {Name: "idiva", Feature: &ARM.HasIDIVA},
+ {Name: "lpae", Feature: &ARM.HasLPAE},
+ {Name: "evtstrm", Feature: &ARM.HasEVTSTRM},
+ {Name: "aes", Feature: &ARM.HasAES},
+ {Name: "crc32", Feature: &ARM.HasCRC32},
+ }
+
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_arm64.go
new file mode 100644
index 00000000..0e27a21e
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.go
@@ -0,0 +1,182 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+import "runtime"
+
+// cacheLineSize is used to prevent false sharing of cache lines.
+// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
+// It doesn't cost much and is much more future-proof.
+const cacheLineSize = 128
+
+func initOptions() {
+ options = []option{
+ {Name: "fp", Feature: &ARM64.HasFP},
+ {Name: "asimd", Feature: &ARM64.HasASIMD},
+ {Name: "evstrm", Feature: &ARM64.HasEVTSTRM},
+ {Name: "aes", Feature: &ARM64.HasAES},
+ {Name: "fphp", Feature: &ARM64.HasFPHP},
+ {Name: "jscvt", Feature: &ARM64.HasJSCVT},
+ {Name: "lrcpc", Feature: &ARM64.HasLRCPC},
+ {Name: "pmull", Feature: &ARM64.HasPMULL},
+ {Name: "sha1", Feature: &ARM64.HasSHA1},
+ {Name: "sha2", Feature: &ARM64.HasSHA2},
+ {Name: "sha3", Feature: &ARM64.HasSHA3},
+ {Name: "sha512", Feature: &ARM64.HasSHA512},
+ {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},
+ {Name: "cpuid", Feature: &ARM64.HasCPUID},
+ {Name: "asimrdm", Feature: &ARM64.HasASIMDRDM},
+ {Name: "fcma", Feature: &ARM64.HasFCMA},
+ {Name: "dcpop", Feature: &ARM64.HasDCPOP},
+ {Name: "asimddp", Feature: &ARM64.HasASIMDDP},
+ {Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM},
+ }
+}
+
+func archInit() {
+ switch runtime.GOOS {
+ case "freebsd":
+ readARM64Registers()
+ case "linux", "netbsd", "openbsd":
+ doinit()
+ default:
+ // Many platforms don't seem to allow reading these registers.
+ setMinimalFeatures()
+ }
+}
+
+// setMinimalFeatures fakes the minimal ARM64 features expected by
+// TestARM64minimalFeatures.
+func setMinimalFeatures() {
+ ARM64.HasASIMD = true
+ ARM64.HasFP = true
+}
+
+func readARM64Registers() {
+ Initialized = true
+
+ parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0())
+}
+
+func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
+ // ID_AA64ISAR0_EL1
+ switch extractBits(isar0, 4, 7) {
+ case 1:
+ ARM64.HasAES = true
+ case 2:
+ ARM64.HasAES = true
+ ARM64.HasPMULL = true
+ }
+
+ switch extractBits(isar0, 8, 11) {
+ case 1:
+ ARM64.HasSHA1 = true
+ }
+
+ switch extractBits(isar0, 12, 15) {
+ case 1:
+ ARM64.HasSHA2 = true
+ case 2:
+ ARM64.HasSHA2 = true
+ ARM64.HasSHA512 = true
+ }
+
+ switch extractBits(isar0, 16, 19) {
+ case 1:
+ ARM64.HasCRC32 = true
+ }
+
+ switch extractBits(isar0, 20, 23) {
+ case 2:
+ ARM64.HasATOMICS = true
+ }
+
+ switch extractBits(isar0, 28, 31) {
+ case 1:
+ ARM64.HasASIMDRDM = true
+ }
+
+ switch extractBits(isar0, 32, 35) {
+ case 1:
+ ARM64.HasSHA3 = true
+ }
+
+ switch extractBits(isar0, 36, 39) {
+ case 1:
+ ARM64.HasSM3 = true
+ }
+
+ switch extractBits(isar0, 40, 43) {
+ case 1:
+ ARM64.HasSM4 = true
+ }
+
+ switch extractBits(isar0, 44, 47) {
+ case 1:
+ ARM64.HasASIMDDP = true
+ }
+
+ // ID_AA64ISAR1_EL1
+ switch extractBits(isar1, 0, 3) {
+ case 1:
+ ARM64.HasDCPOP = true
+ }
+
+ switch extractBits(isar1, 12, 15) {
+ case 1:
+ ARM64.HasJSCVT = true
+ }
+
+ switch extractBits(isar1, 16, 19) {
+ case 1:
+ ARM64.HasFCMA = true
+ }
+
+ switch extractBits(isar1, 20, 23) {
+ case 1:
+ ARM64.HasLRCPC = true
+ }
+
+ // ID_AA64PFR0_EL1
+ switch extractBits(pfr0, 16, 19) {
+ case 0:
+ ARM64.HasFP = true
+ case 1:
+ ARM64.HasFP = true
+ ARM64.HasFPHP = true
+ }
+
+ switch extractBits(pfr0, 20, 23) {
+ case 0:
+ ARM64.HasASIMD = true
+ case 1:
+ ARM64.HasASIMD = true
+ ARM64.HasASIMDHP = true
+ }
+
+ 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
+ }
+}
+
+func extractBits(data uint64, start, end uint) uint {
+ return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/vendor/golang.org/x/sys/cpu/cpu_arm64.s
new file mode 100644
index 00000000..22cc9984
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.s
@@ -0,0 +1,39 @@
+// 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 gc
+
+#include "textflag.h"
+
+// func getisar0() uint64
+TEXT ·getisar0(SB),NOSPLIT,$0-8
+ // get Instruction Set Attributes 0 into x0
+ // mrs x0, ID_AA64ISAR0_EL1 = d5380600
+ WORD $0xd5380600
+ MOVD R0, ret+0(FP)
+ RET
+
+// func getisar1() uint64
+TEXT ·getisar1(SB),NOSPLIT,$0-8
+ // get Instruction Set Attributes 1 into x0
+ // mrs x0, ID_AA64ISAR1_EL1 = d5380620
+ WORD $0xd5380620
+ MOVD R0, ret+0(FP)
+ RET
+
+// func getpfr0() uint64
+TEXT ·getpfr0(SB),NOSPLIT,$0-8
+ // get Processor Feature Register 0 into x0
+ // mrs x0, ID_AA64PFR0_EL1 = d5380400
+ 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
new file mode 100644
index 00000000..6ac6e1ef
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
@@ -0,0 +1,12 @@
+// 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 gc
+
+package cpu
+
+func getisar0() uint64
+func getisar1() uint64
+func getpfr0() uint64
+func getzfr0() uint64
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go
new file mode 100644
index 00000000..c8ae6ddc
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go
@@ -0,0 +1,21 @@
+// 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 gc
+
+package cpu
+
+// haveAsmFunctions reports whether the other functions in this file can
+// be safely called.
+func haveAsmFunctions() bool { return true }
+
+// The following feature detection functions are defined in cpu_s390x.s.
+// They are likely to be expensive to call so the results should be cached.
+func stfle() facilityList
+func kmQuery() queryResult
+func kmcQuery() queryResult
+func kmctrQuery() queryResult
+func kmaQuery() queryResult
+func kimdQuery() queryResult
+func klmdQuery() queryResult
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
new file mode 100644
index 00000000..910728fb
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
@@ -0,0 +1,15 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (386 || amd64 || amd64p32) && gc
+
+package cpu
+
+// cpuid is implemented in cpu_x86.s for gc compiler
+// and in cpu_gccgo.c for gccgo.
+func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
+
+// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
+// and in cpu_gccgo.c for gccgo.
+func xgetbv() (eax, edx uint32)
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go
new file mode 100644
index 00000000..7f194678
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go
@@ -0,0 +1,11 @@
+// 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 gccgo
+
+package cpu
+
+func getisar0() uint64 { return 0 }
+func getisar1() uint64 { return 0 }
+func getpfr0() uint64 { return 0 }
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go
new file mode 100644
index 00000000..9526d2ce
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go
@@ -0,0 +1,22 @@
+// 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 gccgo
+
+package cpu
+
+// haveAsmFunctions reports whether the other functions in this file can
+// be safely called.
+func haveAsmFunctions() bool { return false }
+
+// TODO(mundaym): the following feature detection functions are currently
+// stubs. See https://golang.org/cl/162887 for how to fix this.
+// They are likely to be expensive to call so the results should be cached.
+func stfle() facilityList { panic("not implemented for gccgo") }
+func kmQuery() queryResult { panic("not implemented for gccgo") }
+func kmcQuery() queryResult { panic("not implemented for gccgo") }
+func kmctrQuery() queryResult { panic("not implemented for gccgo") }
+func kmaQuery() queryResult { panic("not implemented for gccgo") }
+func kimdQuery() queryResult { panic("not implemented for gccgo") }
+func klmdQuery() queryResult { panic("not implemented for gccgo") }
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c
new file mode 100644
index 00000000..3f73a05d
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c
@@ -0,0 +1,37 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (386 || amd64 || amd64p32) && gccgo
+
+#include
+#include
+#include
+
+// Need to wrap __get_cpuid_count because it's declared as static.
+int
+gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
+}
+
+#pragma GCC diagnostic ignored "-Wunknown-pragmas"
+#pragma GCC push_options
+#pragma GCC target("xsave")
+#pragma clang attribute push (__attribute__((target("xsave"))), apply_to=function)
+
+// xgetbv reads the contents of an XCR (Extended Control Register)
+// specified in the ECX register into registers EDX:EAX.
+// Currently, the only supported value for XCR is 0.
+void
+gccgoXgetbv(uint32_t *eax, uint32_t *edx)
+{
+ uint64_t v = _xgetbv(0);
+ *eax = v & 0xffffffff;
+ *edx = v >> 32;
+}
+
+#pragma clang attribute pop
+#pragma GCC pop_options
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
new file mode 100644
index 00000000..99c60fe9
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
@@ -0,0 +1,31 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (386 || amd64 || amd64p32) && gccgo
+
+package cpu
+
+//extern gccgoGetCpuidCount
+func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)
+
+func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
+ var a, b, c, d uint32
+ gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)
+ return a, b, c, d
+}
+
+//extern gccgoXgetbv
+func gccgoXgetbv(eax, edx *uint32)
+
+func xgetbv() (eax, edx uint32) {
+ var a, d uint32
+ gccgoXgetbv(&a, &d)
+ return a, d
+}
+
+// gccgo doesn't build on Darwin, per:
+// https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/gcc.rb#L76
+func darwinSupportsAVX512() bool {
+ return false
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux.go b/vendor/golang.org/x/sys/cpu/cpu_linux.go
new file mode 100644
index 00000000..743eb543
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux.go
@@ -0,0 +1,15 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !386 && !amd64 && !amd64p32 && !arm64
+
+package cpu
+
+func archInit() {
+ if err := readHWCAP(); err != nil {
+ return
+ }
+ doinit()
+ Initialized = true
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_arm.go b/vendor/golang.org/x/sys/cpu/cpu_linux_arm.go
new file mode 100644
index 00000000..2057006d
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_arm.go
@@ -0,0 +1,39 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+func doinit() {
+ ARM.HasSWP = isSet(hwCap, hwcap_SWP)
+ ARM.HasHALF = isSet(hwCap, hwcap_HALF)
+ ARM.HasTHUMB = isSet(hwCap, hwcap_THUMB)
+ ARM.Has26BIT = isSet(hwCap, hwcap_26BIT)
+ ARM.HasFASTMUL = isSet(hwCap, hwcap_FAST_MULT)
+ ARM.HasFPA = isSet(hwCap, hwcap_FPA)
+ ARM.HasVFP = isSet(hwCap, hwcap_VFP)
+ ARM.HasEDSP = isSet(hwCap, hwcap_EDSP)
+ ARM.HasJAVA = isSet(hwCap, hwcap_JAVA)
+ ARM.HasIWMMXT = isSet(hwCap, hwcap_IWMMXT)
+ ARM.HasCRUNCH = isSet(hwCap, hwcap_CRUNCH)
+ ARM.HasTHUMBEE = isSet(hwCap, hwcap_THUMBEE)
+ ARM.HasNEON = isSet(hwCap, hwcap_NEON)
+ ARM.HasVFPv3 = isSet(hwCap, hwcap_VFPv3)
+ ARM.HasVFPv3D16 = isSet(hwCap, hwcap_VFPv3D16)
+ ARM.HasTLS = isSet(hwCap, hwcap_TLS)
+ ARM.HasVFPv4 = isSet(hwCap, hwcap_VFPv4)
+ ARM.HasIDIVA = isSet(hwCap, hwcap_IDIVA)
+ ARM.HasIDIVT = isSet(hwCap, hwcap_IDIVT)
+ ARM.HasVFPD32 = isSet(hwCap, hwcap_VFPD32)
+ ARM.HasLPAE = isSet(hwCap, hwcap_LPAE)
+ ARM.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
+ ARM.HasAES = isSet(hwCap2, hwcap2_AES)
+ ARM.HasPMULL = isSet(hwCap2, hwcap2_PMULL)
+ ARM.HasSHA1 = isSet(hwCap2, hwcap2_SHA1)
+ ARM.HasSHA2 = isSet(hwCap2, hwcap2_SHA2)
+ ARM.HasCRC32 = isSet(hwCap2, hwcap2_CRC32)
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
new file mode 100644
index 00000000..3d386d0f
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
@@ -0,0 +1,116 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+import (
+ "strings"
+ "syscall"
+)
+
+// HWCAP/HWCAP2 bits. These are exposed by Linux.
+const (
+ hwcap_FP = 1 << 0
+ hwcap_ASIMD = 1 << 1
+ hwcap_EVTSTRM = 1 << 2
+ hwcap_AES = 1 << 3
+ hwcap_PMULL = 1 << 4
+ hwcap_SHA1 = 1 << 5
+ hwcap_SHA2 = 1 << 6
+ hwcap_CRC32 = 1 << 7
+ hwcap_ATOMICS = 1 << 8
+ hwcap_FPHP = 1 << 9
+ hwcap_ASIMDHP = 1 << 10
+ hwcap_CPUID = 1 << 11
+ hwcap_ASIMDRDM = 1 << 12
+ hwcap_JSCVT = 1 << 13
+ hwcap_FCMA = 1 << 14
+ hwcap_LRCPC = 1 << 15
+ hwcap_DCPOP = 1 << 16
+ hwcap_SHA3 = 1 << 17
+ hwcap_SM3 = 1 << 18
+ hwcap_SM4 = 1 << 19
+ hwcap_ASIMDDP = 1 << 20
+ hwcap_SHA512 = 1 << 21
+ hwcap_SVE = 1 << 22
+ hwcap_ASIMDFHM = 1 << 23
+
+ hwcap2_SVE2 = 1 << 1
+)
+
+// linuxKernelCanEmulateCPUID reports whether we're running
+// on Linux 4.11+. Ideally we'd like to ask the question about
+// whether the current kernel contains
+// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=77c97b4ee21290f5f083173d957843b615abbff2
+// but the version number will have to do.
+func linuxKernelCanEmulateCPUID() bool {
+ var un syscall.Utsname
+ syscall.Uname(&un)
+ var sb strings.Builder
+ for _, b := range un.Release[:] {
+ if b == 0 {
+ break
+ }
+ sb.WriteByte(byte(b))
+ }
+ major, minor, _, ok := parseRelease(sb.String())
+ return ok && (major > 4 || major == 4 && minor >= 11)
+}
+
+func doinit() {
+ if err := readHWCAP(); err != nil {
+ // We failed to read /proc/self/auxv. This can happen if the binary has
+ // been given extra capabilities(7) with /bin/setcap.
+ //
+ // When this happens, we have two options. If the Linux kernel is new
+ // enough (4.11+), we can read the arm64 registers directly which'll
+ // trap into the kernel and then return back to userspace.
+ //
+ // But on older kernels, such as Linux 4.4.180 as used on many Synology
+ // devices, calling readARM64Registers (specifically getisar0) will
+ // cause a SIGILL and we'll die. So for older kernels, parse /proc/cpuinfo
+ // instead.
+ //
+ // See golang/go#57336.
+ if linuxKernelCanEmulateCPUID() {
+ readARM64Registers()
+ } else {
+ readLinuxProcCPUInfo()
+ }
+ return
+ }
+
+ // HWCAP feature bits
+ ARM64.HasFP = isSet(hwCap, hwcap_FP)
+ ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD)
+ ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
+ ARM64.HasAES = isSet(hwCap, hwcap_AES)
+ ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL)
+ ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1)
+ ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2)
+ ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32)
+ ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS)
+ ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP)
+ ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP)
+ ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID)
+ ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM)
+ ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT)
+ ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA)
+ ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC)
+ ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP)
+ ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3)
+ ARM64.HasSM3 = isSet(hwCap, hwcap_SM3)
+ ARM64.HasSM4 = isSet(hwCap, hwcap_SM4)
+ ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP)
+ 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 {
+ return hwc&value != 0
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go b/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go
new file mode 100644
index 00000000..4686c1d5
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go
@@ -0,0 +1,22 @@
+// 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 linux && (mips64 || mips64le)
+
+package cpu
+
+// HWCAP bits. These are exposed by the Linux kernel 5.4.
+const (
+ // CPU features
+ hwcap_MIPS_MSA = 1 << 1
+)
+
+func doinit() {
+ // HWCAP feature bits
+ MIPS64X.HasMSA = isSet(hwCap, hwcap_MIPS_MSA)
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
new file mode 100644
index 00000000..cd63e733
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
@@ -0,0 +1,9 @@
+// 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 linux && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x
+
+package cpu
+
+func doinit() {}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go b/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
new file mode 100644
index 00000000..197188e6
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
@@ -0,0 +1,30 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && (ppc64 || ppc64le)
+
+package cpu
+
+// HWCAP/HWCAP2 bits. These are exposed by the kernel.
+const (
+ // ISA Level
+ _PPC_FEATURE2_ARCH_2_07 = 0x80000000
+ _PPC_FEATURE2_ARCH_3_00 = 0x00800000
+
+ // CPU features
+ _PPC_FEATURE2_DARN = 0x00200000
+ _PPC_FEATURE2_SCV = 0x00100000
+)
+
+func doinit() {
+ // HWCAP2 feature bits
+ PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07)
+ PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00)
+ PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN)
+ PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV)
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go
new file mode 100644
index 00000000..1517ac61
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go
@@ -0,0 +1,40 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+const (
+ // bit mask values from /usr/include/bits/hwcap.h
+ hwcap_ZARCH = 2
+ hwcap_STFLE = 4
+ hwcap_MSA = 8
+ hwcap_LDISP = 16
+ hwcap_EIMM = 32
+ hwcap_DFP = 64
+ hwcap_ETF3EH = 256
+ hwcap_VX = 2048
+ hwcap_VXE = 8192
+)
+
+func initS390Xbase() {
+ // test HWCAP bit vector
+ has := func(featureMask uint) bool {
+ return hwCap&featureMask == featureMask
+ }
+
+ // mandatory
+ S390X.HasZARCH = has(hwcap_ZARCH)
+
+ // optional
+ S390X.HasSTFLE = has(hwcap_STFLE)
+ S390X.HasLDISP = has(hwcap_LDISP)
+ S390X.HasEIMM = has(hwcap_EIMM)
+ S390X.HasETF3EH = has(hwcap_ETF3EH)
+ S390X.HasDFP = has(hwcap_DFP)
+ S390X.HasMSA = has(hwcap_MSA)
+ S390X.HasVX = has(hwcap_VX)
+ if S390X.HasVX {
+ S390X.HasVXE = has(hwcap_VXE)
+ }
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_loong64.go b/vendor/golang.org/x/sys/cpu/cpu_loong64.go
new file mode 100644
index 00000000..55863585
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_loong64.go
@@ -0,0 +1,12 @@
+// 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 loong64
+
+package cpu
+
+const cacheLineSize = 64
+
+func initOptions() {
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_mips64x.go b/vendor/golang.org/x/sys/cpu/cpu_mips64x.go
new file mode 100644
index 00000000..fedb00cc
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_mips64x.go
@@ -0,0 +1,15 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build mips64 || mips64le
+
+package cpu
+
+const cacheLineSize = 32
+
+func initOptions() {
+ options = []option{
+ {Name: "msa", Feature: &MIPS64X.HasMSA},
+ }
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_mipsx.go b/vendor/golang.org/x/sys/cpu/cpu_mipsx.go
new file mode 100644
index 00000000..ffb4ec7e
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_mipsx.go
@@ -0,0 +1,11 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build mips || mipsle
+
+package cpu
+
+const cacheLineSize = 32
+
+func initOptions() {}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go
new file mode 100644
index 00000000..ebfb3fc8
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go
@@ -0,0 +1,173 @@
+// 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.
+
+package cpu
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+// Minimal copy of functionality from x/sys/unix so the cpu package can call
+// sysctl without depending on x/sys/unix.
+
+const (
+ _CTL_QUERY = -2
+
+ _SYSCTL_VERS_1 = 0x1000000
+)
+
+var _zero uintptr
+
+func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+ var _p0 unsafe.Pointer
+ if len(mib) > 0 {
+ _p0 = unsafe.Pointer(&mib[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, errno := syscall.Syscall6(
+ syscall.SYS___SYSCTL,
+ uintptr(_p0),
+ uintptr(len(mib)),
+ uintptr(unsafe.Pointer(old)),
+ uintptr(unsafe.Pointer(oldlen)),
+ uintptr(unsafe.Pointer(new)),
+ uintptr(newlen))
+ if errno != 0 {
+ return errno
+ }
+ return nil
+}
+
+type sysctlNode struct {
+ Flags uint32
+ Num int32
+ Name [32]int8
+ Ver uint32
+ __rsvd uint32
+ Un [16]byte
+ _sysctl_size [8]byte
+ _sysctl_func [8]byte
+ _sysctl_parent [8]byte
+ _sysctl_desc [8]byte
+}
+
+func sysctlNodes(mib []int32) ([]sysctlNode, error) {
+ var olen uintptr
+
+ // Get a list of all sysctl nodes below the given MIB by performing
+ // a sysctl for the given MIB with CTL_QUERY appended.
+ mib = append(mib, _CTL_QUERY)
+ qnode := sysctlNode{Flags: _SYSCTL_VERS_1}
+ qp := (*byte)(unsafe.Pointer(&qnode))
+ sz := unsafe.Sizeof(qnode)
+ if err := sysctl(mib, nil, &olen, qp, sz); err != nil {
+ return nil, err
+ }
+
+ // Now that we know the size, get the actual nodes.
+ nodes := make([]sysctlNode, olen/sz)
+ np := (*byte)(unsafe.Pointer(&nodes[0]))
+ if err := sysctl(mib, np, &olen, qp, sz); err != nil {
+ return nil, err
+ }
+
+ return nodes, nil
+}
+
+func nametomib(name string) ([]int32, error) {
+ // Split name into components.
+ var parts []string
+ last := 0
+ for i := 0; i < len(name); i++ {
+ if name[i] == '.' {
+ parts = append(parts, name[last:i])
+ last = i + 1
+ }
+ }
+ parts = append(parts, name[last:])
+
+ mib := []int32{}
+ // Discover the nodes and construct the MIB OID.
+ for partno, part := range parts {
+ nodes, err := sysctlNodes(mib)
+ if err != nil {
+ return nil, err
+ }
+ for _, node := range nodes {
+ n := make([]byte, 0)
+ for i := range node.Name {
+ if node.Name[i] != 0 {
+ n = append(n, byte(node.Name[i]))
+ }
+ }
+ if string(n) == part {
+ mib = append(mib, int32(node.Num))
+ break
+ }
+ }
+ if len(mib) != partno+1 {
+ return nil, err
+ }
+ }
+
+ return mib, nil
+}
+
+// aarch64SysctlCPUID is struct aarch64_sysctl_cpu_id from NetBSD's
+type aarch64SysctlCPUID struct {
+ midr uint64 /* Main ID Register */
+ revidr uint64 /* Revision ID Register */
+ mpidr uint64 /* Multiprocessor Affinity Register */
+ aa64dfr0 uint64 /* A64 Debug Feature Register 0 */
+ aa64dfr1 uint64 /* A64 Debug Feature Register 1 */
+ aa64isar0 uint64 /* A64 Instruction Set Attribute Register 0 */
+ aa64isar1 uint64 /* A64 Instruction Set Attribute Register 1 */
+ aa64mmfr0 uint64 /* A64 Memory Model Feature Register 0 */
+ aa64mmfr1 uint64 /* A64 Memory Model Feature Register 1 */
+ aa64mmfr2 uint64 /* A64 Memory Model Feature Register 2 */
+ aa64pfr0 uint64 /* A64 Processor Feature Register 0 */
+ aa64pfr1 uint64 /* A64 Processor Feature Register 1 */
+ aa64zfr0 uint64 /* A64 SVE Feature ID Register 0 */
+ mvfr0 uint32 /* Media and VFP Feature Register 0 */
+ mvfr1 uint32 /* Media and VFP Feature Register 1 */
+ mvfr2 uint32 /* Media and VFP Feature Register 2 */
+ pad uint32
+ clidr uint64 /* Cache Level ID Register */
+ ctr uint64 /* Cache Type Register */
+}
+
+func sysctlCPUID(name string) (*aarch64SysctlCPUID, error) {
+ mib, err := nametomib(name)
+ if err != nil {
+ return nil, err
+ }
+
+ out := aarch64SysctlCPUID{}
+ n := unsafe.Sizeof(out)
+ _, _, errno := syscall.Syscall6(
+ syscall.SYS___SYSCTL,
+ uintptr(unsafe.Pointer(&mib[0])),
+ uintptr(len(mib)),
+ uintptr(unsafe.Pointer(&out)),
+ uintptr(unsafe.Pointer(&n)),
+ uintptr(0),
+ uintptr(0))
+ if errno != 0 {
+ return nil, errno
+ }
+ return &out, nil
+}
+
+func doinit() {
+ cpuid, err := sysctlCPUID("machdep.cpu0.cpu_id")
+ if err != nil {
+ setMinimalFeatures()
+ return
+ }
+ parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0)
+
+ Initialized = true
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go
new file mode 100644
index 00000000..85b64d5c
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go
@@ -0,0 +1,65 @@
+// 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 cpu
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+// Minimal copy of functionality from x/sys/unix so the cpu package can call
+// sysctl without depending on x/sys/unix.
+
+const (
+ // From OpenBSD's sys/sysctl.h.
+ _CTL_MACHDEP = 7
+
+ // From OpenBSD's machine/cpu.h.
+ _CPU_ID_AA64ISAR0 = 2
+ _CPU_ID_AA64ISAR1 = 3
+)
+
+// Implemented in the runtime package (runtime/sys_openbsd3.go)
+func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscall6 syscall.syscall6
+
+func sysctl(mib []uint32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+ _, _, errno := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+ if errno != 0 {
+ return errno
+ }
+ return nil
+}
+
+var libc_sysctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
+func sysctlUint64(mib []uint32) (uint64, bool) {
+ var out uint64
+ nout := unsafe.Sizeof(out)
+ if err := sysctl(mib, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); err != nil {
+ return 0, false
+ }
+ return out, true
+}
+
+func doinit() {
+ setMinimalFeatures()
+
+ // Get ID_AA64ISAR0 and ID_AA64ISAR1 from sysctl.
+ isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})
+ if !ok {
+ return
+ }
+ isar1, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR1})
+ if !ok {
+ return
+ }
+ parseARM64SystemRegisters(isar0, isar1, 0)
+
+ Initialized = true
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s
new file mode 100644
index 00000000..054ba05d
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s
@@ -0,0 +1,11 @@
+// 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.
+
+#include "textflag.h"
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_sysctl(SB)
+
+GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
+DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
diff --git a/vendor/golang.org/x/sys/cpu/cpu_other_arm.go b/vendor/golang.org/x/sys/cpu/cpu_other_arm.go
new file mode 100644
index 00000000..e9ecf2a4
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_other_arm.go
@@ -0,0 +1,9 @@
+// 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 !linux && arm
+
+package cpu
+
+func archInit() {}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
new file mode 100644
index 00000000..5341e7f8
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
@@ -0,0 +1,9 @@
+// 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 !linux && !netbsd && !openbsd && arm64
+
+package cpu
+
+func doinit() {}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go b/vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go
new file mode 100644
index 00000000..5f8f2419
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go
@@ -0,0 +1,11 @@
+// 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 !linux && (mips64 || mips64le)
+
+package cpu
+
+func archInit() {
+ Initialized = true
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go b/vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go
new file mode 100644
index 00000000..89608fba
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go
@@ -0,0 +1,12 @@
+// 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 !aix && !linux && (ppc64 || ppc64le)
+
+package cpu
+
+func archInit() {
+ PPC64.IsPOWER8 = true
+ Initialized = true
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go
new file mode 100644
index 00000000..5ab87808
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go
@@ -0,0 +1,11 @@
+// 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 !linux && riscv64
+
+package cpu
+
+func archInit() {
+ Initialized = true
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_ppc64x.go b/vendor/golang.org/x/sys/cpu/cpu_ppc64x.go
new file mode 100644
index 00000000..c14f12b1
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_ppc64x.go
@@ -0,0 +1,16 @@
+// 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 ppc64 || ppc64le
+
+package cpu
+
+const cacheLineSize = 128
+
+func initOptions() {
+ options = []option{
+ {Name: "darn", Feature: &PPC64.HasDARN},
+ {Name: "scv", Feature: &PPC64.HasSCV},
+ }
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go
new file mode 100644
index 00000000..7f0c79c0
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go
@@ -0,0 +1,11 @@
+// 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 riscv64
+
+package cpu
+
+const cacheLineSize = 64
+
+func initOptions() {}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_s390x.go
new file mode 100644
index 00000000..5881b883
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_s390x.go
@@ -0,0 +1,172 @@
+// 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.
+
+package cpu
+
+const cacheLineSize = 256
+
+func initOptions() {
+ options = []option{
+ {Name: "zarch", Feature: &S390X.HasZARCH, Required: true},
+ {Name: "stfle", Feature: &S390X.HasSTFLE, Required: true},
+ {Name: "ldisp", Feature: &S390X.HasLDISP, Required: true},
+ {Name: "eimm", Feature: &S390X.HasEIMM, Required: true},
+ {Name: "dfp", Feature: &S390X.HasDFP},
+ {Name: "etf3eh", Feature: &S390X.HasETF3EH},
+ {Name: "msa", Feature: &S390X.HasMSA},
+ {Name: "aes", Feature: &S390X.HasAES},
+ {Name: "aescbc", Feature: &S390X.HasAESCBC},
+ {Name: "aesctr", Feature: &S390X.HasAESCTR},
+ {Name: "aesgcm", Feature: &S390X.HasAESGCM},
+ {Name: "ghash", Feature: &S390X.HasGHASH},
+ {Name: "sha1", Feature: &S390X.HasSHA1},
+ {Name: "sha256", Feature: &S390X.HasSHA256},
+ {Name: "sha3", Feature: &S390X.HasSHA3},
+ {Name: "sha512", Feature: &S390X.HasSHA512},
+ {Name: "vx", Feature: &S390X.HasVX},
+ {Name: "vxe", Feature: &S390X.HasVXE},
+ }
+}
+
+// bitIsSet reports whether the bit at index is set. The bit index
+// is in big endian order, so bit index 0 is the leftmost bit.
+func bitIsSet(bits []uint64, index uint) bool {
+ return bits[index/64]&((1<<63)>>(index%64)) != 0
+}
+
+// facility is a bit index for the named facility.
+type facility uint8
+
+const (
+ // mandatory facilities
+ zarch facility = 1 // z architecture mode is active
+ stflef facility = 7 // store-facility-list-extended
+ ldisp facility = 18 // long-displacement
+ eimm facility = 21 // extended-immediate
+
+ // miscellaneous facilities
+ dfp facility = 42 // decimal-floating-point
+ etf3eh facility = 30 // extended-translation 3 enhancement
+
+ // cryptography facilities
+ msa facility = 17 // message-security-assist
+ msa3 facility = 76 // message-security-assist extension 3
+ msa4 facility = 77 // message-security-assist extension 4
+ msa5 facility = 57 // message-security-assist extension 5
+ msa8 facility = 146 // message-security-assist extension 8
+ msa9 facility = 155 // message-security-assist extension 9
+
+ // vector facilities
+ vx facility = 129 // vector facility
+ vxe facility = 135 // vector-enhancements 1
+ vxe2 facility = 148 // vector-enhancements 2
+)
+
+// facilityList contains the result of an STFLE call.
+// Bits are numbered in big endian order so the
+// leftmost bit (the MSB) is at index 0.
+type facilityList struct {
+ bits [4]uint64
+}
+
+// Has reports whether the given facilities are present.
+func (s *facilityList) Has(fs ...facility) bool {
+ if len(fs) == 0 {
+ panic("no facility bits provided")
+ }
+ for _, f := range fs {
+ if !bitIsSet(s.bits[:], uint(f)) {
+ return false
+ }
+ }
+ return true
+}
+
+// function is the code for the named cryptographic function.
+type function uint8
+
+const (
+ // KM{,A,C,CTR} function codes
+ aes128 function = 18 // AES-128
+ aes192 function = 19 // AES-192
+ aes256 function = 20 // AES-256
+
+ // K{I,L}MD function codes
+ sha1 function = 1 // SHA-1
+ sha256 function = 2 // SHA-256
+ sha512 function = 3 // SHA-512
+ sha3_224 function = 32 // SHA3-224
+ sha3_256 function = 33 // SHA3-256
+ sha3_384 function = 34 // SHA3-384
+ sha3_512 function = 35 // SHA3-512
+ shake128 function = 36 // SHAKE-128
+ shake256 function = 37 // SHAKE-256
+
+ // KLMD function codes
+ ghash function = 65 // GHASH
+)
+
+// queryResult contains the result of a Query function
+// call. Bits are numbered in big endian order so the
+// leftmost bit (the MSB) is at index 0.
+type queryResult struct {
+ bits [2]uint64
+}
+
+// Has reports whether the given functions are present.
+func (q *queryResult) Has(fns ...function) bool {
+ if len(fns) == 0 {
+ panic("no function codes provided")
+ }
+ for _, f := range fns {
+ if !bitIsSet(q.bits[:], uint(f)) {
+ return false
+ }
+ }
+ return true
+}
+
+func doinit() {
+ initS390Xbase()
+
+ // We need implementations of stfle, km and so on
+ // to detect cryptographic features.
+ if !haveAsmFunctions() {
+ return
+ }
+
+ // optional cryptographic functions
+ if S390X.HasMSA {
+ aes := []function{aes128, aes192, aes256}
+
+ // cipher message
+ km, kmc := kmQuery(), kmcQuery()
+ S390X.HasAES = km.Has(aes...)
+ S390X.HasAESCBC = kmc.Has(aes...)
+ if S390X.HasSTFLE {
+ facilities := stfle()
+ if facilities.Has(msa4) {
+ kmctr := kmctrQuery()
+ S390X.HasAESCTR = kmctr.Has(aes...)
+ }
+ if facilities.Has(msa8) {
+ kma := kmaQuery()
+ S390X.HasAESGCM = kma.Has(aes...)
+ }
+ }
+
+ // compute message digest
+ kimd := kimdQuery() // intermediate (no padding)
+ klmd := klmdQuery() // last (padding)
+ S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
+ S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
+ S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
+ S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
+ sha3 := []function{
+ sha3_224, sha3_256, sha3_384, sha3_512,
+ shake128, shake256,
+ }
+ S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
+ }
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_s390x.s b/vendor/golang.org/x/sys/cpu/cpu_s390x.s
new file mode 100644
index 00000000..1fb4b701
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_s390x.s
@@ -0,0 +1,57 @@
+// 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 gc
+
+#include "textflag.h"
+
+// func stfle() facilityList
+TEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32
+ MOVD $ret+0(FP), R1
+ MOVD $3, R0 // last doubleword index to store
+ XC $32, (R1), (R1) // clear 4 doublewords (32 bytes)
+ WORD $0xb2b01000 // store facility list extended (STFLE)
+ RET
+
+// func kmQuery() queryResult
+TEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KM-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB92E0024 // cipher message (KM)
+ RET
+
+// func kmcQuery() queryResult
+TEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KMC-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB92F0024 // cipher message with chaining (KMC)
+ RET
+
+// func kmctrQuery() queryResult
+TEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KMCTR-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB92D4024 // cipher message with counter (KMCTR)
+ RET
+
+// func kmaQuery() queryResult
+TEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KMA-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xb9296024 // cipher message with authentication (KMA)
+ RET
+
+// func kimdQuery() queryResult
+TEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KIMD-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB93E0024 // compute intermediate message digest (KIMD)
+ RET
+
+// func klmdQuery() queryResult
+TEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KLMD-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB93F0024 // compute last message digest (KLMD)
+ RET
diff --git a/vendor/golang.org/x/sys/cpu/cpu_wasm.go b/vendor/golang.org/x/sys/cpu/cpu_wasm.go
new file mode 100644
index 00000000..384787ea
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_wasm.go
@@ -0,0 +1,17 @@
+// 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 wasm
+
+package cpu
+
+// We're compiling the cpu package for an unknown (software-abstracted) CPU.
+// Make CacheLinePad an empty struct and hope that the usual struct alignment
+// rules are good enough.
+
+const cacheLineSize = 0
+
+func initOptions() {}
+
+func archInit() {}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_x86.go b/vendor/golang.org/x/sys/cpu/cpu_x86.go
new file mode 100644
index 00000000..c29f5e4c
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_x86.go
@@ -0,0 +1,151 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build 386 || amd64 || amd64p32
+
+package cpu
+
+import "runtime"
+
+const cacheLineSize = 64
+
+func initOptions() {
+ options = []option{
+ {Name: "adx", Feature: &X86.HasADX},
+ {Name: "aes", Feature: &X86.HasAES},
+ {Name: "avx", Feature: &X86.HasAVX},
+ {Name: "avx2", Feature: &X86.HasAVX2},
+ {Name: "avx512", Feature: &X86.HasAVX512},
+ {Name: "avx512f", Feature: &X86.HasAVX512F},
+ {Name: "avx512cd", Feature: &X86.HasAVX512CD},
+ {Name: "avx512er", Feature: &X86.HasAVX512ER},
+ {Name: "avx512pf", Feature: &X86.HasAVX512PF},
+ {Name: "avx512vl", Feature: &X86.HasAVX512VL},
+ {Name: "avx512bw", Feature: &X86.HasAVX512BW},
+ {Name: "avx512dq", Feature: &X86.HasAVX512DQ},
+ {Name: "avx512ifma", Feature: &X86.HasAVX512IFMA},
+ {Name: "avx512vbmi", Feature: &X86.HasAVX512VBMI},
+ {Name: "avx512vnniw", Feature: &X86.HasAVX5124VNNIW},
+ {Name: "avx5124fmaps", Feature: &X86.HasAVX5124FMAPS},
+ {Name: "avx512vpopcntdq", Feature: &X86.HasAVX512VPOPCNTDQ},
+ {Name: "avx512vpclmulqdq", Feature: &X86.HasAVX512VPCLMULQDQ},
+ {Name: "avx512vnni", Feature: &X86.HasAVX512VNNI},
+ {Name: "avx512gfni", Feature: &X86.HasAVX512GFNI},
+ {Name: "avx512vaes", Feature: &X86.HasAVX512VAES},
+ {Name: "avx512vbmi2", Feature: &X86.HasAVX512VBMI2},
+ {Name: "avx512bitalg", Feature: &X86.HasAVX512BITALG},
+ {Name: "avx512bf16", Feature: &X86.HasAVX512BF16},
+ {Name: "amxtile", Feature: &X86.HasAMXTile},
+ {Name: "amxint8", Feature: &X86.HasAMXInt8},
+ {Name: "amxbf16", Feature: &X86.HasAMXBF16},
+ {Name: "bmi1", Feature: &X86.HasBMI1},
+ {Name: "bmi2", Feature: &X86.HasBMI2},
+ {Name: "cx16", Feature: &X86.HasCX16},
+ {Name: "erms", Feature: &X86.HasERMS},
+ {Name: "fma", Feature: &X86.HasFMA},
+ {Name: "osxsave", Feature: &X86.HasOSXSAVE},
+ {Name: "pclmulqdq", Feature: &X86.HasPCLMULQDQ},
+ {Name: "popcnt", Feature: &X86.HasPOPCNT},
+ {Name: "rdrand", Feature: &X86.HasRDRAND},
+ {Name: "rdseed", Feature: &X86.HasRDSEED},
+ {Name: "sse3", Feature: &X86.HasSSE3},
+ {Name: "sse41", Feature: &X86.HasSSE41},
+ {Name: "sse42", Feature: &X86.HasSSE42},
+ {Name: "ssse3", Feature: &X86.HasSSSE3},
+
+ // These capabilities should always be enabled on amd64:
+ {Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"},
+ }
+}
+
+func archInit() {
+
+ Initialized = true
+
+ maxID, _, _, _ := cpuid(0, 0)
+
+ if maxID < 1 {
+ return
+ }
+
+ _, _, ecx1, edx1 := cpuid(1, 0)
+ X86.HasSSE2 = isSet(26, edx1)
+
+ X86.HasSSE3 = isSet(0, ecx1)
+ X86.HasPCLMULQDQ = isSet(1, ecx1)
+ X86.HasSSSE3 = isSet(9, ecx1)
+ X86.HasFMA = isSet(12, ecx1)
+ X86.HasCX16 = isSet(13, ecx1)
+ X86.HasSSE41 = isSet(19, ecx1)
+ X86.HasSSE42 = isSet(20, ecx1)
+ X86.HasPOPCNT = isSet(23, ecx1)
+ X86.HasAES = isSet(25, ecx1)
+ X86.HasOSXSAVE = isSet(27, ecx1)
+ X86.HasRDRAND = isSet(30, ecx1)
+
+ var osSupportsAVX, osSupportsAVX512 bool
+ // For XGETBV, OSXSAVE bit is required and sufficient.
+ if X86.HasOSXSAVE {
+ eax, _ := xgetbv()
+ // Check if XMM and YMM registers have OS support.
+ osSupportsAVX = isSet(1, eax) && isSet(2, eax)
+
+ if runtime.GOOS == "darwin" {
+ // Darwin doesn't save/restore AVX-512 mask registers correctly across signal handlers.
+ // Since users can't rely on mask register contents, let's not advertise AVX-512 support.
+ // See issue 49233.
+ osSupportsAVX512 = false
+ } else {
+ // Check if OPMASK and ZMM registers have OS support.
+ osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)
+ }
+ }
+
+ X86.HasAVX = isSet(28, ecx1) && osSupportsAVX
+
+ if maxID < 7 {
+ return
+ }
+
+ _, ebx7, ecx7, edx7 := cpuid(7, 0)
+ X86.HasBMI1 = isSet(3, ebx7)
+ X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
+ X86.HasBMI2 = isSet(8, ebx7)
+ X86.HasERMS = isSet(9, ebx7)
+ X86.HasRDSEED = isSet(18, ebx7)
+ X86.HasADX = isSet(19, ebx7)
+
+ X86.HasAVX512 = isSet(16, ebx7) && osSupportsAVX512 // Because avx-512 foundation is the core required extension
+ if X86.HasAVX512 {
+ X86.HasAVX512F = true
+ X86.HasAVX512CD = isSet(28, ebx7)
+ X86.HasAVX512ER = isSet(27, ebx7)
+ X86.HasAVX512PF = isSet(26, ebx7)
+ X86.HasAVX512VL = isSet(31, ebx7)
+ X86.HasAVX512BW = isSet(30, ebx7)
+ X86.HasAVX512DQ = isSet(17, ebx7)
+ X86.HasAVX512IFMA = isSet(21, ebx7)
+ X86.HasAVX512VBMI = isSet(1, ecx7)
+ X86.HasAVX5124VNNIW = isSet(2, edx7)
+ X86.HasAVX5124FMAPS = isSet(3, edx7)
+ X86.HasAVX512VPOPCNTDQ = isSet(14, ecx7)
+ X86.HasAVX512VPCLMULQDQ = isSet(10, ecx7)
+ X86.HasAVX512VNNI = isSet(11, ecx7)
+ X86.HasAVX512GFNI = isSet(8, ecx7)
+ X86.HasAVX512VAES = isSet(9, ecx7)
+ X86.HasAVX512VBMI2 = isSet(6, ecx7)
+ X86.HasAVX512BITALG = isSet(12, ecx7)
+
+ eax71, _, _, _ := cpuid(7, 1)
+ X86.HasAVX512BF16 = isSet(5, eax71)
+ }
+
+ X86.HasAMXTile = isSet(24, edx7)
+ X86.HasAMXInt8 = isSet(25, edx7)
+ X86.HasAMXBF16 = isSet(22, edx7)
+}
+
+func isSet(bitpos uint, value uint32) bool {
+ return value&(1<> 63))
+)
+
+// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
+// These are initialized in cpu_$GOARCH.go
+// and should not be changed after they are initialized.
+var hwCap uint
+var hwCap2 uint
+
+func readHWCAP() error {
+ // For Go 1.21+, get auxv from the Go runtime.
+ if a := getAuxv(); len(a) > 0 {
+ for len(a) >= 2 {
+ tag, val := a[0], uint(a[1])
+ a = a[2:]
+ switch tag {
+ case _AT_HWCAP:
+ hwCap = val
+ case _AT_HWCAP2:
+ hwCap2 = val
+ }
+ }
+ return nil
+ }
+
+ buf, err := os.ReadFile(procAuxv)
+ if err != nil {
+ // e.g. on android /proc/self/auxv is not accessible, so silently
+ // ignore the error and leave Initialized = false. On some
+ // architectures (e.g. arm64) doinit() implements a fallback
+ // readout and will set Initialized = true again.
+ return err
+ }
+ bo := hostByteOrder()
+ for len(buf) >= 2*(uintSize/8) {
+ var tag, val uint
+ switch uintSize {
+ case 32:
+ tag = uint(bo.Uint32(buf[0:]))
+ val = uint(bo.Uint32(buf[4:]))
+ buf = buf[8:]
+ case 64:
+ tag = uint(bo.Uint64(buf[0:]))
+ val = uint(bo.Uint64(buf[8:]))
+ buf = buf[16:]
+ }
+ switch tag {
+ case _AT_HWCAP:
+ hwCap = val
+ case _AT_HWCAP2:
+ hwCap2 = val
+ }
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/sys/cpu/parse.go b/vendor/golang.org/x/sys/cpu/parse.go
new file mode 100644
index 00000000..762b63d6
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/parse.go
@@ -0,0 +1,43 @@
+// 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 cpu
+
+import "strconv"
+
+// parseRelease parses a dot-separated version number. It follows the semver
+// syntax, but allows the minor and patch versions to be elided.
+//
+// This is a copy of the Go runtime's parseRelease from
+// https://golang.org/cl/209597.
+func parseRelease(rel string) (major, minor, patch int, ok bool) {
+ // Strip anything after a dash or plus.
+ for i := 0; i < len(rel); i++ {
+ if rel[i] == '-' || rel[i] == '+' {
+ rel = rel[:i]
+ break
+ }
+ }
+
+ next := func() (int, bool) {
+ for i := 0; i < len(rel); i++ {
+ if rel[i] == '.' {
+ ver, err := strconv.Atoi(rel[:i])
+ rel = rel[i+1:]
+ return ver, err == nil
+ }
+ }
+ ver, err := strconv.Atoi(rel)
+ rel = ""
+ return ver, err == nil
+ }
+ if major, ok = next(); !ok || rel == "" {
+ return
+ }
+ if minor, ok = next(); !ok || rel == "" {
+ return
+ }
+ patch, ok = next()
+ return
+}
diff --git a/vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go b/vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go
new file mode 100644
index 00000000..4cd64c70
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go
@@ -0,0 +1,53 @@
+// 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 linux && arm64
+
+package cpu
+
+import (
+ "errors"
+ "io"
+ "os"
+ "strings"
+)
+
+func readLinuxProcCPUInfo() error {
+ f, err := os.Open("/proc/cpuinfo")
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ var buf [1 << 10]byte // enough for first CPU
+ n, err := io.ReadFull(f, buf[:])
+ if err != nil && err != io.ErrUnexpectedEOF {
+ return err
+ }
+ in := string(buf[:n])
+ const features = "\nFeatures : "
+ i := strings.Index(in, features)
+ if i == -1 {
+ return errors.New("no CPU features found")
+ }
+ in = in[i+len(features):]
+ if i := strings.Index(in, "\n"); i != -1 {
+ in = in[:i]
+ }
+ m := map[string]*bool{}
+
+ initOptions() // need it early here; it's harmless to call twice
+ for _, o := range options {
+ m[o.Name] = o.Feature
+ }
+ // The EVTSTRM field has alias "evstrm" in Go, but Linux calls it "evtstrm".
+ m["evtstrm"] = &ARM64.HasEVTSTRM
+
+ for _, f := range strings.Fields(in) {
+ if p, ok := m[f]; ok {
+ *p = true
+ }
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/sys/cpu/runtime_auxv.go b/vendor/golang.org/x/sys/cpu/runtime_auxv.go
new file mode 100644
index 00000000..5f92ac9a
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/runtime_auxv.go
@@ -0,0 +1,16 @@
+// 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 cpu
+
+// getAuxvFn is non-nil on Go 1.21+ (via runtime_auxv_go121.go init)
+// on platforms that use auxv.
+var getAuxvFn func() []uintptr
+
+func getAuxv() []uintptr {
+ if getAuxvFn == nil {
+ return nil
+ }
+ return getAuxvFn()
+}
diff --git a/vendor/golang.org/x/sys/cpu/runtime_auxv_go121.go b/vendor/golang.org/x/sys/cpu/runtime_auxv_go121.go
new file mode 100644
index 00000000..4c9788ea
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/runtime_auxv_go121.go
@@ -0,0 +1,18 @@
+// 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 go1.21
+
+package cpu
+
+import (
+ _ "unsafe" // for linkname
+)
+
+//go:linkname runtime_getAuxv runtime.getAuxv
+func runtime_getAuxv() []uintptr
+
+func init() {
+ getAuxvFn = runtime_getAuxv
+}
diff --git a/vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go b/vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go
new file mode 100644
index 00000000..1b9ccb09
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go
@@ -0,0 +1,26 @@
+// 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.
+
+// Recreate a getsystemcfg syscall handler instead of
+// using the one provided by x/sys/unix to avoid having
+// the dependency between them. (See golang.org/issue/32102)
+// Moreover, this file will be used during the building of
+// gccgo's libgo and thus must not used a CGo method.
+
+//go:build aix && gccgo
+
+package cpu
+
+import (
+ "syscall"
+)
+
+//extern getsystemcfg
+func gccgoGetsystemcfg(label uint32) (r uint64)
+
+func callgetsystemcfg(label int) (r1 uintptr, e1 syscall.Errno) {
+ r1 = uintptr(gccgoGetsystemcfg(uint32(label)))
+ e1 = syscall.GetErrno()
+ return
+}
diff --git a/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go b/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go
new file mode 100644
index 00000000..e8b6cdbe
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go
@@ -0,0 +1,35 @@
+// 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.
+
+// Minimal copy of x/sys/unix so the cpu package can make a
+// system call on AIX without depending on x/sys/unix.
+// (See golang.org/issue/32102)
+
+//go:build aix && ppc64 && gc
+
+package cpu
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+//go:cgo_import_dynamic libc_getsystemcfg getsystemcfg "libc.a/shr_64.o"
+
+//go:linkname libc_getsystemcfg libc_getsystemcfg
+
+type syscallFunc uintptr
+
+var libc_getsystemcfg syscallFunc
+
+type errno = syscall.Errno
+
+// Implemented in runtime/syscall_aix.go.
+func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)
+func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)
+
+func callgetsystemcfg(label int) (r1 uintptr, e1 errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getsystemcfg)), 1, uintptr(label), 0, 0, 0, 0, 0)
+ return
+}
diff --git a/vendor/golang.org/x/sys/execabs/execabs.go b/vendor/golang.org/x/sys/execabs/execabs.go
new file mode 100644
index 00000000..3bf40fdf
--- /dev/null
+++ b/vendor/golang.org/x/sys/execabs/execabs.go
@@ -0,0 +1,102 @@
+// 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.
+
+// Package execabs is a drop-in replacement for os/exec
+// that requires PATH lookups to find absolute paths.
+// That is, execabs.Command("cmd") runs the same PATH lookup
+// as exec.Command("cmd"), but if the result is a path
+// which is relative, the Run and Start methods will report
+// an error instead of running the executable.
+//
+// See https://blog.golang.org/path-security for more information
+// about when it may be necessary or appropriate to use this package.
+package execabs
+
+import (
+ "context"
+ "fmt"
+ "os/exec"
+ "path/filepath"
+ "reflect"
+ "unsafe"
+)
+
+// ErrNotFound is the error resulting if a path search failed to find an executable file.
+// It is an alias for exec.ErrNotFound.
+var ErrNotFound = exec.ErrNotFound
+
+// Cmd represents an external command being prepared or run.
+// It is an alias for exec.Cmd.
+type Cmd = exec.Cmd
+
+// Error is returned by LookPath when it fails to classify a file as an executable.
+// It is an alias for exec.Error.
+type Error = exec.Error
+
+// An ExitError reports an unsuccessful exit by a command.
+// It is an alias for exec.ExitError.
+type ExitError = exec.ExitError
+
+func relError(file, path string) error {
+ return fmt.Errorf("%s resolves to executable in current directory (.%c%s)", file, filepath.Separator, path)
+}
+
+// LookPath searches for an executable named file in the directories
+// named by the PATH environment variable. If file contains a slash,
+// it is tried directly and the PATH is not consulted. The result will be
+// an absolute path.
+//
+// LookPath differs from exec.LookPath in its handling of PATH lookups,
+// which are used for file names without slashes. If exec.LookPath's
+// PATH lookup would have returned an executable from the current directory,
+// LookPath instead returns an error.
+func LookPath(file string) (string, error) {
+ path, err := exec.LookPath(file)
+ if err != nil && !isGo119ErrDot(err) {
+ return "", err
+ }
+ if filepath.Base(file) == file && !filepath.IsAbs(path) {
+ return "", relError(file, path)
+ }
+ return path, nil
+}
+
+func fixCmd(name string, cmd *exec.Cmd) {
+ if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) && !isGo119ErrFieldSet(cmd) {
+ // exec.Command was called with a bare binary name and
+ // exec.LookPath returned a path which is not absolute.
+ // Set cmd.lookPathErr and clear cmd.Path so that it
+ // cannot be run.
+ lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer()))
+ if *lookPathErr == nil {
+ *lookPathErr = relError(name, cmd.Path)
+ }
+ cmd.Path = ""
+ }
+}
+
+// CommandContext is like Command but includes a context.
+//
+// The provided context is used to kill the process (by calling os.Process.Kill)
+// if the context becomes done before the command completes on its own.
+func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd {
+ cmd := exec.CommandContext(ctx, name, arg...)
+ fixCmd(name, cmd)
+ return cmd
+
+}
+
+// Command returns the Cmd struct to execute the named program with the given arguments.
+// See exec.Command for most details.
+//
+// Command differs from exec.Command in its handling of PATH lookups,
+// which are used when the program name contains no slashes.
+// If exec.Command would have returned an exec.Cmd configured to run an
+// executable from the current directory, Command instead
+// returns an exec.Cmd that will return an error from Start or Run.
+func Command(name string, arg ...string) *exec.Cmd {
+ cmd := exec.Command(name, arg...)
+ fixCmd(name, cmd)
+ return cmd
+}
diff --git a/vendor/golang.org/x/sys/execabs/execabs_go118.go b/vendor/golang.org/x/sys/execabs/execabs_go118.go
new file mode 100644
index 00000000..5627d70e
--- /dev/null
+++ b/vendor/golang.org/x/sys/execabs/execabs_go118.go
@@ -0,0 +1,17 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.19
+
+package execabs
+
+import "os/exec"
+
+func isGo119ErrDot(err error) bool {
+ return false
+}
+
+func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
+ return false
+}
diff --git a/vendor/golang.org/x/sys/execabs/execabs_go119.go b/vendor/golang.org/x/sys/execabs/execabs_go119.go
new file mode 100644
index 00000000..d60ab1b4
--- /dev/null
+++ b/vendor/golang.org/x/sys/execabs/execabs_go119.go
@@ -0,0 +1,20 @@
+// 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.19
+
+package execabs
+
+import (
+ "errors"
+ "os/exec"
+)
+
+func isGo119ErrDot(err error) bool {
+ return errors.Is(err, exec.ErrDot)
+}
+
+func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
+ return cmd.Err != nil
+}
diff --git a/vendor/golang.org/x/tools/cmd/stringer/stringer.go b/vendor/golang.org/x/tools/cmd/stringer/stringer.go
new file mode 100644
index 00000000..2b19c93e
--- /dev/null
+++ b/vendor/golang.org/x/tools/cmd/stringer/stringer.go
@@ -0,0 +1,660 @@
+// 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.
+
+// Stringer is a tool to automate the creation of methods that satisfy the fmt.Stringer
+// interface. Given the name of a (signed or unsigned) integer type T that has constants
+// defined, stringer will create a new self-contained Go source file implementing
+//
+// func (t T) String() string
+//
+// The file is created in the same package and directory as the package that defines T.
+// It has helpful defaults designed for use with go generate.
+//
+// Stringer works best with constants that are consecutive values such as created using iota,
+// but creates good code regardless. In the future it might also provide custom support for
+// constant sets that are bit patterns.
+//
+// For example, given this snippet,
+//
+// package painkiller
+//
+// type Pill int
+//
+// const (
+// Placebo Pill = iota
+// Aspirin
+// Ibuprofen
+// Paracetamol
+// Acetaminophen = Paracetamol
+// )
+//
+// running this command
+//
+// stringer -type=Pill
+//
+// in the same directory will create the file pill_string.go, in package painkiller,
+// containing a definition of
+//
+// func (Pill) String() string
+//
+// That method will translate the value of a Pill constant to the string representation
+// of the respective constant name, so that the call fmt.Print(painkiller.Aspirin) will
+// print the string "Aspirin".
+//
+// Typically this process would be run using go generate, like this:
+//
+// //go:generate stringer -type=Pill
+//
+// If multiple constants have the same value, the lexically first matching name will
+// be used (in the example, Acetaminophen will print as "Paracetamol").
+//
+// With no arguments, it processes the package in the current directory.
+// Otherwise, the arguments must name a single directory holding a Go package
+// or a set of Go source files that represent a single Go package.
+//
+// The -type flag accepts a comma-separated list of types so a single run can
+// generate methods for multiple types. The default output file is t_string.go,
+// where t is the lower-cased name of the first type listed. It can be overridden
+// with the -output flag.
+//
+// The -linecomment flag tells stringer to generate the text of any line comment, trimmed
+// of leading spaces, instead of the constant name. For instance, if the constants above had a
+// Pill prefix, one could write
+//
+// PillAspirin // Aspirin
+//
+// to suppress it in the output.
+package main // import "golang.org/x/tools/cmd/stringer"
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "go/ast"
+ "go/constant"
+ "go/format"
+ "go/token"
+ "go/types"
+ "log"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "golang.org/x/tools/go/packages"
+)
+
+var (
+ typeNames = flag.String("type", "", "comma-separated list of type names; must be set")
+ output = flag.String("output", "", "output file name; default srcdir/_string.go")
+ trimprefix = flag.String("trimprefix", "", "trim the `prefix` from the generated constant names")
+ linecomment = flag.Bool("linecomment", false, "use line comment text as printed text when present")
+ buildTags = flag.String("tags", "", "comma-separated list of build tags to apply")
+)
+
+// Usage is a replacement usage function for the flags package.
+func Usage() {
+ fmt.Fprintf(os.Stderr, "Usage of stringer:\n")
+ fmt.Fprintf(os.Stderr, "\tstringer [flags] -type T [directory]\n")
+ fmt.Fprintf(os.Stderr, "\tstringer [flags] -type T files... # Must be a single package\n")
+ fmt.Fprintf(os.Stderr, "For more information, see:\n")
+ fmt.Fprintf(os.Stderr, "\thttps://pkg.go.dev/golang.org/x/tools/cmd/stringer\n")
+ fmt.Fprintf(os.Stderr, "Flags:\n")
+ flag.PrintDefaults()
+}
+
+func main() {
+ log.SetFlags(0)
+ log.SetPrefix("stringer: ")
+ flag.Usage = Usage
+ flag.Parse()
+ if len(*typeNames) == 0 {
+ flag.Usage()
+ os.Exit(2)
+ }
+ types := strings.Split(*typeNames, ",")
+ var tags []string
+ if len(*buildTags) > 0 {
+ tags = strings.Split(*buildTags, ",")
+ }
+
+ // We accept either one directory or a list of files. Which do we have?
+ args := flag.Args()
+ if len(args) == 0 {
+ // Default: process whole package in current directory.
+ args = []string{"."}
+ }
+
+ // Parse the package once.
+ var dir string
+ g := Generator{
+ trimPrefix: *trimprefix,
+ lineComment: *linecomment,
+ }
+ // TODO(suzmue): accept other patterns for packages (directories, list of files, import paths, etc).
+ if len(args) == 1 && isDirectory(args[0]) {
+ dir = args[0]
+ } else {
+ if len(tags) != 0 {
+ log.Fatal("-tags option applies only to directories, not when files are specified")
+ }
+ dir = filepath.Dir(args[0])
+ }
+
+ g.parsePackage(args, tags)
+
+ // Print the header and package clause.
+ g.Printf("// Code generated by \"stringer %s\"; DO NOT EDIT.\n", strings.Join(os.Args[1:], " "))
+ g.Printf("\n")
+ g.Printf("package %s", g.pkg.name)
+ g.Printf("\n")
+ g.Printf("import \"strconv\"\n") // Used by all methods.
+
+ // Run generate for each type.
+ for _, typeName := range types {
+ g.generate(typeName)
+ }
+
+ // Format the output.
+ src := g.format()
+
+ // Write to file.
+ outputName := *output
+ if outputName == "" {
+ baseName := fmt.Sprintf("%s_string.go", types[0])
+ outputName = filepath.Join(dir, strings.ToLower(baseName))
+ }
+ err := os.WriteFile(outputName, src, 0644)
+ if err != nil {
+ log.Fatalf("writing output: %s", err)
+ }
+}
+
+// isDirectory reports whether the named file is a directory.
+func isDirectory(name string) bool {
+ info, err := os.Stat(name)
+ if err != nil {
+ log.Fatal(err)
+ }
+ return info.IsDir()
+}
+
+// Generator holds the state of the analysis. Primarily used to buffer
+// the output for format.Source.
+type Generator struct {
+ buf bytes.Buffer // Accumulated output.
+ pkg *Package // Package we are scanning.
+
+ trimPrefix string
+ lineComment bool
+
+ logf func(format string, args ...interface{}) // test logging hook; nil when not testing
+}
+
+func (g *Generator) Printf(format string, args ...interface{}) {
+ fmt.Fprintf(&g.buf, format, args...)
+}
+
+// File holds a single parsed file and associated data.
+type File struct {
+ pkg *Package // Package to which this file belongs.
+ file *ast.File // Parsed AST.
+ // These fields are reset for each type being generated.
+ typeName string // Name of the constant type.
+ values []Value // Accumulator for constant values of that type.
+
+ trimPrefix string
+ lineComment bool
+}
+
+type Package struct {
+ name string
+ defs map[*ast.Ident]types.Object
+ files []*File
+}
+
+// parsePackage analyzes the single package constructed from the patterns and tags.
+// parsePackage exits if there is an error.
+func (g *Generator) parsePackage(patterns []string, tags []string) {
+ cfg := &packages.Config{
+ Mode: packages.NeedName | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax,
+ // TODO: Need to think about constants in test files. Maybe write type_string_test.go
+ // in a separate pass? For later.
+ Tests: false,
+ BuildFlags: []string{fmt.Sprintf("-tags=%s", strings.Join(tags, " "))},
+ Logf: g.logf,
+ }
+ pkgs, err := packages.Load(cfg, patterns...)
+ if err != nil {
+ log.Fatal(err)
+ }
+ if len(pkgs) != 1 {
+ log.Fatalf("error: %d packages matching %v", len(pkgs), strings.Join(patterns, " "))
+ }
+ g.addPackage(pkgs[0])
+}
+
+// addPackage adds a type checked Package and its syntax files to the generator.
+func (g *Generator) addPackage(pkg *packages.Package) {
+ g.pkg = &Package{
+ name: pkg.Name,
+ defs: pkg.TypesInfo.Defs,
+ files: make([]*File, len(pkg.Syntax)),
+ }
+
+ for i, file := range pkg.Syntax {
+ g.pkg.files[i] = &File{
+ file: file,
+ pkg: g.pkg,
+ trimPrefix: g.trimPrefix,
+ lineComment: g.lineComment,
+ }
+ }
+}
+
+// generate produces the String method for the named type.
+func (g *Generator) generate(typeName string) {
+ values := make([]Value, 0, 100)
+ for _, file := range g.pkg.files {
+ // Set the state for this run of the walker.
+ file.typeName = typeName
+ file.values = nil
+ if file.file != nil {
+ ast.Inspect(file.file, file.genDecl)
+ values = append(values, file.values...)
+ }
+ }
+
+ if len(values) == 0 {
+ log.Fatalf("no values defined for type %s", typeName)
+ }
+ // Generate code that will fail if the constants change value.
+ g.Printf("func _() {\n")
+ g.Printf("\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n")
+ g.Printf("\t// Re-run the stringer command to generate them again.\n")
+ g.Printf("\tvar x [1]struct{}\n")
+ for _, v := range values {
+ g.Printf("\t_ = x[%s - %s]\n", v.originalName, v.str)
+ }
+ g.Printf("}\n")
+ runs := splitIntoRuns(values)
+ // The decision of which pattern to use depends on the number of
+ // runs in the numbers. If there's only one, it's easy. For more than
+ // one, there's a tradeoff between complexity and size of the data
+ // and code vs. the simplicity of a map. A map takes more space,
+ // but so does the code. The decision here (crossover at 10) is
+ // arbitrary, but considers that for large numbers of runs the cost
+ // of the linear scan in the switch might become important, and
+ // rather than use yet another algorithm such as binary search,
+ // we punt and use a map. In any case, the likelihood of a map
+ // being necessary for any realistic example other than bitmasks
+ // is very low. And bitmasks probably deserve their own analysis,
+ // to be done some other day.
+ switch {
+ case len(runs) == 1:
+ g.buildOneRun(runs, typeName)
+ case len(runs) <= 10:
+ g.buildMultipleRuns(runs, typeName)
+ default:
+ g.buildMap(runs, typeName)
+ }
+}
+
+// splitIntoRuns breaks the values into runs of contiguous sequences.
+// For example, given 1,2,3,5,6,7 it returns {1,2,3},{5,6,7}.
+// The input slice is known to be non-empty.
+func splitIntoRuns(values []Value) [][]Value {
+ // We use stable sort so the lexically first name is chosen for equal elements.
+ sort.Stable(byValue(values))
+ // Remove duplicates. Stable sort has put the one we want to print first,
+ // so use that one. The String method won't care about which named constant
+ // was the argument, so the first name for the given value is the only one to keep.
+ // We need to do this because identical values would cause the switch or map
+ // to fail to compile.
+ j := 1
+ for i := 1; i < len(values); i++ {
+ if values[i].value != values[i-1].value {
+ values[j] = values[i]
+ j++
+ }
+ }
+ values = values[:j]
+ runs := make([][]Value, 0, 10)
+ for len(values) > 0 {
+ // One contiguous sequence per outer loop.
+ i := 1
+ for i < len(values) && values[i].value == values[i-1].value+1 {
+ i++
+ }
+ runs = append(runs, values[:i])
+ values = values[i:]
+ }
+ return runs
+}
+
+// format returns the gofmt-ed contents of the Generator's buffer.
+func (g *Generator) format() []byte {
+ src, err := format.Source(g.buf.Bytes())
+ if err != nil {
+ // Should never happen, but can arise when developing this code.
+ // The user can compile the output to see the error.
+ log.Printf("warning: internal error: invalid Go generated: %s", err)
+ log.Printf("warning: compile the package to analyze the error")
+ return g.buf.Bytes()
+ }
+ return src
+}
+
+// Value represents a declared constant.
+type Value struct {
+ originalName string // The name of the constant.
+ name string // The name with trimmed prefix.
+ // The value is stored as a bit pattern alone. The boolean tells us
+ // whether to interpret it as an int64 or a uint64; the only place
+ // this matters is when sorting.
+ // Much of the time the str field is all we need; it is printed
+ // by Value.String.
+ value uint64 // Will be converted to int64 when needed.
+ signed bool // Whether the constant is a signed type.
+ str string // The string representation given by the "go/constant" package.
+}
+
+func (v *Value) String() string {
+ return v.str
+}
+
+// byValue lets us sort the constants into increasing order.
+// We take care in the Less method to sort in signed or unsigned order,
+// as appropriate.
+type byValue []Value
+
+func (b byValue) Len() int { return len(b) }
+func (b byValue) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
+func (b byValue) Less(i, j int) bool {
+ if b[i].signed {
+ return int64(b[i].value) < int64(b[j].value)
+ }
+ return b[i].value < b[j].value
+}
+
+// genDecl processes one declaration clause.
+func (f *File) genDecl(node ast.Node) bool {
+ decl, ok := node.(*ast.GenDecl)
+ if !ok || decl.Tok != token.CONST {
+ // We only care about const declarations.
+ return true
+ }
+ // The name of the type of the constants we are declaring.
+ // Can change if this is a multi-element declaration.
+ typ := ""
+ // Loop over the elements of the declaration. Each element is a ValueSpec:
+ // a list of names possibly followed by a type, possibly followed by values.
+ // If the type and value are both missing, we carry down the type (and value,
+ // but the "go/types" package takes care of that).
+ for _, spec := range decl.Specs {
+ vspec := spec.(*ast.ValueSpec) // Guaranteed to succeed as this is CONST.
+ if vspec.Type == nil && len(vspec.Values) > 0 {
+ // "X = 1". With no type but a value. If the constant is untyped,
+ // skip this vspec and reset the remembered type.
+ typ = ""
+
+ // If this is a simple type conversion, remember the type.
+ // We don't mind if this is actually a call; a qualified call won't
+ // be matched (that will be SelectorExpr, not Ident), and only unusual
+ // situations will result in a function call that appears to be
+ // a type conversion.
+ ce, ok := vspec.Values[0].(*ast.CallExpr)
+ if !ok {
+ continue
+ }
+ id, ok := ce.Fun.(*ast.Ident)
+ if !ok {
+ continue
+ }
+ typ = id.Name
+ }
+ if vspec.Type != nil {
+ // "X T". We have a type. Remember it.
+ ident, ok := vspec.Type.(*ast.Ident)
+ if !ok {
+ continue
+ }
+ typ = ident.Name
+ }
+ if typ != f.typeName {
+ // This is not the type we're looking for.
+ continue
+ }
+ // We now have a list of names (from one line of source code) all being
+ // declared with the desired type.
+ // Grab their names and actual values and store them in f.values.
+ for _, name := range vspec.Names {
+ if name.Name == "_" {
+ continue
+ }
+ // This dance lets the type checker find the values for us. It's a
+ // bit tricky: look up the object declared by the name, find its
+ // types.Const, and extract its value.
+ obj, ok := f.pkg.defs[name]
+ if !ok {
+ log.Fatalf("no value for constant %s", name)
+ }
+ info := obj.Type().Underlying().(*types.Basic).Info()
+ if info&types.IsInteger == 0 {
+ log.Fatalf("can't handle non-integer constant type %s", typ)
+ }
+ value := obj.(*types.Const).Val() // Guaranteed to succeed as this is CONST.
+ if value.Kind() != constant.Int {
+ log.Fatalf("can't happen: constant is not an integer %s", name)
+ }
+ i64, isInt := constant.Int64Val(value)
+ u64, isUint := constant.Uint64Val(value)
+ if !isInt && !isUint {
+ log.Fatalf("internal error: value of %s is not an integer: %s", name, value.String())
+ }
+ if !isInt {
+ u64 = uint64(i64)
+ }
+ v := Value{
+ originalName: name.Name,
+ value: u64,
+ signed: info&types.IsUnsigned == 0,
+ str: value.String(),
+ }
+ if c := vspec.Comment; f.lineComment && c != nil && len(c.List) == 1 {
+ v.name = strings.TrimSpace(c.Text())
+ } else {
+ v.name = strings.TrimPrefix(v.originalName, f.trimPrefix)
+ }
+ f.values = append(f.values, v)
+ }
+ }
+ return false
+}
+
+// Helpers
+
+// usize returns the number of bits of the smallest unsigned integer
+// type that will hold n. Used to create the smallest possible slice of
+// integers to use as indexes into the concatenated strings.
+func usize(n int) int {
+ switch {
+ case n < 1<<8:
+ return 8
+ case n < 1<<16:
+ return 16
+ default:
+ // 2^32 is enough constants for anyone.
+ return 32
+ }
+}
+
+// declareIndexAndNameVars declares the index slices and concatenated names
+// strings representing the runs of values.
+func (g *Generator) declareIndexAndNameVars(runs [][]Value, typeName string) {
+ var indexes, names []string
+ for i, run := range runs {
+ index, name := g.createIndexAndNameDecl(run, typeName, fmt.Sprintf("_%d", i))
+ if len(run) != 1 {
+ indexes = append(indexes, index)
+ }
+ names = append(names, name)
+ }
+ g.Printf("const (\n")
+ for _, name := range names {
+ g.Printf("\t%s\n", name)
+ }
+ g.Printf(")\n\n")
+
+ if len(indexes) > 0 {
+ g.Printf("var (")
+ for _, index := range indexes {
+ g.Printf("\t%s\n", index)
+ }
+ g.Printf(")\n\n")
+ }
+}
+
+// declareIndexAndNameVar is the single-run version of declareIndexAndNameVars
+func (g *Generator) declareIndexAndNameVar(run []Value, typeName string) {
+ index, name := g.createIndexAndNameDecl(run, typeName, "")
+ g.Printf("const %s\n", name)
+ g.Printf("var %s\n", index)
+}
+
+// createIndexAndNameDecl returns the pair of declarations for the run. The caller will add "const" and "var".
+func (g *Generator) createIndexAndNameDecl(run []Value, typeName string, suffix string) (string, string) {
+ b := new(bytes.Buffer)
+ indexes := make([]int, len(run))
+ for i := range run {
+ b.WriteString(run[i].name)
+ indexes[i] = b.Len()
+ }
+ nameConst := fmt.Sprintf("_%s_name%s = %q", typeName, suffix, b.String())
+ nameLen := b.Len()
+ b.Reset()
+ fmt.Fprintf(b, "_%s_index%s = [...]uint%d{0, ", typeName, suffix, usize(nameLen))
+ for i, v := range indexes {
+ if i > 0 {
+ fmt.Fprintf(b, ", ")
+ }
+ fmt.Fprintf(b, "%d", v)
+ }
+ fmt.Fprintf(b, "}")
+ return b.String(), nameConst
+}
+
+// declareNameVars declares the concatenated names string representing all the values in the runs.
+func (g *Generator) declareNameVars(runs [][]Value, typeName string, suffix string) {
+ g.Printf("const _%s_name%s = \"", typeName, suffix)
+ for _, run := range runs {
+ for i := range run {
+ g.Printf("%s", run[i].name)
+ }
+ }
+ g.Printf("\"\n")
+}
+
+// buildOneRun generates the variables and String method for a single run of contiguous values.
+func (g *Generator) buildOneRun(runs [][]Value, typeName string) {
+ values := runs[0]
+ g.Printf("\n")
+ g.declareIndexAndNameVar(values, typeName)
+ // The generated code is simple enough to write as a Printf format.
+ lessThanZero := ""
+ if values[0].signed {
+ lessThanZero = "i < 0 || "
+ }
+ if values[0].value == 0 { // Signed or unsigned, 0 is still 0.
+ g.Printf(stringOneRun, typeName, usize(len(values)), lessThanZero)
+ } else {
+ g.Printf(stringOneRunWithOffset, typeName, values[0].String(), usize(len(values)), lessThanZero)
+ }
+}
+
+// Arguments to format are:
+//
+// [1]: type name
+// [2]: size of index element (8 for uint8 etc.)
+// [3]: less than zero check (for signed types)
+const stringOneRun = `func (i %[1]s) String() string {
+ if %[3]si >= %[1]s(len(_%[1]s_index)-1) {
+ return "%[1]s(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _%[1]s_name[_%[1]s_index[i]:_%[1]s_index[i+1]]
+}
+`
+
+// Arguments to format are:
+// [1]: type name
+// [2]: lowest defined value for type, as a string
+// [3]: size of index element (8 for uint8 etc.)
+// [4]: less than zero check (for signed types)
+/*
+ */
+const stringOneRunWithOffset = `func (i %[1]s) String() string {
+ i -= %[2]s
+ if %[4]si >= %[1]s(len(_%[1]s_index)-1) {
+ return "%[1]s(" + strconv.FormatInt(int64(i + %[2]s), 10) + ")"
+ }
+ return _%[1]s_name[_%[1]s_index[i] : _%[1]s_index[i+1]]
+}
+`
+
+// buildMultipleRuns generates the variables and String method for multiple runs of contiguous values.
+// For this pattern, a single Printf format won't do.
+func (g *Generator) buildMultipleRuns(runs [][]Value, typeName string) {
+ g.Printf("\n")
+ g.declareIndexAndNameVars(runs, typeName)
+ g.Printf("func (i %s) String() string {\n", typeName)
+ g.Printf("\tswitch {\n")
+ for i, values := range runs {
+ if len(values) == 1 {
+ g.Printf("\tcase i == %s:\n", &values[0])
+ g.Printf("\t\treturn _%s_name_%d\n", typeName, i)
+ continue
+ }
+ if values[0].value == 0 && !values[0].signed {
+ // For an unsigned lower bound of 0, "0 <= i" would be redundant.
+ g.Printf("\tcase i <= %s:\n", &values[len(values)-1])
+ } else {
+ g.Printf("\tcase %s <= i && i <= %s:\n", &values[0], &values[len(values)-1])
+ }
+ if values[0].value != 0 {
+ g.Printf("\t\ti -= %s\n", &values[0])
+ }
+ g.Printf("\t\treturn _%s_name_%d[_%s_index_%d[i]:_%s_index_%d[i+1]]\n",
+ typeName, i, typeName, i, typeName, i)
+ }
+ g.Printf("\tdefault:\n")
+ g.Printf("\t\treturn \"%s(\" + strconv.FormatInt(int64(i), 10) + \")\"\n", typeName)
+ g.Printf("\t}\n")
+ g.Printf("}\n")
+}
+
+// buildMap handles the case where the space is so sparse a map is a reasonable fallback.
+// It's a rare situation but has simple code.
+func (g *Generator) buildMap(runs [][]Value, typeName string) {
+ g.Printf("\n")
+ g.declareNameVars(runs, typeName, "")
+ g.Printf("\nvar _%s_map = map[%s]string{\n", typeName, typeName)
+ n := 0
+ for _, values := range runs {
+ for _, value := range values {
+ g.Printf("\t%s: _%s_name[%d:%d],\n", &value, typeName, n, n+len(value.name))
+ n += len(value.name)
+ }
+ }
+ g.Printf("}\n\n")
+ g.Printf(stringMap, typeName)
+}
+
+// Argument to format is the type name.
+const stringMap = `func (i %[1]s) String() string {
+ if str, ok := _%[1]s_map[i]; ok {
+ return str
+ }
+ return "%[1]s(" + strconv.FormatInt(int64(i), 10) + ")"
+}
+`
diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
new file mode 100644
index 00000000..137cc8df
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
@@ -0,0 +1,186 @@
+// 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 gcexportdata provides functions for locating, reading, and
+// writing export data files containing type information produced by the
+// gc compiler. This package supports go1.7 export data format and all
+// later versions.
+//
+// Although it might seem convenient for this package to live alongside
+// go/types in the standard library, this would cause version skew
+// problems for developer tools that use it, since they must be able to
+// consume the outputs of the gc compiler both before and after a Go
+// update such as from Go 1.7 to Go 1.8. Because this package lives in
+// golang.org/x/tools, sites can update their version of this repo some
+// time before the Go 1.8 release and rebuild and redeploy their
+// developer tools, which will then be able to consume both Go 1.7 and
+// Go 1.8 export data files, so they will work before and after the
+// Go update. (See discussion at https://golang.org/issue/15651.)
+package gcexportdata // import "golang.org/x/tools/go/gcexportdata"
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "go/token"
+ "go/types"
+ "io"
+ "os/exec"
+
+ "golang.org/x/tools/internal/gcimporter"
+)
+
+// Find returns the name of an object (.o) or archive (.a) file
+// containing type information for the specified import path,
+// using the go command.
+// If no file was found, an empty filename is returned.
+//
+// A relative srcDir is interpreted relative to the current working directory.
+//
+// Find also returns the package's resolved (canonical) import path,
+// reflecting the effects of srcDir and vendoring on importPath.
+//
+// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages,
+// which is more efficient.
+func Find(importPath, srcDir string) (filename, path string) {
+ cmd := exec.Command("go", "list", "-json", "-export", "--", importPath)
+ cmd.Dir = srcDir
+ out, err := cmd.Output()
+ if err != nil {
+ return "", ""
+ }
+ var data struct {
+ ImportPath string
+ Export string
+ }
+ json.Unmarshal(out, &data)
+ return data.Export, data.ImportPath
+}
+
+// NewReader returns a reader for the export data section of an object
+// (.o) or archive (.a) file read from r. The new reader may provide
+// additional trailing data beyond the end of the export data.
+func NewReader(r io.Reader) (io.Reader, error) {
+ buf := bufio.NewReader(r)
+ _, size, err := gcimporter.FindExportData(buf)
+ if err != nil {
+ return nil, err
+ }
+
+ if size >= 0 {
+ // We were given an archive and found the __.PKGDEF in it.
+ // This tells us the size of the export data, and we don't
+ // need to return the entire file.
+ return &io.LimitedReader{
+ R: buf,
+ N: size,
+ }, nil
+ } else {
+ // We were given an object file. As such, we don't know how large
+ // the export data is and must return the entire file.
+ return buf, nil
+ }
+}
+
+// readAll works the same way as io.ReadAll, but avoids allocations and copies
+// by preallocating a byte slice of the necessary size if the size is known up
+// front. This is always possible when the input is an archive. In that case,
+// NewReader will return the known size using an io.LimitedReader.
+func readAll(r io.Reader) ([]byte, error) {
+ if lr, ok := r.(*io.LimitedReader); ok {
+ data := make([]byte, lr.N)
+ _, err := io.ReadFull(lr, data)
+ return data, err
+ }
+ return io.ReadAll(r)
+}
+
+// Read reads export data from in, decodes it, and returns type
+// information for the package.
+//
+// The package path (effectively its linker symbol prefix) is
+// specified by path, since unlike the package name, this information
+// may not be recorded in the export data.
+//
+// File position information is added to fset.
+//
+// Read may inspect and add to the imports map to ensure that references
+// within the export data to other packages are consistent. The caller
+// must ensure that imports[path] does not exist, or exists but is
+// incomplete (see types.Package.Complete), and Read inserts the
+// resulting package into this map entry.
+//
+// On return, the state of the reader is undefined.
+func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) {
+ data, err := readAll(in)
+ if err != nil {
+ return nil, fmt.Errorf("reading export data for %q: %v", path, err)
+ }
+
+ if bytes.HasPrefix(data, []byte("!")) {
+ return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path)
+ }
+
+ // The indexed export format starts with an 'i'; the older
+ // binary export format starts with a 'c', 'd', or 'v'
+ // (from "version"). Select appropriate importer.
+ if len(data) > 0 {
+ switch data[0] {
+ case 'v', 'c', 'd': // binary, till go1.10
+ return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0])
+
+ case 'i': // indexed, till go1.19
+ _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path)
+ return pkg, err
+
+ case 'u': // unified, from go1.20
+ _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path)
+ return pkg, err
+
+ default:
+ l := len(data)
+ if l > 10 {
+ l = 10
+ }
+ return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path)
+ }
+ }
+ return nil, fmt.Errorf("empty export data for %s", path)
+}
+
+// Write writes encoded type information for the specified package to out.
+// The FileSet provides file position information for named objects.
+func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
+ if _, err := io.WriteString(out, "i"); err != nil {
+ return err
+ }
+ return gcimporter.IExportData(out, fset, pkg)
+}
+
+// ReadBundle reads an export bundle from in, decodes it, and returns type
+// information for the packages.
+// File position information is added to fset.
+//
+// ReadBundle may inspect and add to the imports map to ensure that references
+// within the export bundle to other packages are consistent.
+//
+// On return, the state of the reader is undefined.
+//
+// Experimental: This API is experimental and may change in the future.
+func ReadBundle(in io.Reader, fset *token.FileSet, imports map[string]*types.Package) ([]*types.Package, error) {
+ data, err := readAll(in)
+ if err != nil {
+ return nil, fmt.Errorf("reading export bundle: %v", err)
+ }
+ return gcimporter.IImportBundle(fset, imports, data)
+}
+
+// WriteBundle writes encoded type information for the specified packages to out.
+// The FileSet provides file position information for named objects.
+//
+// Experimental: This API is experimental and may change in the future.
+func WriteBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error {
+ return gcimporter.IExportBundle(out, fset, pkgs)
+}
diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go
new file mode 100644
index 00000000..37a7247e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/gcexportdata/importer.go
@@ -0,0 +1,75 @@
+// 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 gcexportdata
+
+import (
+ "fmt"
+ "go/token"
+ "go/types"
+ "os"
+)
+
+// NewImporter returns a new instance of the types.Importer interface
+// that reads type information from export data files written by gc.
+// The Importer also satisfies types.ImporterFrom.
+//
+// Export data files are located using "go build" workspace conventions
+// and the build.Default context.
+//
+// Use this importer instead of go/importer.For("gc", ...) to avoid the
+// version-skew problems described in the documentation of this package,
+// or to control the FileSet or access the imports map populated during
+// package loading.
+//
+// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages,
+// which is more efficient.
+func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom {
+ return importer{fset, imports}
+}
+
+type importer struct {
+ fset *token.FileSet
+ imports map[string]*types.Package
+}
+
+func (imp importer) Import(importPath string) (*types.Package, error) {
+ return imp.ImportFrom(importPath, "", 0)
+}
+
+func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) {
+ filename, path := Find(importPath, srcDir)
+ if filename == "" {
+ if importPath == "unsafe" {
+ // Even for unsafe, call Find first in case
+ // the package was vendored.
+ return types.Unsafe, nil
+ }
+ return nil, fmt.Errorf("can't find import: %s", importPath)
+ }
+
+ if pkg, ok := imp.imports[path]; ok && pkg.Complete() {
+ return pkg, nil // cache hit
+ }
+
+ // open file
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ f.Close()
+ if err != nil {
+ // add file name to error
+ err = fmt.Errorf("reading export data: %s: %v", filename, err)
+ }
+ }()
+
+ r, err := NewReader(f)
+ if err != nil {
+ return nil, err
+ }
+
+ return Read(r, imp.fset, imp.imports, path)
+}
diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go
new file mode 100644
index 00000000..3531ac8f
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/doc.go
@@ -0,0 +1,242 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package packages loads Go packages for inspection and analysis.
+
+The [Load] function takes as input a list of patterns and returns a
+list of [Package] values describing individual packages matched by those
+patterns.
+A [Config] specifies configuration options, the most important of which is
+the [LoadMode], which controls the amount of detail in the loaded packages.
+
+Load passes most patterns directly to the underlying build tool.
+The default build tool is the go command.
+Its supported patterns are described at
+https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns.
+Other build systems may be supported by providing a "driver";
+see [The driver protocol].
+
+All patterns with the prefix "query=", where query is a
+non-empty string of letters from [a-z], are reserved and may be
+interpreted as query operators.
+
+Two query operators are currently supported: "file" and "pattern".
+
+The query "file=path/to/file.go" matches the package or packages enclosing
+the Go source file path/to/file.go. For example "file=~/go/src/fmt/print.go"
+might return the packages "fmt" and "fmt [fmt.test]".
+
+The query "pattern=string" causes "string" to be passed directly to
+the underlying build tool. In most cases this is unnecessary,
+but an application can use Load("pattern=" + x) as an escaping mechanism
+to ensure that x is not interpreted as a query operator if it contains '='.
+
+All other query operators are reserved for future use and currently
+cause Load to report an error.
+
+The Package struct provides basic information about the package, including
+
+ - ID, a unique identifier for the package in the returned set;
+ - GoFiles, the names of the package's Go source files;
+ - Imports, a map from source import strings to the Packages they name;
+ - Types, the type information for the package's exported symbols;
+ - Syntax, the parsed syntax trees for the package's source code; and
+ - TypesInfo, the result of a complete type-check of the package syntax trees.
+
+(See the documentation for type Package for the complete list of fields
+and more detailed descriptions.)
+
+For example,
+
+ Load(nil, "bytes", "unicode...")
+
+returns four Package structs describing the standard library packages
+bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern
+can match multiple packages and that a package might be matched by
+multiple patterns: in general it is not possible to determine which
+packages correspond to which patterns.
+
+Note that the list returned by Load contains only the packages matched
+by the patterns. Their dependencies can be found by walking the import
+graph using the Imports fields.
+
+The Load function can be configured by passing a pointer to a Config as
+the first argument. A nil Config is equivalent to the zero Config, which
+causes Load to run in LoadFiles mode, collecting minimal information.
+See the documentation for type Config for details.
+
+As noted earlier, the Config.Mode controls the amount of detail
+reported about the loaded packages. See the documentation for type LoadMode
+for details.
+
+Most tools should pass their command-line arguments (after any flags)
+uninterpreted to [Load], so that it can interpret them
+according to the conventions of the underlying build system.
+
+See the Example function for typical usage.
+
+# The driver protocol
+
+[Load] may be used to load Go packages even in Go projects that use
+alternative build systems, by installing an appropriate "driver"
+program for the build system and specifying its location in the
+GOPACKAGESDRIVER environment variable.
+For example,
+https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration
+explains how to use the driver for Bazel.
+
+The driver program is responsible for interpreting patterns in its
+preferred notation and reporting information about the packages that
+those patterns identify. Drivers must also support the special "file="
+and "pattern=" patterns described above.
+
+The patterns are provided as positional command-line arguments. A
+JSON-encoded [DriverRequest] message providing additional information
+is written to the driver's standard input. The driver must write a
+JSON-encoded [DriverResponse] message to its standard output. (This
+message differs from the JSON schema produced by 'go list'.)
+*/
+package packages // import "golang.org/x/tools/go/packages"
+
+/*
+
+Motivation and design considerations
+
+The new package's design solves problems addressed by two existing
+packages: go/build, which locates and describes packages, and
+golang.org/x/tools/go/loader, which loads, parses and type-checks them.
+The go/build.Package structure encodes too much of the 'go build' way
+of organizing projects, leaving us in need of a data type that describes a
+package of Go source code independent of the underlying build system.
+We wanted something that works equally well with go build and vgo, and
+also other build systems such as Bazel and Blaze, making it possible to
+construct analysis tools that work in all these environments.
+Tools such as errcheck and staticcheck were essentially unavailable to
+the Go community at Google, and some of Google's internal tools for Go
+are unavailable externally.
+This new package provides a uniform way to obtain package metadata by
+querying each of these build systems, optionally supporting their
+preferred command-line notations for packages, so that tools integrate
+neatly with users' build environments. The Metadata query function
+executes an external query tool appropriate to the current workspace.
+
+Loading packages always returns the complete import graph "all the way down",
+even if all you want is information about a single package, because the query
+mechanisms of all the build systems we currently support ({go,vgo} list, and
+blaze/bazel aspect-based query) cannot provide detailed information
+about one package without visiting all its dependencies too, so there is
+no additional asymptotic cost to providing transitive information.
+(This property might not be true of a hypothetical 5th build system.)
+
+In calls to TypeCheck, all initial packages, and any package that
+transitively depends on one of them, must be loaded from source.
+Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from
+source; D may be loaded from export data, and E may not be loaded at all
+(though it's possible that D's export data mentions it, so a
+types.Package may be created for it and exposed.)
+
+The old loader had a feature to suppress type-checking of function
+bodies on a per-package basis, primarily intended to reduce the work of
+obtaining type information for imported packages. Now that imports are
+satisfied by export data, the optimization no longer seems necessary.
+
+Despite some early attempts, the old loader did not exploit export data,
+instead always using the equivalent of WholeProgram mode. This was due
+to the complexity of mixing source and export data packages (now
+resolved by the upward traversal mentioned above), and because export data
+files were nearly always missing or stale. Now that 'go build' supports
+caching, all the underlying build systems can guarantee to produce
+export data in a reasonable (amortized) time.
+
+Test "main" packages synthesized by the build system are now reported as
+first-class packages, avoiding the need for clients (such as go/ssa) to
+reinvent this generation logic.
+
+One way in which go/packages is simpler than the old loader is in its
+treatment of in-package tests. In-package tests are packages that
+consist of all the files of the library under test, plus the test files.
+The old loader constructed in-package tests by a two-phase process of
+mutation called "augmentation": first it would construct and type check
+all the ordinary library packages and type-check the packages that
+depend on them; then it would add more (test) files to the package and
+type-check again. This two-phase approach had four major problems:
+1) in processing the tests, the loader modified the library package,
+ leaving no way for a client application to see both the test
+ package and the library package; one would mutate into the other.
+2) because test files can declare additional methods on types defined in
+ the library portion of the package, the dispatch of method calls in
+ the library portion was affected by the presence of the test files.
+ This should have been a clue that the packages were logically
+ different.
+3) this model of "augmentation" assumed at most one in-package test
+ per library package, which is true of projects using 'go build',
+ but not other build systems.
+4) because of the two-phase nature of test processing, all packages that
+ import the library package had to be processed before augmentation,
+ forcing a "one-shot" API and preventing the client from calling Load
+ in several times in sequence as is now possible in WholeProgram mode.
+ (TypeCheck mode has a similar one-shot restriction for a different reason.)
+
+Early drafts of this package supported "multi-shot" operation.
+Although it allowed clients to make a sequence of calls (or concurrent
+calls) to Load, building up the graph of Packages incrementally,
+it was of marginal value: it complicated the API
+(since it allowed some options to vary across calls but not others),
+it complicated the implementation,
+it cannot be made to work in Types mode, as explained above,
+and it was less efficient than making one combined call (when this is possible).
+Among the clients we have inspected, none made multiple calls to load
+but could not be easily and satisfactorily modified to make only a single call.
+However, applications changes may be required.
+For example, the ssadump command loads the user-specified packages
+and in addition the runtime package. It is tempting to simply append
+"runtime" to the user-provided list, but that does not work if the user
+specified an ad-hoc package such as [a.go b.go].
+Instead, ssadump no longer requests the runtime package,
+but seeks it among the dependencies of the user-specified packages,
+and emits an error if it is not found.
+
+Questions & Tasks
+
+- Add GOARCH/GOOS?
+ They are not portable concepts, but could be made portable.
+ Our goal has been to allow users to express themselves using the conventions
+ of the underlying build system: if the build system honors GOARCH
+ during a build and during a metadata query, then so should
+ applications built atop that query mechanism.
+ Conversely, if the target architecture of the build is determined by
+ command-line flags, the application can pass the relevant
+ flags through to the build system using a command such as:
+ myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin"
+ However, this approach is low-level, unwieldy, and non-portable.
+ GOOS and GOARCH seem important enough to warrant a dedicated option.
+
+- How should we handle partial failures such as a mixture of good and
+ malformed patterns, existing and non-existent packages, successful and
+ failed builds, import failures, import cycles, and so on, in a call to
+ Load?
+
+- Support bazel, blaze, and go1.10 list, not just go1.11 list.
+
+- Handle (and test) various partial success cases, e.g.
+ a mixture of good packages and:
+ invalid patterns
+ nonexistent packages
+ empty packages
+ packages with malformed package or import declarations
+ unreadable files
+ import cycles
+ other parse errors
+ type errors
+ Make sure we record errors at the correct place in the graph.
+
+- Missing packages among initial arguments are not reported.
+ Return bogus packages for them, like golist does.
+
+- "undeclared name" errors (for example) are reported out of source file
+ order. I suspect this is due to the breadth-first resolution now used
+ by go/types. Is that a bug? Discuss with gri.
+
+*/
diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go
new file mode 100644
index 00000000..c2b4b711
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/external.go
@@ -0,0 +1,156 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+// This file defines the protocol that enables an external "driver"
+// tool to supply package metadata in place of 'go list'.
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "os"
+ "os/exec"
+ "strings"
+)
+
+// DriverRequest defines the schema of a request for package metadata
+// from an external driver program. The JSON-encoded DriverRequest
+// message is provided to the driver program's standard input. The
+// query patterns are provided as command-line arguments.
+//
+// See the package documentation for an overview.
+type DriverRequest struct {
+ Mode LoadMode `json:"mode"`
+
+ // Env specifies the environment the underlying build system should be run in.
+ Env []string `json:"env"`
+
+ // BuildFlags are flags that should be passed to the underlying build system.
+ BuildFlags []string `json:"build_flags"`
+
+ // Tests specifies whether the patterns should also return test packages.
+ Tests bool `json:"tests"`
+
+ // Overlay maps file paths (relative to the driver's working directory)
+ // to the contents of overlay files (see Config.Overlay).
+ Overlay map[string][]byte `json:"overlay"`
+}
+
+// DriverResponse defines the schema of a response from an external
+// driver program, providing the results of a query for package
+// metadata. The driver program must write a JSON-encoded
+// DriverResponse message to its standard output.
+//
+// See the package documentation for an overview.
+type DriverResponse struct {
+ // NotHandled is returned if the request can't be handled by the current
+ // driver. If an external driver returns a response with NotHandled, the
+ // rest of the DriverResponse is ignored, and go/packages will fallback
+ // to the next driver. If go/packages is extended in the future to support
+ // lists of multiple drivers, go/packages will fall back to the next driver.
+ NotHandled bool
+
+ // Compiler and Arch are the arguments pass of types.SizesFor
+ // to get a types.Sizes to use when type checking.
+ Compiler string
+ Arch string
+
+ // Roots is the set of package IDs that make up the root packages.
+ // We have to encode this separately because when we encode a single package
+ // we cannot know if it is one of the roots as that requires knowledge of the
+ // graph it is part of.
+ Roots []string `json:",omitempty"`
+
+ // Packages is the full set of packages in the graph.
+ // The packages are not connected into a graph.
+ // The Imports if populated will be stubs that only have their ID set.
+ // Imports will be connected and then type and syntax information added in a
+ // later pass (see refine).
+ Packages []*Package
+
+ // GoVersion is the minor version number used by the driver
+ // (e.g. the go command on the PATH) when selecting .go files.
+ // Zero means unknown.
+ GoVersion int
+}
+
+// driver is the type for functions that query the build system for the
+// packages named by the patterns.
+type driver func(cfg *Config, patterns ...string) (*DriverResponse, error)
+
+// findExternalDriver returns the file path of a tool that supplies
+// the build system package structure, or "" if not found."
+// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its
+// value, otherwise it searches for a binary named gopackagesdriver on the PATH.
+func findExternalDriver(cfg *Config) driver {
+ const toolPrefix = "GOPACKAGESDRIVER="
+ tool := ""
+ for _, env := range cfg.Env {
+ if val := strings.TrimPrefix(env, toolPrefix); val != env {
+ tool = val
+ }
+ }
+ if tool != "" && tool == "off" {
+ return nil
+ }
+ if tool == "" {
+ var err error
+ tool, err = exec.LookPath("gopackagesdriver")
+ if err != nil {
+ return nil
+ }
+ }
+ return func(cfg *Config, words ...string) (*DriverResponse, error) {
+ req, err := json.Marshal(DriverRequest{
+ Mode: cfg.Mode,
+ Env: cfg.Env,
+ BuildFlags: cfg.BuildFlags,
+ Tests: cfg.Tests,
+ Overlay: cfg.Overlay,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("failed to encode message to driver tool: %v", err)
+ }
+
+ buf := new(bytes.Buffer)
+ stderr := new(bytes.Buffer)
+ cmd := exec.CommandContext(cfg.Context, tool, words...)
+ cmd.Dir = cfg.Dir
+ // The cwd gets resolved to the real path. On Darwin, where
+ // /tmp is a symlink, this breaks anything that expects the
+ // working directory to keep the original path, including the
+ // go command when dealing with modules.
+ //
+ // os.Getwd stdlib has a special feature where if the
+ // cwd and the PWD are the same node then it trusts
+ // the PWD, so by setting it in the env for the child
+ // process we fix up all the paths returned by the go
+ // command.
+ //
+ // (See similar trick in Invocation.run in ../../internal/gocommand/invoke.go)
+ cmd.Env = append(slicesClip(cfg.Env), "PWD="+cfg.Dir)
+ cmd.Stdin = bytes.NewReader(req)
+ cmd.Stdout = buf
+ cmd.Stderr = stderr
+
+ if err := cmd.Run(); err != nil {
+ return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
+ }
+ if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" {
+ fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr)
+ }
+
+ var response DriverResponse
+ if err := json.Unmarshal(buf.Bytes(), &response); err != nil {
+ return nil, err
+ }
+ return &response, nil
+ }
+}
+
+// slicesClip removes unused capacity from the slice, returning s[:len(s):len(s)].
+// TODO(adonovan): use go1.21 slices.Clip.
+func slicesClip[S ~[]E, E any](s S) S { return s[:len(s):len(s)] }
diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go
new file mode 100644
index 00000000..1a3a5b44
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/golist.go
@@ -0,0 +1,1066 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "unicode"
+
+ "golang.org/x/tools/internal/gocommand"
+ "golang.org/x/tools/internal/packagesinternal"
+)
+
+// debug controls verbose logging.
+var debug, _ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG"))
+
+// A goTooOldError reports that the go command
+// found by exec.LookPath is too old to use the new go list behavior.
+type goTooOldError struct {
+ error
+}
+
+// responseDeduper wraps a DriverResponse, deduplicating its contents.
+type responseDeduper struct {
+ seenRoots map[string]bool
+ seenPackages map[string]*Package
+ dr *DriverResponse
+}
+
+func newDeduper() *responseDeduper {
+ return &responseDeduper{
+ dr: &DriverResponse{},
+ seenRoots: map[string]bool{},
+ seenPackages: map[string]*Package{},
+ }
+}
+
+// addAll fills in r with a DriverResponse.
+func (r *responseDeduper) addAll(dr *DriverResponse) {
+ for _, pkg := range dr.Packages {
+ r.addPackage(pkg)
+ }
+ for _, root := range dr.Roots {
+ r.addRoot(root)
+ }
+ r.dr.GoVersion = dr.GoVersion
+}
+
+func (r *responseDeduper) addPackage(p *Package) {
+ if r.seenPackages[p.ID] != nil {
+ return
+ }
+ r.seenPackages[p.ID] = p
+ r.dr.Packages = append(r.dr.Packages, p)
+}
+
+func (r *responseDeduper) addRoot(id string) {
+ if r.seenRoots[id] {
+ return
+ }
+ r.seenRoots[id] = true
+ r.dr.Roots = append(r.dr.Roots, id)
+}
+
+type golistState struct {
+ cfg *Config
+ ctx context.Context
+
+ envOnce sync.Once
+ goEnvError error
+ goEnv map[string]string
+
+ rootsOnce sync.Once
+ rootDirsError error
+ rootDirs map[string]string
+
+ goVersionOnce sync.Once
+ goVersionError error
+ goVersion int // The X in Go 1.X.
+
+ // vendorDirs caches the (non)existence of vendor directories.
+ vendorDirs map[string]bool
+}
+
+// getEnv returns Go environment variables. Only specific variables are
+// populated -- computing all of them is slow.
+func (state *golistState) getEnv() (map[string]string, error) {
+ state.envOnce.Do(func() {
+ var b *bytes.Buffer
+ b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH")
+ if state.goEnvError != nil {
+ return
+ }
+
+ state.goEnv = make(map[string]string)
+ decoder := json.NewDecoder(b)
+ if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil {
+ return
+ }
+ })
+ return state.goEnv, state.goEnvError
+}
+
+// mustGetEnv is a convenience function that can be used if getEnv has already succeeded.
+func (state *golistState) mustGetEnv() map[string]string {
+ env, err := state.getEnv()
+ if err != nil {
+ panic(fmt.Sprintf("mustGetEnv: %v", err))
+ }
+ return env
+}
+
+// goListDriver uses the go list command to interpret the patterns and produce
+// the build system package structure.
+// See driver for more details.
+func goListDriver(cfg *Config, patterns ...string) (_ *DriverResponse, err error) {
+ // Make sure that any asynchronous go commands are killed when we return.
+ parentCtx := cfg.Context
+ if parentCtx == nil {
+ parentCtx = context.Background()
+ }
+ ctx, cancel := context.WithCancel(parentCtx)
+ defer cancel()
+
+ response := newDeduper()
+
+ state := &golistState{
+ cfg: cfg,
+ ctx: ctx,
+ vendorDirs: map[string]bool{},
+ }
+
+ // Fill in response.Sizes asynchronously if necessary.
+ if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 {
+ errCh := make(chan error)
+ go func() {
+ compiler, arch, err := getSizesForArgs(ctx, state.cfgInvocation(), cfg.gocmdRunner)
+ response.dr.Compiler = compiler
+ response.dr.Arch = arch
+ errCh <- err
+ }()
+ defer func() {
+ if sizesErr := <-errCh; sizesErr != nil {
+ err = sizesErr
+ }
+ }()
+ }
+
+ // Determine files requested in contains patterns
+ var containFiles []string
+ restPatterns := make([]string, 0, len(patterns))
+ // Extract file= and other [querytype]= patterns. Report an error if querytype
+ // doesn't exist.
+extractQueries:
+ for _, pattern := range patterns {
+ eqidx := strings.Index(pattern, "=")
+ if eqidx < 0 {
+ restPatterns = append(restPatterns, pattern)
+ } else {
+ query, value := pattern[:eqidx], pattern[eqidx+len("="):]
+ switch query {
+ case "file":
+ containFiles = append(containFiles, value)
+ case "pattern":
+ restPatterns = append(restPatterns, value)
+ case "": // not a reserved query
+ restPatterns = append(restPatterns, pattern)
+ default:
+ for _, rune := range query {
+ if rune < 'a' || rune > 'z' { // not a reserved query
+ restPatterns = append(restPatterns, pattern)
+ continue extractQueries
+ }
+ }
+ // Reject all other patterns containing "="
+ return nil, fmt.Errorf("invalid query type %q in query pattern %q", query, pattern)
+ }
+ }
+ }
+
+ // See if we have any patterns to pass through to go list. Zero initial
+ // patterns also requires a go list call, since it's the equivalent of
+ // ".".
+ if len(restPatterns) > 0 || len(patterns) == 0 {
+ dr, err := state.createDriverResponse(restPatterns...)
+ if err != nil {
+ return nil, err
+ }
+ response.addAll(dr)
+ }
+
+ if len(containFiles) != 0 {
+ if err := state.runContainsQueries(response, containFiles); err != nil {
+ return nil, err
+ }
+ }
+
+ // (We may yet return an error due to defer.)
+ return response.dr, nil
+}
+
+func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error {
+ for _, query := range queries {
+ // TODO(matloob): Do only one query per directory.
+ fdir := filepath.Dir(query)
+ // Pass absolute path of directory to go list so that it knows to treat it as a directory,
+ // not a package path.
+ pattern, err := filepath.Abs(fdir)
+ if err != nil {
+ return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err)
+ }
+ dirResponse, err := state.createDriverResponse(pattern)
+
+ // If there was an error loading the package, or no packages are returned,
+ // or the package is returned with errors, try to load the file as an
+ // ad-hoc package.
+ // Usually the error will appear in a returned package, but may not if we're
+ // in module mode and the ad-hoc is located outside a module.
+ if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 &&
+ len(dirResponse.Packages[0].Errors) == 1 {
+ var queryErr error
+ if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil {
+ return err // return the original error
+ }
+ }
+ isRoot := make(map[string]bool, len(dirResponse.Roots))
+ for _, root := range dirResponse.Roots {
+ isRoot[root] = true
+ }
+ for _, pkg := range dirResponse.Packages {
+ // Add any new packages to the main set
+ // We don't bother to filter packages that will be dropped by the changes of roots,
+ // that will happen anyway during graph construction outside this function.
+ // Over-reporting packages is not a problem.
+ response.addPackage(pkg)
+ // if the package was not a root one, it cannot have the file
+ if !isRoot[pkg.ID] {
+ continue
+ }
+ for _, pkgFile := range pkg.GoFiles {
+ if filepath.Base(query) == filepath.Base(pkgFile) {
+ response.addRoot(pkg.ID)
+ break
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// adhocPackage attempts to load or construct an ad-hoc package for a given
+// query, if the original call to the driver produced inadequate results.
+func (state *golistState) adhocPackage(pattern, query string) (*DriverResponse, error) {
+ response, err := state.createDriverResponse(query)
+ if err != nil {
+ return nil, err
+ }
+ // If we get nothing back from `go list`,
+ // try to make this file into its own ad-hoc package.
+ // TODO(rstambler): Should this check against the original response?
+ if len(response.Packages) == 0 {
+ response.Packages = append(response.Packages, &Package{
+ ID: "command-line-arguments",
+ PkgPath: query,
+ GoFiles: []string{query},
+ CompiledGoFiles: []string{query},
+ Imports: make(map[string]*Package),
+ })
+ response.Roots = append(response.Roots, "command-line-arguments")
+ }
+ // Handle special cases.
+ if len(response.Packages) == 1 {
+ // golang/go#33482: If this is a file= query for ad-hoc packages where
+ // the file only exists on an overlay, and exists outside of a module,
+ // add the file to the package and remove the errors.
+ if response.Packages[0].ID == "command-line-arguments" ||
+ filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) {
+ if len(response.Packages[0].GoFiles) == 0 {
+ filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath
+ // TODO(matloob): check if the file is outside of a root dir?
+ for path := range state.cfg.Overlay {
+ if path == filename {
+ response.Packages[0].Errors = nil
+ response.Packages[0].GoFiles = []string{path}
+ response.Packages[0].CompiledGoFiles = []string{path}
+ }
+ }
+ }
+ }
+ }
+ return response, nil
+}
+
+// Fields must match go list;
+// see $GOROOT/src/cmd/go/internal/load/pkg.go.
+type jsonPackage struct {
+ ImportPath string
+ Dir string
+ Name string
+ Export string
+ GoFiles []string
+ CompiledGoFiles []string
+ IgnoredGoFiles []string
+ IgnoredOtherFiles []string
+ EmbedPatterns []string
+ EmbedFiles []string
+ CFiles []string
+ CgoFiles []string
+ CXXFiles []string
+ MFiles []string
+ HFiles []string
+ FFiles []string
+ SFiles []string
+ SwigFiles []string
+ SwigCXXFiles []string
+ SysoFiles []string
+ Imports []string
+ ImportMap map[string]string
+ Deps []string
+ Module *Module
+ TestGoFiles []string
+ TestImports []string
+ XTestGoFiles []string
+ XTestImports []string
+ ForTest string // q in a "p [q.test]" package, else ""
+ DepOnly bool
+
+ Error *packagesinternal.PackageError
+ DepsErrors []*packagesinternal.PackageError
+}
+
+type jsonPackageError struct {
+ ImportStack []string
+ Pos string
+ Err string
+}
+
+func otherFiles(p *jsonPackage) [][]string {
+ return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles}
+}
+
+// createDriverResponse uses the "go list" command to expand the pattern
+// words and return a response for the specified packages.
+func (state *golistState) createDriverResponse(words ...string) (*DriverResponse, error) {
+ // go list uses the following identifiers in ImportPath and Imports:
+ //
+ // "p" -- importable package or main (command)
+ // "q.test" -- q's test executable
+ // "p [q.test]" -- variant of p as built for q's test executable
+ // "q_test [q.test]" -- q's external test package
+ //
+ // The packages p that are built differently for a test q.test
+ // are q itself, plus any helpers used by the external test q_test,
+ // typically including "testing" and all its dependencies.
+
+ // Run "go list" for complete
+ // information on the specified packages.
+ goVersion, err := state.getGoVersion()
+ if err != nil {
+ return nil, err
+ }
+ buf, err := state.invokeGo("list", golistargs(state.cfg, words, goVersion)...)
+ if err != nil {
+ return nil, err
+ }
+
+ seen := make(map[string]*jsonPackage)
+ pkgs := make(map[string]*Package)
+ additionalErrors := make(map[string][]Error)
+ // Decode the JSON and convert it to Package form.
+ response := &DriverResponse{
+ GoVersion: goVersion,
+ }
+ for dec := json.NewDecoder(buf); dec.More(); {
+ p := new(jsonPackage)
+ if err := dec.Decode(p); err != nil {
+ return nil, fmt.Errorf("JSON decoding failed: %v", err)
+ }
+
+ if p.ImportPath == "" {
+ // The documentation for go list says that “[e]rroneous packages will have
+ // a non-empty ImportPath”. If for some reason it comes back empty, we
+ // prefer to error out rather than silently discarding data or handing
+ // back a package without any way to refer to it.
+ if p.Error != nil {
+ return nil, Error{
+ Pos: p.Error.Pos,
+ Msg: p.Error.Err,
+ }
+ }
+ return nil, fmt.Errorf("package missing import path: %+v", p)
+ }
+
+ // Work around https://golang.org/issue/33157:
+ // go list -e, when given an absolute path, will find the package contained at
+ // that directory. But when no package exists there, it will return a fake package
+ // with an error and the ImportPath set to the absolute path provided to go list.
+ // Try to convert that absolute path to what its package path would be if it's
+ // contained in a known module or GOPATH entry. This will allow the package to be
+ // properly "reclaimed" when overlays are processed.
+ if filepath.IsAbs(p.ImportPath) && p.Error != nil {
+ pkgPath, ok, err := state.getPkgPath(p.ImportPath)
+ if err != nil {
+ return nil, err
+ }
+ if ok {
+ p.ImportPath = pkgPath
+ }
+ }
+
+ if old, found := seen[p.ImportPath]; found {
+ // If one version of the package has an error, and the other doesn't, assume
+ // that this is a case where go list is reporting a fake dependency variant
+ // of the imported package: When a package tries to invalidly import another
+ // package, go list emits a variant of the imported package (with the same
+ // import path, but with an error on it, and the package will have a
+ // DepError set on it). An example of when this can happen is for imports of
+ // main packages: main packages can not be imported, but they may be
+ // separately matched and listed by another pattern.
+ // See golang.org/issue/36188 for more details.
+
+ // The plan is that eventually, hopefully in Go 1.15, the error will be
+ // reported on the importing package rather than the duplicate "fake"
+ // version of the imported package. Once all supported versions of Go
+ // have the new behavior this logic can be deleted.
+ // TODO(matloob): delete the workaround logic once all supported versions of
+ // Go return the errors on the proper package.
+
+ // There should be exactly one version of a package that doesn't have an
+ // error.
+ if old.Error == nil && p.Error == nil {
+ if !reflect.DeepEqual(p, old) {
+ return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath)
+ }
+ continue
+ }
+
+ // Determine if this package's error needs to be bubbled up.
+ // This is a hack, and we expect for go list to eventually set the error
+ // on the package.
+ if old.Error != nil {
+ var errkind string
+ if strings.Contains(old.Error.Err, "not an importable package") {
+ errkind = "not an importable package"
+ } else if strings.Contains(old.Error.Err, "use of internal package") && strings.Contains(old.Error.Err, "not allowed") {
+ errkind = "use of internal package not allowed"
+ }
+ if errkind != "" {
+ if len(old.Error.ImportStack) < 1 {
+ return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind)
+ }
+ importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1]
+ if importingPkg == old.ImportPath {
+ // Using an older version of Go which put this package itself on top of import
+ // stack, instead of the importer. Look for importer in second from top
+ // position.
+ if len(old.Error.ImportStack) < 2 {
+ return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind)
+ }
+ importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2]
+ }
+ additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{
+ Pos: old.Error.Pos,
+ Msg: old.Error.Err,
+ Kind: ListError,
+ })
+ }
+ }
+
+ // Make sure that if there's a version of the package without an error,
+ // that's the one reported to the user.
+ if old.Error == nil {
+ continue
+ }
+
+ // This package will replace the old one at the end of the loop.
+ }
+ seen[p.ImportPath] = p
+
+ pkg := &Package{
+ Name: p.Name,
+ ID: p.ImportPath,
+ GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles),
+ CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles),
+ OtherFiles: absJoin(p.Dir, otherFiles(p)...),
+ EmbedFiles: absJoin(p.Dir, p.EmbedFiles),
+ EmbedPatterns: absJoin(p.Dir, p.EmbedPatterns),
+ IgnoredFiles: absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles),
+ forTest: p.ForTest,
+ depsErrors: p.DepsErrors,
+ Module: p.Module,
+ }
+
+ if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 {
+ if len(p.CompiledGoFiles) > len(p.GoFiles) {
+ // We need the cgo definitions, which are in the first
+ // CompiledGoFile after the non-cgo ones. This is a hack but there
+ // isn't currently a better way to find it. We also need the pure
+ // Go files and unprocessed cgo files, all of which are already
+ // in pkg.GoFiles.
+ cgoTypes := p.CompiledGoFiles[len(p.GoFiles)]
+ pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...)
+ } else {
+ // golang/go#38990: go list silently fails to do cgo processing
+ pkg.CompiledGoFiles = nil
+ pkg.Errors = append(pkg.Errors, Error{
+ Msg: "go list failed to return CompiledGoFiles. This may indicate failure to perform cgo processing; try building at the command line. See https://golang.org/issue/38990.",
+ Kind: ListError,
+ })
+ }
+ }
+
+ // Work around https://golang.org/issue/28749:
+ // cmd/go puts assembly, C, and C++ files in CompiledGoFiles.
+ // Remove files from CompiledGoFiles that are non-go files
+ // (or are not files that look like they are from the cache).
+ if len(pkg.CompiledGoFiles) > 0 {
+ out := pkg.CompiledGoFiles[:0]
+ for _, f := range pkg.CompiledGoFiles {
+ if ext := filepath.Ext(f); ext != ".go" && ext != "" { // ext == "" means the file is from the cache, so probably cgo-processed file
+ continue
+ }
+ out = append(out, f)
+ }
+ pkg.CompiledGoFiles = out
+ }
+
+ // Extract the PkgPath from the package's ID.
+ if i := strings.IndexByte(pkg.ID, ' '); i >= 0 {
+ pkg.PkgPath = pkg.ID[:i]
+ } else {
+ pkg.PkgPath = pkg.ID
+ }
+
+ if pkg.PkgPath == "unsafe" {
+ pkg.CompiledGoFiles = nil // ignore fake unsafe.go file (#59929)
+ } else if len(pkg.CompiledGoFiles) == 0 {
+ // Work around for pre-go.1.11 versions of go list.
+ // TODO(matloob): they should be handled by the fallback.
+ // Can we delete this?
+ pkg.CompiledGoFiles = pkg.GoFiles
+ }
+
+ // Assume go list emits only absolute paths for Dir.
+ if p.Dir != "" && !filepath.IsAbs(p.Dir) {
+ log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s", p.Dir)
+ }
+
+ if p.Export != "" && !filepath.IsAbs(p.Export) {
+ pkg.ExportFile = filepath.Join(p.Dir, p.Export)
+ } else {
+ pkg.ExportFile = p.Export
+ }
+
+ // imports
+ //
+ // Imports contains the IDs of all imported packages.
+ // ImportsMap records (path, ID) only where they differ.
+ ids := make(map[string]bool)
+ for _, id := range p.Imports {
+ ids[id] = true
+ }
+ pkg.Imports = make(map[string]*Package)
+ for path, id := range p.ImportMap {
+ pkg.Imports[path] = &Package{ID: id} // non-identity import
+ delete(ids, id)
+ }
+ for id := range ids {
+ if id == "C" {
+ continue
+ }
+
+ pkg.Imports[id] = &Package{ID: id} // identity import
+ }
+ if !p.DepOnly {
+ response.Roots = append(response.Roots, pkg.ID)
+ }
+
+ // Temporary work-around for golang/go#39986. Parse filenames out of
+ // error messages. This happens if there are unrecoverable syntax
+ // errors in the source, so we can't match on a specific error message.
+ //
+ // TODO(rfindley): remove this heuristic, in favor of considering
+ // InvalidGoFiles from the list driver.
+ if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) {
+ addFilenameFromPos := func(pos string) bool {
+ split := strings.Split(pos, ":")
+ if len(split) < 1 {
+ return false
+ }
+ filename := strings.TrimSpace(split[0])
+ if filename == "" {
+ return false
+ }
+ if !filepath.IsAbs(filename) {
+ filename = filepath.Join(state.cfg.Dir, filename)
+ }
+ info, _ := os.Stat(filename)
+ if info == nil {
+ return false
+ }
+ pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename)
+ pkg.GoFiles = append(pkg.GoFiles, filename)
+ return true
+ }
+ found := addFilenameFromPos(err.Pos)
+ // In some cases, go list only reports the error position in the
+ // error text, not the error position. One such case is when the
+ // file's package name is a keyword (see golang.org/issue/39763).
+ if !found {
+ addFilenameFromPos(err.Err)
+ }
+ }
+
+ if p.Error != nil {
+ msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363.
+ // Address golang.org/issue/35964 by appending import stack to error message.
+ if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 {
+ msg += fmt.Sprintf(": import stack: %v", p.Error.ImportStack)
+ }
+ pkg.Errors = append(pkg.Errors, Error{
+ Pos: p.Error.Pos,
+ Msg: msg,
+ Kind: ListError,
+ })
+ }
+
+ pkgs[pkg.ID] = pkg
+ }
+
+ for id, errs := range additionalErrors {
+ if p, ok := pkgs[id]; ok {
+ p.Errors = append(p.Errors, errs...)
+ }
+ }
+ for _, pkg := range pkgs {
+ response.Packages = append(response.Packages, pkg)
+ }
+ sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID })
+
+ return response, nil
+}
+
+func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool {
+ if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 {
+ return false
+ }
+
+ goV, err := state.getGoVersion()
+ if err != nil {
+ return false
+ }
+
+ // On Go 1.14 and earlier, only add filenames from errors if the import stack is empty.
+ // The import stack behaves differently for these versions than newer Go versions.
+ if goV < 15 {
+ return len(p.Error.ImportStack) == 0
+ }
+
+ // On Go 1.15 and later, only parse filenames out of error if there's no import stack,
+ // or the current package is at the top of the import stack. This is not guaranteed
+ // to work perfectly, but should avoid some cases where files in errors don't belong to this
+ // package.
+ return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath
+}
+
+// getGoVersion returns the effective minor version of the go command.
+func (state *golistState) getGoVersion() (int, error) {
+ state.goVersionOnce.Do(func() {
+ state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.cfg.gocmdRunner)
+ })
+ return state.goVersion, state.goVersionError
+}
+
+// getPkgPath finds the package path of a directory if it's relative to a root
+// directory.
+func (state *golistState) getPkgPath(dir string) (string, bool, error) {
+ absDir, err := filepath.Abs(dir)
+ if err != nil {
+ return "", false, err
+ }
+ roots, err := state.determineRootDirs()
+ if err != nil {
+ return "", false, err
+ }
+
+ for rdir, rpath := range roots {
+ // Make sure that the directory is in the module,
+ // to avoid creating a path relative to another module.
+ if !strings.HasPrefix(absDir, rdir) {
+ continue
+ }
+ // TODO(matloob): This doesn't properly handle symlinks.
+ r, err := filepath.Rel(rdir, dir)
+ if err != nil {
+ continue
+ }
+ if rpath != "" {
+ // We choose only one root even though the directory even it can belong in multiple modules
+ // or GOPATH entries. This is okay because we only need to work with absolute dirs when a
+ // file is missing from disk, for instance when gopls calls go/packages in an overlay.
+ // Once the file is saved, gopls, or the next invocation of the tool will get the correct
+ // result straight from golist.
+ // TODO(matloob): Implement module tiebreaking?
+ return path.Join(rpath, filepath.ToSlash(r)), true, nil
+ }
+ return filepath.ToSlash(r), true, nil
+ }
+ return "", false, nil
+}
+
+// absJoin absolutizes and flattens the lists of files.
+func absJoin(dir string, fileses ...[]string) (res []string) {
+ for _, files := range fileses {
+ for _, file := range files {
+ if !filepath.IsAbs(file) {
+ file = filepath.Join(dir, file)
+ }
+ res = append(res, file)
+ }
+ }
+ return res
+}
+
+func jsonFlag(cfg *Config, goVersion int) string {
+ if goVersion < 19 {
+ return "-json"
+ }
+ var fields []string
+ added := make(map[string]bool)
+ addFields := func(fs ...string) {
+ for _, f := range fs {
+ if !added[f] {
+ added[f] = true
+ fields = append(fields, f)
+ }
+ }
+ }
+ addFields("Name", "ImportPath", "Error") // These fields are always needed
+ if cfg.Mode&NeedFiles != 0 || cfg.Mode&NeedTypes != 0 {
+ addFields("Dir", "GoFiles", "IgnoredGoFiles", "IgnoredOtherFiles", "CFiles",
+ "CgoFiles", "CXXFiles", "MFiles", "HFiles", "FFiles", "SFiles",
+ "SwigFiles", "SwigCXXFiles", "SysoFiles")
+ if cfg.Tests {
+ addFields("TestGoFiles", "XTestGoFiles")
+ }
+ }
+ if cfg.Mode&NeedTypes != 0 {
+ // CompiledGoFiles seems to be required for the test case TestCgoNoSyntax,
+ // even when -compiled isn't passed in.
+ // TODO(#52435): Should we make the test ask for -compiled, or automatically
+ // request CompiledGoFiles in certain circumstances?
+ addFields("Dir", "CompiledGoFiles")
+ }
+ if cfg.Mode&NeedCompiledGoFiles != 0 {
+ addFields("Dir", "CompiledGoFiles", "Export")
+ }
+ if cfg.Mode&NeedImports != 0 {
+ // When imports are requested, DepOnly is used to distinguish between packages
+ // explicitly requested and transitive imports of those packages.
+ addFields("DepOnly", "Imports", "ImportMap")
+ if cfg.Tests {
+ addFields("TestImports", "XTestImports")
+ }
+ }
+ if cfg.Mode&NeedDeps != 0 {
+ addFields("DepOnly")
+ }
+ if usesExportData(cfg) {
+ // Request Dir in the unlikely case Export is not absolute.
+ addFields("Dir", "Export")
+ }
+ if cfg.Mode&needInternalForTest != 0 {
+ addFields("ForTest")
+ }
+ if cfg.Mode&needInternalDepsErrors != 0 {
+ addFields("DepsErrors")
+ }
+ if cfg.Mode&NeedModule != 0 {
+ addFields("Module")
+ }
+ if cfg.Mode&NeedEmbedFiles != 0 {
+ addFields("EmbedFiles")
+ }
+ if cfg.Mode&NeedEmbedPatterns != 0 {
+ addFields("EmbedPatterns")
+ }
+ return "-json=" + strings.Join(fields, ",")
+}
+
+func golistargs(cfg *Config, words []string, goVersion int) []string {
+ const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo
+ fullargs := []string{
+ "-e", jsonFlag(cfg, goVersion),
+ fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0),
+ fmt.Sprintf("-test=%t", cfg.Tests),
+ fmt.Sprintf("-export=%t", usesExportData(cfg)),
+ fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0),
+ // go list doesn't let you pass -test and -find together,
+ // probably because you'd just get the TestMain.
+ fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)),
+ }
+
+ // golang/go#60456: with go1.21 and later, go list serves pgo variants, which
+ // can be costly to compute and may result in redundant processing for the
+ // caller. Disable these variants. If someone wants to add e.g. a NeedPGO
+ // mode flag, that should be a separate proposal.
+ if goVersion >= 21 {
+ fullargs = append(fullargs, "-pgo=off")
+ }
+
+ fullargs = append(fullargs, cfg.BuildFlags...)
+ fullargs = append(fullargs, "--")
+ fullargs = append(fullargs, words...)
+ return fullargs
+}
+
+// cfgInvocation returns an Invocation that reflects cfg's settings.
+func (state *golistState) cfgInvocation() gocommand.Invocation {
+ cfg := state.cfg
+ return gocommand.Invocation{
+ BuildFlags: cfg.BuildFlags,
+ ModFile: cfg.modFile,
+ ModFlag: cfg.modFlag,
+ CleanEnv: cfg.Env != nil,
+ Env: cfg.Env,
+ Logf: cfg.Logf,
+ WorkingDir: cfg.Dir,
+ Overlay: cfg.goListOverlayFile,
+ }
+}
+
+// invokeGo returns the stdout of a go command invocation.
+func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) {
+ cfg := state.cfg
+
+ inv := state.cfgInvocation()
+ inv.Verb = verb
+ inv.Args = args
+ gocmdRunner := cfg.gocmdRunner
+ if gocmdRunner == nil {
+ gocmdRunner = &gocommand.Runner{}
+ }
+ stdout, stderr, friendlyErr, err := gocmdRunner.RunRaw(cfg.Context, inv)
+ if err != nil {
+ // Check for 'go' executable not being found.
+ if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
+ return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound)
+ }
+
+ exitErr, ok := err.(*exec.ExitError)
+ if !ok {
+ // Catastrophic error:
+ // - context cancellation
+ return nil, fmt.Errorf("couldn't run 'go': %w", err)
+ }
+
+ // Old go version?
+ if strings.Contains(stderr.String(), "flag provided but not defined") {
+ return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)}
+ }
+
+ // Related to #24854
+ if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") {
+ return nil, friendlyErr
+ }
+
+ // Is there an error running the C compiler in cgo? This will be reported in the "Error" field
+ // and should be suppressed by go list -e.
+ //
+ // This condition is not perfect yet because the error message can include other error messages than runtime/cgo.
+ isPkgPathRune := func(r rune) bool {
+ // From https://golang.org/ref/spec#Import_declarations:
+ // Implementation restriction: A compiler may restrict ImportPaths to non-empty strings
+ // using only characters belonging to Unicode's L, M, N, P, and S general categories
+ // (the Graphic characters without spaces) and may also exclude the
+ // characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD.
+ return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) &&
+ !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r)
+ }
+ // golang/go#36770: Handle case where cmd/go prints module download messages before the error.
+ msg := stderr.String()
+ for strings.HasPrefix(msg, "go: downloading") {
+ msg = msg[strings.IndexRune(msg, '\n')+1:]
+ }
+ if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") {
+ msg := msg[len("# "):]
+ if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") {
+ return stdout, nil
+ }
+ // Treat pkg-config errors as a special case (golang.org/issue/36770).
+ if strings.HasPrefix(msg, "pkg-config") {
+ return stdout, nil
+ }
+ }
+
+ // This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show
+ // the error in the Err section of stdout in case -e option is provided.
+ // This fix is provided for backwards compatibility.
+ if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") {
+ output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+ strings.Trim(stderr.String(), "\n"))
+ return bytes.NewBufferString(output), nil
+ }
+
+ // Similar to the previous error, but currently lacks a fix in Go.
+ if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") {
+ output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+ strings.Trim(stderr.String(), "\n"))
+ return bytes.NewBufferString(output), nil
+ }
+
+ // Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath.
+ // If the package doesn't exist, put the absolute path of the directory into the error message,
+ // as Go 1.13 list does.
+ const noSuchDirectory = "no such directory"
+ if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) {
+ errstr := stderr.String()
+ abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):])
+ output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+ abspath, strings.Trim(stderr.String(), "\n"))
+ return bytes.NewBufferString(output), nil
+ }
+
+ // Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist.
+ // Note that the error message we look for in this case is different that the one looked for above.
+ if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") {
+ output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+ strings.Trim(stderr.String(), "\n"))
+ return bytes.NewBufferString(output), nil
+ }
+
+ // Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a
+ // directory outside any module.
+ if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") {
+ output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+ // TODO(matloob): command-line-arguments isn't correct here.
+ "command-line-arguments", strings.Trim(stderr.String(), "\n"))
+ return bytes.NewBufferString(output), nil
+ }
+
+ // Another variation of the previous error
+ if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") {
+ output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+ // TODO(matloob): command-line-arguments isn't correct here.
+ "command-line-arguments", strings.Trim(stderr.String(), "\n"))
+ return bytes.NewBufferString(output), nil
+ }
+
+ // Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit
+ // status if there's a dependency on a package that doesn't exist. But it should return
+ // a zero exit status and set an error on that package.
+ if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") {
+ // Don't clobber stdout if `go list` actually returned something.
+ if len(stdout.String()) > 0 {
+ return stdout, nil
+ }
+ // try to extract package name from string
+ stderrStr := stderr.String()
+ var importPath string
+ colon := strings.Index(stderrStr, ":")
+ if colon > 0 && strings.HasPrefix(stderrStr, "go build ") {
+ importPath = stderrStr[len("go build "):colon]
+ }
+ output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+ importPath, strings.Trim(stderrStr, "\n"))
+ return bytes.NewBufferString(output), nil
+ }
+
+ // Export mode entails a build.
+ // If that build fails, errors appear on stderr
+ // (despite the -e flag) and the Export field is blank.
+ // Do not fail in that case.
+ // The same is true if an ad-hoc package given to go list doesn't exist.
+ // TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when
+ // packages don't exist or a build fails.
+ if !usesExportData(cfg) && !containsGoFile(args) {
+ return nil, friendlyErr
+ }
+ }
+ return stdout, nil
+}
+
+func containsGoFile(s []string) bool {
+ for _, f := range s {
+ if strings.HasSuffix(f, ".go") {
+ return true
+ }
+ }
+ return false
+}
+
+func cmdDebugStr(cmd *exec.Cmd) string {
+ env := make(map[string]string)
+ for _, kv := range cmd.Env {
+ split := strings.SplitN(kv, "=", 2)
+ k, v := split[0], split[1]
+ env[k] = v
+ }
+
+ var args []string
+ for _, arg := range cmd.Args {
+ quoted := strconv.Quote(arg)
+ if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") {
+ args = append(args, quoted)
+ } else {
+ args = append(args, arg)
+ }
+ }
+ return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " "))
+}
+
+// getSizesForArgs queries 'go list' for the appropriate
+// Compiler and GOARCH arguments to pass to [types.SizesFor].
+func getSizesForArgs(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) {
+ inv.Verb = "list"
+ inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
+ stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
+ var goarch, compiler string
+ if rawErr != nil {
+ rawErrMsg := rawErr.Error()
+ if strings.Contains(rawErrMsg, "cannot find main module") ||
+ strings.Contains(rawErrMsg, "go.mod file not found") {
+ // User's running outside of a module.
+ // All bets are off. Get GOARCH and guess compiler is gc.
+ // TODO(matloob): Is this a problem in practice?
+ inv.Verb = "env"
+ inv.Args = []string{"GOARCH"}
+ envout, enverr := gocmdRunner.Run(ctx, inv)
+ if enverr != nil {
+ return "", "", enverr
+ }
+ goarch = strings.TrimSpace(envout.String())
+ compiler = "gc"
+ } else if friendlyErr != nil {
+ return "", "", friendlyErr
+ } else {
+ // This should be unreachable, but be defensive
+ // in case RunRaw's error results are inconsistent.
+ return "", "", rawErr
+ }
+ } else {
+ fields := strings.Fields(stdout.String())
+ if len(fields) < 2 {
+ return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>",
+ stdout.String(), stderr.String())
+ }
+ goarch = fields[0]
+ compiler = fields[1]
+ }
+ return compiler, goarch, nil
+}
diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
new file mode 100644
index 00000000..d823c474
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
@@ -0,0 +1,83 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+import (
+ "encoding/json"
+ "path/filepath"
+
+ "golang.org/x/tools/internal/gocommand"
+)
+
+// determineRootDirs returns a mapping from absolute directories that could
+// contain code to their corresponding import path prefixes.
+func (state *golistState) determineRootDirs() (map[string]string, error) {
+ env, err := state.getEnv()
+ if err != nil {
+ return nil, err
+ }
+ if env["GOMOD"] != "" {
+ state.rootsOnce.Do(func() {
+ state.rootDirs, state.rootDirsError = state.determineRootDirsModules()
+ })
+ } else {
+ state.rootsOnce.Do(func() {
+ state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH()
+ })
+ }
+ return state.rootDirs, state.rootDirsError
+}
+
+func (state *golistState) determineRootDirsModules() (map[string]string, error) {
+ // List all of the modules--the first will be the directory for the main
+ // module. Any replaced modules will also need to be treated as roots.
+ // Editing files in the module cache isn't a great idea, so we don't
+ // plan to ever support that.
+ out, err := state.invokeGo("list", "-m", "-json", "all")
+ if err != nil {
+ // 'go list all' will fail if we're outside of a module and
+ // GO111MODULE=on. Try falling back without 'all'.
+ var innerErr error
+ out, innerErr = state.invokeGo("list", "-m", "-json")
+ if innerErr != nil {
+ return nil, err
+ }
+ }
+ roots := map[string]string{}
+ modules := map[string]string{}
+ var i int
+ for dec := json.NewDecoder(out); dec.More(); {
+ mod := new(gocommand.ModuleJSON)
+ if err := dec.Decode(mod); err != nil {
+ return nil, err
+ }
+ if mod.Dir != "" && mod.Path != "" {
+ // This is a valid module; add it to the map.
+ absDir, err := filepath.Abs(mod.Dir)
+ if err != nil {
+ return nil, err
+ }
+ modules[absDir] = mod.Path
+ // The first result is the main module.
+ if i == 0 || mod.Replace != nil && mod.Replace.Path != "" {
+ roots[absDir] = mod.Path
+ }
+ }
+ i++
+ }
+ return roots, nil
+}
+
+func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) {
+ m := map[string]string{}
+ for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) {
+ absDir, err := filepath.Abs(dir)
+ if err != nil {
+ return nil, err
+ }
+ m[filepath.Join(absDir, "src")] = ""
+ }
+ return m, nil
+}
diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go
new file mode 100644
index 00000000..5c080d21
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/loadmode_string.go
@@ -0,0 +1,57 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+import (
+ "fmt"
+ "strings"
+)
+
+var allModes = []LoadMode{
+ NeedName,
+ NeedFiles,
+ NeedCompiledGoFiles,
+ NeedImports,
+ NeedDeps,
+ NeedExportFile,
+ NeedTypes,
+ NeedSyntax,
+ NeedTypesInfo,
+ NeedTypesSizes,
+}
+
+var modeStrings = []string{
+ "NeedName",
+ "NeedFiles",
+ "NeedCompiledGoFiles",
+ "NeedImports",
+ "NeedDeps",
+ "NeedExportFile",
+ "NeedTypes",
+ "NeedSyntax",
+ "NeedTypesInfo",
+ "NeedTypesSizes",
+}
+
+func (mod LoadMode) String() string {
+ m := mod
+ if m == 0 {
+ return "LoadMode(0)"
+ }
+ var out []string
+ for i, x := range allModes {
+ if x > m {
+ break
+ }
+ if (m & x) != 0 {
+ out = append(out, modeStrings[i])
+ m = m ^ x
+ }
+ }
+ if m != 0 {
+ out = append(out, "Unknown")
+ }
+ return fmt.Sprintf("LoadMode(%s)", strings.Join(out, "|"))
+}
diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go
new file mode 100644
index 00000000..34306ddd
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/packages.go
@@ -0,0 +1,1510 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+// See doc.go for package documentation and implementation notes.
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/scanner"
+ "go/token"
+ "go/types"
+ "io"
+ "log"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "sync"
+ "time"
+
+ "golang.org/x/sync/errgroup"
+
+ "golang.org/x/tools/go/gcexportdata"
+ "golang.org/x/tools/internal/gocommand"
+ "golang.org/x/tools/internal/packagesinternal"
+ "golang.org/x/tools/internal/typesinternal"
+ "golang.org/x/tools/internal/versions"
+)
+
+// A LoadMode controls the amount of detail to return when loading.
+// The bits below can be combined to specify which fields should be
+// filled in the result packages.
+//
+// The zero value is a special case, equivalent to combining
+// the NeedName, NeedFiles, and NeedCompiledGoFiles bits.
+//
+// ID and Errors (if present) will always be filled.
+// [Load] may return more information than requested.
+//
+// Unfortunately there are a number of open bugs related to
+// interactions among the LoadMode bits:
+// - https://github.com/golang/go/issues/48226
+// - https://github.com/golang/go/issues/56633
+// - https://github.com/golang/go/issues/56677
+// - https://github.com/golang/go/issues/58726
+// - https://github.com/golang/go/issues/63517
+type LoadMode int
+
+const (
+ // NeedName adds Name and PkgPath.
+ NeedName LoadMode = 1 << iota
+
+ // NeedFiles adds GoFiles and OtherFiles.
+ NeedFiles
+
+ // NeedCompiledGoFiles adds CompiledGoFiles.
+ NeedCompiledGoFiles
+
+ // NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain
+ // "placeholder" Packages with only the ID set.
+ NeedImports
+
+ // NeedDeps adds the fields requested by the LoadMode in the packages in Imports.
+ NeedDeps
+
+ // NeedExportFile adds ExportFile.
+ NeedExportFile
+
+ // NeedTypes adds Types, Fset, and IllTyped.
+ NeedTypes
+
+ // NeedSyntax adds Syntax.
+ NeedSyntax
+
+ // NeedTypesInfo adds TypesInfo.
+ NeedTypesInfo
+
+ // NeedTypesSizes adds TypesSizes.
+ NeedTypesSizes
+
+ // needInternalDepsErrors adds the internal deps errors field for use by gopls.
+ needInternalDepsErrors
+
+ // needInternalForTest adds the internal forTest field.
+ // Tests must also be set on the context for this field to be populated.
+ needInternalForTest
+
+ // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+.
+ // Modifies CompiledGoFiles and Types, and has no effect on its own.
+ typecheckCgo
+
+ // NeedModule adds Module.
+ NeedModule
+
+ // NeedEmbedFiles adds EmbedFiles.
+ NeedEmbedFiles
+
+ // NeedEmbedPatterns adds EmbedPatterns.
+ NeedEmbedPatterns
+)
+
+const (
+ // Deprecated: LoadFiles exists for historical compatibility
+ // and should not be used. Please directly specify the needed fields using the Need values.
+ LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles
+
+ // Deprecated: LoadImports exists for historical compatibility
+ // and should not be used. Please directly specify the needed fields using the Need values.
+ LoadImports = LoadFiles | NeedImports
+
+ // Deprecated: LoadTypes exists for historical compatibility
+ // and should not be used. Please directly specify the needed fields using the Need values.
+ LoadTypes = LoadImports | NeedTypes | NeedTypesSizes
+
+ // Deprecated: LoadSyntax exists for historical compatibility
+ // and should not be used. Please directly specify the needed fields using the Need values.
+ LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo
+
+ // Deprecated: LoadAllSyntax exists for historical compatibility
+ // and should not be used. Please directly specify the needed fields using the Need values.
+ LoadAllSyntax = LoadSyntax | NeedDeps
+
+ // Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile.
+ NeedExportsFile = NeedExportFile
+)
+
+// A Config specifies details about how packages should be loaded.
+// The zero value is a valid configuration.
+//
+// Calls to Load do not modify this struct.
+//
+// TODO(adonovan): #67702: this is currently false: in fact,
+// calls to [Load] do not modify the public fields of this struct, but
+// may modify hidden fields, so concurrent calls to [Load] must not
+// use the same Config. But perhaps we should reestablish the
+// documented invariant.
+type Config struct {
+ // Mode controls the level of information returned for each package.
+ Mode LoadMode
+
+ // Context specifies the context for the load operation.
+ // Cancelling the context may cause [Load] to abort and
+ // return an error.
+ Context context.Context
+
+ // Logf is the logger for the config.
+ // If the user provides a logger, debug logging is enabled.
+ // If the GOPACKAGESDEBUG environment variable is set to true,
+ // but the logger is nil, default to log.Printf.
+ Logf func(format string, args ...interface{})
+
+ // Dir is the directory in which to run the build system's query tool
+ // that provides information about the packages.
+ // If Dir is empty, the tool is run in the current directory.
+ Dir string
+
+ // Env is the environment to use when invoking the build system's query tool.
+ // If Env is nil, the current environment is used.
+ // As in os/exec's Cmd, only the last value in the slice for
+ // each environment key is used. To specify the setting of only
+ // a few variables, append to the current environment, as in:
+ //
+ // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386")
+ //
+ Env []string
+
+ // gocmdRunner guards go command calls from concurrency errors.
+ gocmdRunner *gocommand.Runner
+
+ // BuildFlags is a list of command-line flags to be passed through to
+ // the build system's query tool.
+ BuildFlags []string
+
+ // modFile will be used for -modfile in go command invocations.
+ modFile string
+
+ // modFlag will be used for -modfile in go command invocations.
+ modFlag string
+
+ // Fset provides source position information for syntax trees and types.
+ // If Fset is nil, Load will use a new fileset, but preserve Fset's value.
+ Fset *token.FileSet
+
+ // ParseFile is called to read and parse each file
+ // when preparing a package's type-checked syntax tree.
+ // It must be safe to call ParseFile simultaneously from multiple goroutines.
+ // If ParseFile is nil, the loader will uses parser.ParseFile.
+ //
+ // ParseFile should parse the source from src and use filename only for
+ // recording position information.
+ //
+ // An application may supply a custom implementation of ParseFile
+ // to change the effective file contents or the behavior of the parser,
+ // or to modify the syntax tree. For example, selectively eliminating
+ // unwanted function bodies can significantly accelerate type checking.
+ ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error)
+
+ // If Tests is set, the loader includes not just the packages
+ // matching a particular pattern but also any related test packages,
+ // including test-only variants of the package and the test executable.
+ //
+ // For example, when using the go command, loading "fmt" with Tests=true
+ // returns four packages, with IDs "fmt" (the standard package),
+ // "fmt [fmt.test]" (the package as compiled for the test),
+ // "fmt_test" (the test functions from source files in package fmt_test),
+ // and "fmt.test" (the test binary).
+ //
+ // In build systems with explicit names for tests,
+ // setting Tests may have no effect.
+ Tests bool
+
+ // Overlay is a mapping from absolute file paths to file contents.
+ //
+ // For each map entry, [Load] uses the alternative file
+ // contents provided by the overlay mapping instead of reading
+ // from the file system. This mechanism can be used to enable
+ // editor-integrated tools to correctly analyze the contents
+ // of modified but unsaved buffers, for example.
+ //
+ // The overlay mapping is passed to the build system's driver
+ // (see "The driver protocol") so that it too can report
+ // consistent package metadata about unsaved files. However,
+ // drivers may vary in their level of support for overlays.
+ Overlay map[string][]byte
+
+ // goListOverlayFile is the JSON file that encodes the Overlay
+ // mapping, used by 'go list -overlay=...'
+ goListOverlayFile string
+}
+
+// Load loads and returns the Go packages named by the given patterns.
+//
+// Config specifies loading options;
+// nil behaves the same as an empty Config.
+//
+// The [Config.Mode] field is a set of bits that determine what kinds
+// of information should be computed and returned. Modes that require
+// more information tend to be slower. See [LoadMode] for details
+// and important caveats. Its zero value is equivalent to
+// NeedName | NeedFiles | NeedCompiledGoFiles.
+//
+// Each call to Load returns a new set of [Package] instances.
+// The Packages and their Imports form a directed acyclic graph.
+//
+// If the [NeedTypes] mode flag was set, each call to Load uses a new
+// [types.Importer], so [types.Object] and [types.Type] values from
+// different calls to Load must not be mixed as they will have
+// inconsistent notions of type identity.
+//
+// If any of the patterns was invalid as defined by the
+// underlying build system, Load returns an error.
+// It may return an empty list of packages without an error,
+// for instance for an empty expansion of a valid wildcard.
+// Errors associated with a particular package are recorded in the
+// corresponding Package's Errors list, and do not cause Load to
+// return an error. Clients may need to handle such errors before
+// proceeding with further analysis. The PrintErrors function is
+// provided for convenient display of all errors.
+func Load(cfg *Config, patterns ...string) ([]*Package, error) {
+ ld := newLoader(cfg)
+ response, external, err := defaultDriver(&ld.Config, patterns...)
+ if err != nil {
+ return nil, err
+ }
+
+ ld.sizes = types.SizesFor(response.Compiler, response.Arch)
+ if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 {
+ // Type size information is needed but unavailable.
+ if external {
+ // An external driver may fail to populate the Compiler/GOARCH fields,
+ // especially since they are relatively new (see #63700).
+ // Provide a sensible fallback in this case.
+ ld.sizes = types.SizesFor("gc", runtime.GOARCH)
+ if ld.sizes == nil { // gccgo-only arch
+ ld.sizes = types.SizesFor("gc", "amd64")
+ }
+ } else {
+ // Go list should never fail to deliver accurate size information.
+ // Reject the whole Load since the error is the same for every package.
+ return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q",
+ response.Compiler, response.Arch)
+ }
+ }
+
+ return ld.refine(response)
+}
+
+// defaultDriver is a driver that implements go/packages' fallback behavior.
+// It will try to request to an external driver, if one exists. If there's
+// no external driver, or the driver returns a response with NotHandled set,
+// defaultDriver will fall back to the go list driver.
+// The boolean result indicates that an external driver handled the request.
+func defaultDriver(cfg *Config, patterns ...string) (*DriverResponse, bool, error) {
+ const (
+ // windowsArgMax specifies the maximum command line length for
+ // the Windows' CreateProcess function.
+ windowsArgMax = 32767
+ // maxEnvSize is a very rough estimation of the maximum environment
+ // size of a user.
+ maxEnvSize = 16384
+ // safeArgMax specifies the maximum safe command line length to use
+ // by the underlying driver excl. the environment. We choose the Windows'
+ // ARG_MAX as the starting point because it's one of the lowest ARG_MAX
+ // constants out of the different supported platforms,
+ // e.g., https://www.in-ulm.de/~mascheck/various/argmax/#results.
+ safeArgMax = windowsArgMax - maxEnvSize
+ )
+ chunks, err := splitIntoChunks(patterns, safeArgMax)
+ if err != nil {
+ return nil, false, err
+ }
+
+ if driver := findExternalDriver(cfg); driver != nil {
+ response, err := callDriverOnChunks(driver, cfg, chunks)
+ if err != nil {
+ return nil, false, err
+ } else if !response.NotHandled {
+ return response, true, nil
+ }
+ // (fall through)
+ }
+
+ // go list fallback
+ //
+ // Write overlays once, as there are many calls
+ // to 'go list' (one per chunk plus others too).
+ overlay, cleanupOverlay, err := gocommand.WriteOverlays(cfg.Overlay)
+ if err != nil {
+ return nil, false, err
+ }
+ defer cleanupOverlay()
+ cfg.goListOverlayFile = overlay
+
+ response, err := callDriverOnChunks(goListDriver, cfg, chunks)
+ if err != nil {
+ return nil, false, err
+ }
+ return response, false, err
+}
+
+// splitIntoChunks chunks the slice so that the total number of characters
+// in a chunk is no longer than argMax.
+func splitIntoChunks(patterns []string, argMax int) ([][]string, error) {
+ if argMax <= 0 {
+ return nil, errors.New("failed to split patterns into chunks, negative safe argMax value")
+ }
+ var chunks [][]string
+ charsInChunk := 0
+ nextChunkStart := 0
+ for i, v := range patterns {
+ vChars := len(v)
+ if vChars > argMax {
+ // a single pattern is longer than the maximum safe ARG_MAX, hardly should happen
+ return nil, errors.New("failed to split patterns into chunks, a pattern is too long")
+ }
+ charsInChunk += vChars + 1 // +1 is for a whitespace between patterns that has to be counted too
+ if charsInChunk > argMax {
+ chunks = append(chunks, patterns[nextChunkStart:i])
+ nextChunkStart = i
+ charsInChunk = vChars
+ }
+ }
+ // add the last chunk
+ if nextChunkStart < len(patterns) {
+ chunks = append(chunks, patterns[nextChunkStart:])
+ }
+ return chunks, nil
+}
+
+func callDriverOnChunks(driver driver, cfg *Config, chunks [][]string) (*DriverResponse, error) {
+ if len(chunks) == 0 {
+ return driver(cfg)
+ }
+ responses := make([]*DriverResponse, len(chunks))
+ errNotHandled := errors.New("driver returned NotHandled")
+ var g errgroup.Group
+ for i, chunk := range chunks {
+ i := i
+ chunk := chunk
+ g.Go(func() (err error) {
+ responses[i], err = driver(cfg, chunk...)
+ if responses[i] != nil && responses[i].NotHandled {
+ err = errNotHandled
+ }
+ return err
+ })
+ }
+ if err := g.Wait(); err != nil {
+ if errors.Is(err, errNotHandled) {
+ return &DriverResponse{NotHandled: true}, nil
+ }
+ return nil, err
+ }
+ return mergeResponses(responses...), nil
+}
+
+func mergeResponses(responses ...*DriverResponse) *DriverResponse {
+ if len(responses) == 0 {
+ return nil
+ }
+ response := newDeduper()
+ response.dr.NotHandled = false
+ response.dr.Compiler = responses[0].Compiler
+ response.dr.Arch = responses[0].Arch
+ response.dr.GoVersion = responses[0].GoVersion
+ for _, v := range responses {
+ response.addAll(v)
+ }
+ return response.dr
+}
+
+// A Package describes a loaded Go package.
+//
+// It also defines part of the JSON schema of [DriverResponse].
+// See the package documentation for an overview.
+type Package struct {
+ // ID is a unique identifier for a package,
+ // in a syntax provided by the underlying build system.
+ //
+ // Because the syntax varies based on the build system,
+ // clients should treat IDs as opaque and not attempt to
+ // interpret them.
+ ID string
+
+ // Name is the package name as it appears in the package source code.
+ Name string
+
+ // PkgPath is the package path as used by the go/types package.
+ PkgPath string
+
+ // Errors contains any errors encountered querying the metadata
+ // of the package, or while parsing or type-checking its files.
+ Errors []Error
+
+ // TypeErrors contains the subset of errors produced during type checking.
+ TypeErrors []types.Error
+
+ // GoFiles lists the absolute file paths of the package's Go source files.
+ // It may include files that should not be compiled, for example because
+ // they contain non-matching build tags, are documentary pseudo-files such as
+ // unsafe/unsafe.go or builtin/builtin.go, or are subject to cgo preprocessing.
+ GoFiles []string
+
+ // CompiledGoFiles lists the absolute file paths of the package's source
+ // files that are suitable for type checking.
+ // This may differ from GoFiles if files are processed before compilation.
+ CompiledGoFiles []string
+
+ // OtherFiles lists the absolute file paths of the package's non-Go source files,
+ // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on.
+ OtherFiles []string
+
+ // EmbedFiles lists the absolute file paths of the package's files
+ // embedded with go:embed.
+ EmbedFiles []string
+
+ // EmbedPatterns lists the absolute file patterns of the package's
+ // files embedded with go:embed.
+ EmbedPatterns []string
+
+ // IgnoredFiles lists source files that are not part of the package
+ // using the current build configuration but that might be part of
+ // the package using other build configurations.
+ IgnoredFiles []string
+
+ // ExportFile is the absolute path to a file containing type
+ // information for the package as provided by the build system.
+ ExportFile string
+
+ // Imports maps import paths appearing in the package's Go source files
+ // to corresponding loaded Packages.
+ Imports map[string]*Package
+
+ // Module is the module information for the package if it exists.
+ //
+ // Note: it may be missing for std and cmd; see Go issue #65816.
+ Module *Module
+
+ // -- The following fields are not part of the driver JSON schema. --
+
+ // Types provides type information for the package.
+ // The NeedTypes LoadMode bit sets this field for packages matching the
+ // patterns; type information for dependencies may be missing or incomplete,
+ // unless NeedDeps and NeedImports are also set.
+ //
+ // Each call to [Load] returns a consistent set of type
+ // symbols, as defined by the comment at [types.Identical].
+ // Avoid mixing type information from two or more calls to [Load].
+ Types *types.Package `json:"-"`
+
+ // Fset provides position information for Types, TypesInfo, and Syntax.
+ // It is set only when Types is set.
+ Fset *token.FileSet `json:"-"`
+
+ // IllTyped indicates whether the package or any dependency contains errors.
+ // It is set only when Types is set.
+ IllTyped bool `json:"-"`
+
+ // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles.
+ //
+ // The NeedSyntax LoadMode bit populates this field for packages matching the patterns.
+ // If NeedDeps and NeedImports are also set, this field will also be populated
+ // for dependencies.
+ //
+ // Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are
+ // removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles.
+ Syntax []*ast.File `json:"-"`
+
+ // TypesInfo provides type information about the package's syntax trees.
+ // It is set only when Syntax is set.
+ TypesInfo *types.Info `json:"-"`
+
+ // TypesSizes provides the effective size function for types in TypesInfo.
+ TypesSizes types.Sizes `json:"-"`
+
+ // -- internal --
+
+ // forTest is the package under test, if any.
+ forTest string
+
+ // depsErrors is the DepsErrors field from the go list response, if any.
+ depsErrors []*packagesinternal.PackageError
+}
+
+// Module provides module information for a package.
+//
+// It also defines part of the JSON schema of [DriverResponse].
+// See the package documentation for an overview.
+type Module struct {
+ Path string // module path
+ Version string // module version
+ Replace *Module // replaced by this module
+ Time *time.Time // time version was created
+ Main bool // is this the main module?
+ Indirect bool // is this module only an indirect dependency of main module?
+ Dir string // directory holding files for this module, if any
+ GoMod string // path to go.mod file used when loading this module, if any
+ GoVersion string // go version used in module
+ Error *ModuleError // error loading module
+}
+
+// ModuleError holds errors loading a module.
+type ModuleError struct {
+ Err string // the error itself
+}
+
+func init() {
+ packagesinternal.GetForTest = func(p interface{}) string {
+ return p.(*Package).forTest
+ }
+ packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError {
+ return p.(*Package).depsErrors
+ }
+ packagesinternal.SetModFile = func(config interface{}, value string) {
+ config.(*Config).modFile = value
+ }
+ packagesinternal.SetModFlag = func(config interface{}, value string) {
+ config.(*Config).modFlag = value
+ }
+ packagesinternal.TypecheckCgo = int(typecheckCgo)
+ packagesinternal.DepsErrors = int(needInternalDepsErrors)
+ packagesinternal.ForTest = int(needInternalForTest)
+}
+
+// An Error describes a problem with a package's metadata, syntax, or types.
+type Error struct {
+ Pos string // "file:line:col" or "file:line" or "" or "-"
+ Msg string
+ Kind ErrorKind
+}
+
+// ErrorKind describes the source of the error, allowing the user to
+// differentiate between errors generated by the driver, the parser, or the
+// type-checker.
+type ErrorKind int
+
+const (
+ UnknownError ErrorKind = iota
+ ListError
+ ParseError
+ TypeError
+)
+
+func (err Error) Error() string {
+ pos := err.Pos
+ if pos == "" {
+ pos = "-" // like token.Position{}.String()
+ }
+ return pos + ": " + err.Msg
+}
+
+// flatPackage is the JSON form of Package
+// It drops all the type and syntax fields, and transforms the Imports
+//
+// TODO(adonovan): identify this struct with Package, effectively
+// publishing the JSON protocol.
+type flatPackage struct {
+ ID string
+ Name string `json:",omitempty"`
+ PkgPath string `json:",omitempty"`
+ Errors []Error `json:",omitempty"`
+ GoFiles []string `json:",omitempty"`
+ CompiledGoFiles []string `json:",omitempty"`
+ OtherFiles []string `json:",omitempty"`
+ EmbedFiles []string `json:",omitempty"`
+ EmbedPatterns []string `json:",omitempty"`
+ IgnoredFiles []string `json:",omitempty"`
+ ExportFile string `json:",omitempty"`
+ Imports map[string]string `json:",omitempty"`
+}
+
+// MarshalJSON returns the Package in its JSON form.
+// For the most part, the structure fields are written out unmodified, and
+// the type and syntax fields are skipped.
+// The imports are written out as just a map of path to package id.
+// The errors are written using a custom type that tries to preserve the
+// structure of error types we know about.
+//
+// This method exists to enable support for additional build systems. It is
+// not intended for use by clients of the API and we may change the format.
+func (p *Package) MarshalJSON() ([]byte, error) {
+ flat := &flatPackage{
+ ID: p.ID,
+ Name: p.Name,
+ PkgPath: p.PkgPath,
+ Errors: p.Errors,
+ GoFiles: p.GoFiles,
+ CompiledGoFiles: p.CompiledGoFiles,
+ OtherFiles: p.OtherFiles,
+ EmbedFiles: p.EmbedFiles,
+ EmbedPatterns: p.EmbedPatterns,
+ IgnoredFiles: p.IgnoredFiles,
+ ExportFile: p.ExportFile,
+ }
+ if len(p.Imports) > 0 {
+ flat.Imports = make(map[string]string, len(p.Imports))
+ for path, ipkg := range p.Imports {
+ flat.Imports[path] = ipkg.ID
+ }
+ }
+ return json.Marshal(flat)
+}
+
+// UnmarshalJSON reads in a Package from its JSON format.
+// See MarshalJSON for details about the format accepted.
+func (p *Package) UnmarshalJSON(b []byte) error {
+ flat := &flatPackage{}
+ if err := json.Unmarshal(b, &flat); err != nil {
+ return err
+ }
+ *p = Package{
+ ID: flat.ID,
+ Name: flat.Name,
+ PkgPath: flat.PkgPath,
+ Errors: flat.Errors,
+ GoFiles: flat.GoFiles,
+ CompiledGoFiles: flat.CompiledGoFiles,
+ OtherFiles: flat.OtherFiles,
+ EmbedFiles: flat.EmbedFiles,
+ EmbedPatterns: flat.EmbedPatterns,
+ IgnoredFiles: flat.IgnoredFiles,
+ ExportFile: flat.ExportFile,
+ }
+ if len(flat.Imports) > 0 {
+ p.Imports = make(map[string]*Package, len(flat.Imports))
+ for path, id := range flat.Imports {
+ p.Imports[path] = &Package{ID: id}
+ }
+ }
+ return nil
+}
+
+func (p *Package) String() string { return p.ID }
+
+// loaderPackage augments Package with state used during the loading phase
+type loaderPackage struct {
+ *Package
+ importErrors map[string]error // maps each bad import to its error
+ loadOnce sync.Once
+ color uint8 // for cycle detection
+ needsrc bool // load from source (Mode >= LoadTypes)
+ needtypes bool // type information is either requested or depended on
+ initial bool // package was matched by a pattern
+ goVersion int // minor version number of go command on PATH
+}
+
+// loader holds the working state of a single call to load.
+type loader struct {
+ pkgs map[string]*loaderPackage
+ Config
+ sizes types.Sizes // non-nil if needed by mode
+ parseCache map[string]*parseValue
+ parseCacheMu sync.Mutex
+ exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
+
+ // Config.Mode contains the implied mode (see impliedLoadMode).
+ // Implied mode contains all the fields we need the data for.
+ // In requestedMode there are the actually requested fields.
+ // We'll zero them out before returning packages to the user.
+ // This makes it easier for us to get the conditions where
+ // we need certain modes right.
+ requestedMode LoadMode
+}
+
+type parseValue struct {
+ f *ast.File
+ err error
+ ready chan struct{}
+}
+
+func newLoader(cfg *Config) *loader {
+ ld := &loader{
+ parseCache: map[string]*parseValue{},
+ }
+ if cfg != nil {
+ ld.Config = *cfg
+ // If the user has provided a logger, use it.
+ ld.Config.Logf = cfg.Logf
+ }
+ if ld.Config.Logf == nil {
+ // If the GOPACKAGESDEBUG environment variable is set to true,
+ // but the user has not provided a logger, default to log.Printf.
+ if debug {
+ ld.Config.Logf = log.Printf
+ } else {
+ ld.Config.Logf = func(format string, args ...interface{}) {}
+ }
+ }
+ if ld.Config.Mode == 0 {
+ ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility.
+ }
+ if ld.Config.Env == nil {
+ ld.Config.Env = os.Environ()
+ }
+ if ld.Config.gocmdRunner == nil {
+ ld.Config.gocmdRunner = &gocommand.Runner{}
+ }
+ if ld.Context == nil {
+ ld.Context = context.Background()
+ }
+ if ld.Dir == "" {
+ if dir, err := os.Getwd(); err == nil {
+ ld.Dir = dir
+ }
+ }
+
+ // Save the actually requested fields. We'll zero them out before returning packages to the user.
+ ld.requestedMode = ld.Mode
+ ld.Mode = impliedLoadMode(ld.Mode)
+
+ if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
+ if ld.Fset == nil {
+ ld.Fset = token.NewFileSet()
+ }
+
+ // ParseFile is required even in LoadTypes mode
+ // because we load source if export data is missing.
+ if ld.ParseFile == nil {
+ ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
+ const mode = parser.AllErrors | parser.ParseComments
+ return parser.ParseFile(fset, filename, src, mode)
+ }
+ }
+ }
+
+ return ld
+}
+
+// refine connects the supplied packages into a graph and then adds type
+// and syntax information as requested by the LoadMode.
+func (ld *loader) refine(response *DriverResponse) ([]*Package, error) {
+ roots := response.Roots
+ rootMap := make(map[string]int, len(roots))
+ for i, root := range roots {
+ rootMap[root] = i
+ }
+ ld.pkgs = make(map[string]*loaderPackage)
+ // first pass, fixup and build the map and roots
+ var initial = make([]*loaderPackage, len(roots))
+ for _, pkg := range response.Packages {
+ rootIndex := -1
+ if i, found := rootMap[pkg.ID]; found {
+ rootIndex = i
+ }
+
+ // Overlays can invalidate export data.
+ // TODO(matloob): make this check fine-grained based on dependencies on overlaid files
+ exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe"
+ // This package needs type information if the caller requested types and the package is
+ // either a root, or it's a non-root and the user requested dependencies ...
+ needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0))
+ // This package needs source if the call requested source (or types info, which implies source)
+ // and the package is either a root, or itas a non- root and the user requested dependencies...
+ needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) ||
+ // ... or if we need types and the exportData is invalid. We fall back to (incompletely)
+ // typechecking packages from source if they fail to compile.
+ (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe"
+ lpkg := &loaderPackage{
+ Package: pkg,
+ needtypes: needtypes,
+ needsrc: needsrc,
+ goVersion: response.GoVersion,
+ }
+ ld.pkgs[lpkg.ID] = lpkg
+ if rootIndex >= 0 {
+ initial[rootIndex] = lpkg
+ lpkg.initial = true
+ }
+ }
+ for i, root := range roots {
+ if initial[i] == nil {
+ return nil, fmt.Errorf("root package %v is missing", root)
+ }
+ }
+
+ if ld.Mode&NeedImports != 0 {
+ // Materialize the import graph.
+
+ const (
+ white = 0 // new
+ grey = 1 // in progress
+ black = 2 // complete
+ )
+
+ // visit traverses the import graph, depth-first,
+ // and materializes the graph as Packages.Imports.
+ //
+ // Valid imports are saved in the Packages.Import map.
+ // Invalid imports (cycles and missing nodes) are saved in the importErrors map.
+ // Thus, even in the presence of both kinds of errors,
+ // the Import graph remains a DAG.
+ //
+ // visit returns whether the package needs src or has a transitive
+ // dependency on a package that does. These are the only packages
+ // for which we load source code.
+ var stack []*loaderPackage
+ var visit func(lpkg *loaderPackage) bool
+ visit = func(lpkg *loaderPackage) bool {
+ switch lpkg.color {
+ case black:
+ return lpkg.needsrc
+ case grey:
+ panic("internal error: grey node")
+ }
+ lpkg.color = grey
+ stack = append(stack, lpkg) // push
+ stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
+ lpkg.Imports = make(map[string]*Package, len(stubs))
+ for importPath, ipkg := range stubs {
+ var importErr error
+ imp := ld.pkgs[ipkg.ID]
+ if imp == nil {
+ // (includes package "C" when DisableCgo)
+ importErr = fmt.Errorf("missing package: %q", ipkg.ID)
+ } else if imp.color == grey {
+ importErr = fmt.Errorf("import cycle: %s", stack)
+ }
+ if importErr != nil {
+ if lpkg.importErrors == nil {
+ lpkg.importErrors = make(map[string]error)
+ }
+ lpkg.importErrors[importPath] = importErr
+ continue
+ }
+
+ if visit(imp) {
+ lpkg.needsrc = true
+ }
+ lpkg.Imports[importPath] = imp.Package
+ }
+
+ // Complete type information is required for the
+ // immediate dependencies of each source package.
+ if lpkg.needsrc && ld.Mode&NeedTypes != 0 {
+ for _, ipkg := range lpkg.Imports {
+ ld.pkgs[ipkg.ID].needtypes = true
+ }
+ }
+
+ // NeedTypeSizes causes TypeSizes to be set even
+ // on packages for which types aren't needed.
+ if ld.Mode&NeedTypesSizes != 0 {
+ lpkg.TypesSizes = ld.sizes
+ }
+ stack = stack[:len(stack)-1] // pop
+ lpkg.color = black
+
+ return lpkg.needsrc
+ }
+
+ // For each initial package, create its import DAG.
+ for _, lpkg := range initial {
+ visit(lpkg)
+ }
+
+ } else {
+ // !NeedImports: drop the stub (ID-only) import packages
+ // that we are not even going to try to resolve.
+ for _, lpkg := range initial {
+ lpkg.Imports = nil
+ }
+ }
+
+ // Load type data and syntax if needed, starting at
+ // the initial packages (roots of the import DAG).
+ if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
+ var wg sync.WaitGroup
+ for _, lpkg := range initial {
+ wg.Add(1)
+ go func(lpkg *loaderPackage) {
+ ld.loadRecursive(lpkg)
+ wg.Done()
+ }(lpkg)
+ }
+ wg.Wait()
+ }
+
+ // If the context is done, return its error and
+ // throw out [likely] incomplete packages.
+ if err := ld.Context.Err(); err != nil {
+ return nil, err
+ }
+
+ result := make([]*Package, len(initial))
+ for i, lpkg := range initial {
+ result[i] = lpkg.Package
+ }
+ for i := range ld.pkgs {
+ // Clear all unrequested fields,
+ // to catch programs that use more than they request.
+ if ld.requestedMode&NeedName == 0 {
+ ld.pkgs[i].Name = ""
+ ld.pkgs[i].PkgPath = ""
+ }
+ if ld.requestedMode&NeedFiles == 0 {
+ ld.pkgs[i].GoFiles = nil
+ ld.pkgs[i].OtherFiles = nil
+ ld.pkgs[i].IgnoredFiles = nil
+ }
+ if ld.requestedMode&NeedEmbedFiles == 0 {
+ ld.pkgs[i].EmbedFiles = nil
+ }
+ if ld.requestedMode&NeedEmbedPatterns == 0 {
+ ld.pkgs[i].EmbedPatterns = nil
+ }
+ if ld.requestedMode&NeedCompiledGoFiles == 0 {
+ ld.pkgs[i].CompiledGoFiles = nil
+ }
+ if ld.requestedMode&NeedImports == 0 {
+ ld.pkgs[i].Imports = nil
+ }
+ if ld.requestedMode&NeedExportFile == 0 {
+ ld.pkgs[i].ExportFile = ""
+ }
+ if ld.requestedMode&NeedTypes == 0 {
+ ld.pkgs[i].Types = nil
+ ld.pkgs[i].Fset = nil
+ ld.pkgs[i].IllTyped = false
+ }
+ if ld.requestedMode&NeedSyntax == 0 {
+ ld.pkgs[i].Syntax = nil
+ }
+ if ld.requestedMode&NeedTypesInfo == 0 {
+ ld.pkgs[i].TypesInfo = nil
+ }
+ if ld.requestedMode&NeedTypesSizes == 0 {
+ ld.pkgs[i].TypesSizes = nil
+ }
+ if ld.requestedMode&NeedModule == 0 {
+ ld.pkgs[i].Module = nil
+ }
+ }
+
+ return result, nil
+}
+
+// loadRecursive loads the specified package and its dependencies,
+// recursively, in parallel, in topological order.
+// It is atomic and idempotent.
+// Precondition: ld.Mode&NeedTypes.
+func (ld *loader) loadRecursive(lpkg *loaderPackage) {
+ lpkg.loadOnce.Do(func() {
+ // Load the direct dependencies, in parallel.
+ var wg sync.WaitGroup
+ for _, ipkg := range lpkg.Imports {
+ imp := ld.pkgs[ipkg.ID]
+ wg.Add(1)
+ go func(imp *loaderPackage) {
+ ld.loadRecursive(imp)
+ wg.Done()
+ }(imp)
+ }
+ wg.Wait()
+ ld.loadPackage(lpkg)
+ })
+}
+
+// loadPackage loads the specified package.
+// It must be called only once per Package,
+// after immediate dependencies are loaded.
+// Precondition: ld.Mode & NeedTypes.
+func (ld *loader) loadPackage(lpkg *loaderPackage) {
+ if lpkg.PkgPath == "unsafe" {
+ // Fill in the blanks to avoid surprises.
+ lpkg.Types = types.Unsafe
+ lpkg.Fset = ld.Fset
+ lpkg.Syntax = []*ast.File{}
+ lpkg.TypesInfo = new(types.Info)
+ lpkg.TypesSizes = ld.sizes
+ return
+ }
+
+ // Call NewPackage directly with explicit name.
+ // This avoids skew between golist and go/types when the files'
+ // package declarations are inconsistent.
+ lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name)
+ lpkg.Fset = ld.Fset
+
+ // Start shutting down if the context is done and do not load
+ // source or export data files.
+ // Packages that import this one will have ld.Context.Err() != nil.
+ // ld.Context.Err() will be returned later by refine.
+ if ld.Context.Err() != nil {
+ return
+ }
+
+ // Subtle: we populate all Types fields with an empty Package
+ // before loading export data so that export data processing
+ // never has to create a types.Package for an indirect dependency,
+ // which would then require that such created packages be explicitly
+ // inserted back into the Import graph as a final step after export data loading.
+ // (Hence this return is after the Types assignment.)
+ // The Diamond test exercises this case.
+ if !lpkg.needtypes && !lpkg.needsrc {
+ return
+ }
+ if !lpkg.needsrc {
+ if err := ld.loadFromExportData(lpkg); err != nil {
+ lpkg.Errors = append(lpkg.Errors, Error{
+ Pos: "-",
+ Msg: err.Error(),
+ Kind: UnknownError, // e.g. can't find/open/parse export data
+ })
+ }
+ return // not a source package, don't get syntax trees
+ }
+
+ appendError := func(err error) {
+ // Convert various error types into the one true Error.
+ var errs []Error
+ switch err := err.(type) {
+ case Error:
+ // from driver
+ errs = append(errs, err)
+
+ case *os.PathError:
+ // from parser
+ errs = append(errs, Error{
+ Pos: err.Path + ":1",
+ Msg: err.Err.Error(),
+ Kind: ParseError,
+ })
+
+ case scanner.ErrorList:
+ // from parser
+ for _, err := range err {
+ errs = append(errs, Error{
+ Pos: err.Pos.String(),
+ Msg: err.Msg,
+ Kind: ParseError,
+ })
+ }
+
+ case types.Error:
+ // from type checker
+ lpkg.TypeErrors = append(lpkg.TypeErrors, err)
+ errs = append(errs, Error{
+ Pos: err.Fset.Position(err.Pos).String(),
+ Msg: err.Msg,
+ Kind: TypeError,
+ })
+
+ default:
+ // unexpected impoverished error from parser?
+ errs = append(errs, Error{
+ Pos: "-",
+ Msg: err.Error(),
+ Kind: UnknownError,
+ })
+
+ // If you see this error message, please file a bug.
+ log.Printf("internal error: error %q (%T) without position", err, err)
+ }
+
+ lpkg.Errors = append(lpkg.Errors, errs...)
+ }
+
+ // If the go command on the PATH is newer than the runtime,
+ // then the go/{scanner,ast,parser,types} packages from the
+ // standard library may be unable to process the files
+ // selected by go list.
+ //
+ // There is currently no way to downgrade the effective
+ // version of the go command (see issue 52078), so we proceed
+ // with the newer go command but, in case of parse or type
+ // errors, we emit an additional diagnostic.
+ //
+ // See:
+ // - golang.org/issue/52078 (flag to set release tags)
+ // - golang.org/issue/50825 (gopls legacy version support)
+ // - golang.org/issue/55883 (go/packages confusing error)
+ //
+ // Should we assert a hard minimum of (currently) go1.16 here?
+ var runtimeVersion int
+ if _, err := fmt.Sscanf(runtime.Version(), "go1.%d", &runtimeVersion); err == nil && runtimeVersion < lpkg.goVersion {
+ defer func() {
+ if len(lpkg.Errors) > 0 {
+ appendError(Error{
+ Pos: "-",
+ Msg: fmt.Sprintf("This application uses version go1.%d of the source-processing packages but runs version go1.%d of 'go list'. It may fail to process source files that rely on newer language features. If so, rebuild the application using a newer version of Go.", runtimeVersion, lpkg.goVersion),
+ Kind: UnknownError,
+ })
+ }
+ }()
+ }
+
+ if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" {
+ // The config requested loading sources and types, but sources are missing.
+ // Add an error to the package and fall back to loading from export data.
+ appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError})
+ _ = ld.loadFromExportData(lpkg) // ignore any secondary errors
+
+ return // can't get syntax trees for this package
+ }
+
+ files, errs := ld.parseFiles(lpkg.CompiledGoFiles)
+ for _, err := range errs {
+ appendError(err)
+ }
+
+ lpkg.Syntax = files
+ if ld.Config.Mode&NeedTypes == 0 {
+ return
+ }
+
+ // Start shutting down if the context is done and do not type check.
+ // Packages that import this one will have ld.Context.Err() != nil.
+ // ld.Context.Err() will be returned later by refine.
+ if ld.Context.Err() != nil {
+ return
+ }
+
+ lpkg.TypesInfo = &types.Info{
+ Types: make(map[ast.Expr]types.TypeAndValue),
+ Defs: make(map[*ast.Ident]types.Object),
+ Uses: make(map[*ast.Ident]types.Object),
+ Implicits: make(map[ast.Node]types.Object),
+ Instances: make(map[*ast.Ident]types.Instance),
+ Scopes: make(map[ast.Node]*types.Scope),
+ Selections: make(map[*ast.SelectorExpr]*types.Selection),
+ }
+ versions.InitFileVersions(lpkg.TypesInfo)
+ lpkg.TypesSizes = ld.sizes
+
+ importer := importerFunc(func(path string) (*types.Package, error) {
+ if path == "unsafe" {
+ return types.Unsafe, nil
+ }
+
+ // The imports map is keyed by import path.
+ ipkg := lpkg.Imports[path]
+ if ipkg == nil {
+ if err := lpkg.importErrors[path]; err != nil {
+ return nil, err
+ }
+ // There was skew between the metadata and the
+ // import declarations, likely due to an edit
+ // race, or because the ParseFile feature was
+ // used to supply alternative file contents.
+ return nil, fmt.Errorf("no metadata for %s", path)
+ }
+
+ if ipkg.Types != nil && ipkg.Types.Complete() {
+ return ipkg.Types, nil
+ }
+ log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg)
+ panic("unreachable")
+ })
+
+ // type-check
+ tc := &types.Config{
+ Importer: importer,
+
+ // Type-check bodies of functions only in initial packages.
+ // Example: for import graph A->B->C and initial packages {A,C},
+ // we can ignore function bodies in B.
+ IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial,
+
+ Error: appendError,
+ Sizes: ld.sizes, // may be nil
+ }
+ if lpkg.Module != nil && lpkg.Module.GoVersion != "" {
+ tc.GoVersion = "go" + lpkg.Module.GoVersion
+ }
+ if (ld.Mode & typecheckCgo) != 0 {
+ if !typesinternal.SetUsesCgo(tc) {
+ appendError(Error{
+ Msg: "typecheckCgo requires Go 1.15+",
+ Kind: ListError,
+ })
+ return
+ }
+ }
+
+ typErr := types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
+ lpkg.importErrors = nil // no longer needed
+
+ // In go/types go1.21 and go1.22, Checker.Files failed fast with a
+ // a "too new" error, without calling tc.Error and without
+ // proceeding to type-check the package (#66525).
+ // We rely on the runtimeVersion error to give the suggested remedy.
+ if typErr != nil && len(lpkg.Errors) == 0 && len(lpkg.Syntax) > 0 {
+ if msg := typErr.Error(); strings.HasPrefix(msg, "package requires newer Go version") {
+ appendError(types.Error{
+ Fset: ld.Fset,
+ Pos: lpkg.Syntax[0].Package,
+ Msg: msg,
+ })
+ }
+ }
+
+ // If !Cgo, the type-checker uses FakeImportC mode, so
+ // it doesn't invoke the importer for import "C",
+ // nor report an error for the import,
+ // or for any undefined C.f reference.
+ // We must detect this explicitly and correctly
+ // mark the package as IllTyped (by reporting an error).
+ // TODO(adonovan): if these errors are annoying,
+ // we could just set IllTyped quietly.
+ if tc.FakeImportC {
+ outer:
+ for _, f := range lpkg.Syntax {
+ for _, imp := range f.Imports {
+ if imp.Path.Value == `"C"` {
+ err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`}
+ appendError(err)
+ break outer
+ }
+ }
+ }
+ }
+
+ // If types.Checker.Files had an error that was unreported,
+ // make sure to report the unknown error so the package is illTyped.
+ if typErr != nil && len(lpkg.Errors) == 0 {
+ appendError(typErr)
+ }
+
+ // Record accumulated errors.
+ illTyped := len(lpkg.Errors) > 0
+ if !illTyped {
+ for _, imp := range lpkg.Imports {
+ if imp.IllTyped {
+ illTyped = true
+ break
+ }
+ }
+ }
+ lpkg.IllTyped = illTyped
+}
+
+// An importFunc is an implementation of the single-method
+// types.Importer interface based on a function value.
+type importerFunc func(path string) (*types.Package, error)
+
+func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
+
+// We use a counting semaphore to limit
+// the number of parallel I/O calls per process.
+var ioLimit = make(chan bool, 20)
+
+func (ld *loader) parseFile(filename string) (*ast.File, error) {
+ ld.parseCacheMu.Lock()
+ v, ok := ld.parseCache[filename]
+ if ok {
+ // cache hit
+ ld.parseCacheMu.Unlock()
+ <-v.ready
+ } else {
+ // cache miss
+ v = &parseValue{ready: make(chan struct{})}
+ ld.parseCache[filename] = v
+ ld.parseCacheMu.Unlock()
+
+ var src []byte
+ for f, contents := range ld.Config.Overlay {
+ if sameFile(f, filename) {
+ src = contents
+ }
+ }
+ var err error
+ if src == nil {
+ ioLimit <- true // wait
+ src, err = os.ReadFile(filename)
+ <-ioLimit // signal
+ }
+ if err != nil {
+ v.err = err
+ } else {
+ v.f, v.err = ld.ParseFile(ld.Fset, filename, src)
+ }
+
+ close(v.ready)
+ }
+ return v.f, v.err
+}
+
+// parseFiles reads and parses the Go source files and returns the ASTs
+// of the ones that could be at least partially parsed, along with a
+// list of I/O and parse errors encountered.
+//
+// Because files are scanned in parallel, the token.Pos
+// positions of the resulting ast.Files are not ordered.
+func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
+ var wg sync.WaitGroup
+ n := len(filenames)
+ parsed := make([]*ast.File, n)
+ errors := make([]error, n)
+ for i, file := range filenames {
+ wg.Add(1)
+ go func(i int, filename string) {
+ parsed[i], errors[i] = ld.parseFile(filename)
+ wg.Done()
+ }(i, file)
+ }
+ wg.Wait()
+
+ // Eliminate nils, preserving order.
+ var o int
+ for _, f := range parsed {
+ if f != nil {
+ parsed[o] = f
+ o++
+ }
+ }
+ parsed = parsed[:o]
+
+ o = 0
+ for _, err := range errors {
+ if err != nil {
+ errors[o] = err
+ o++
+ }
+ }
+ errors = errors[:o]
+
+ return parsed, errors
+}
+
+// sameFile returns true if x and y have the same basename and denote
+// the same file.
+func sameFile(x, y string) bool {
+ if x == y {
+ // It could be the case that y doesn't exist.
+ // For instance, it may be an overlay file that
+ // hasn't been written to disk. To handle that case
+ // let x == y through. (We added the exact absolute path
+ // string to the CompiledGoFiles list, so the unwritten
+ // overlay case implies x==y.)
+ return true
+ }
+ if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation)
+ if xi, err := os.Stat(x); err == nil {
+ if yi, err := os.Stat(y); err == nil {
+ return os.SameFile(xi, yi)
+ }
+ }
+ }
+ return false
+}
+
+// loadFromExportData ensures that type information is present for the specified
+// package, loading it from an export data file on the first request.
+// On success it sets lpkg.Types to a new Package.
+func (ld *loader) loadFromExportData(lpkg *loaderPackage) error {
+ if lpkg.PkgPath == "" {
+ log.Fatalf("internal error: Package %s has no PkgPath", lpkg)
+ }
+
+ // Because gcexportdata.Read has the potential to create or
+ // modify the types.Package for each node in the transitive
+ // closure of dependencies of lpkg, all exportdata operations
+ // must be sequential. (Finer-grained locking would require
+ // changes to the gcexportdata API.)
+ //
+ // The exportMu lock guards the lpkg.Types field and the
+ // types.Package it points to, for each loaderPackage in the graph.
+ //
+ // Not all accesses to Package.Pkg need to be protected by exportMu:
+ // graph ordering ensures that direct dependencies of source
+ // packages are fully loaded before the importer reads their Pkg field.
+ ld.exportMu.Lock()
+ defer ld.exportMu.Unlock()
+
+ if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() {
+ return nil // cache hit
+ }
+
+ lpkg.IllTyped = true // fail safe
+
+ if lpkg.ExportFile == "" {
+ // Errors while building export data will have been printed to stderr.
+ return fmt.Errorf("no export data file")
+ }
+ f, err := os.Open(lpkg.ExportFile)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ // Read gc export data.
+ //
+ // We don't currently support gccgo export data because all
+ // underlying workspaces use the gc toolchain. (Even build
+ // systems that support gccgo don't use it for workspace
+ // queries.)
+ r, err := gcexportdata.NewReader(f)
+ if err != nil {
+ return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
+ }
+
+ // Build the view.
+ //
+ // The gcexportdata machinery has no concept of package ID.
+ // It identifies packages by their PkgPath, which although not
+ // globally unique is unique within the scope of one invocation
+ // of the linker, type-checker, or gcexportdata.
+ //
+ // So, we must build a PkgPath-keyed view of the global
+ // (conceptually ID-keyed) cache of packages and pass it to
+ // gcexportdata. The view must contain every existing
+ // package that might possibly be mentioned by the
+ // current package---its transitive closure.
+ //
+ // In loadPackage, we unconditionally create a types.Package for
+ // each dependency so that export data loading does not
+ // create new ones.
+ //
+ // TODO(adonovan): it would be simpler and more efficient
+ // if the export data machinery invoked a callback to
+ // get-or-create a package instead of a map.
+ //
+ view := make(map[string]*types.Package) // view seen by gcexportdata
+ seen := make(map[*loaderPackage]bool) // all visited packages
+ var visit func(pkgs map[string]*Package)
+ visit = func(pkgs map[string]*Package) {
+ for _, p := range pkgs {
+ lpkg := ld.pkgs[p.ID]
+ if !seen[lpkg] {
+ seen[lpkg] = true
+ view[lpkg.PkgPath] = lpkg.Types
+ visit(lpkg.Imports)
+ }
+ }
+ }
+ visit(lpkg.Imports)
+
+ viewLen := len(view) + 1 // adding the self package
+ // Parse the export data.
+ // (May modify incomplete packages in view but not create new ones.)
+ tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath)
+ if err != nil {
+ return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
+ }
+ if _, ok := view["go.shape"]; ok {
+ // Account for the pseudopackage "go.shape" that gets
+ // created by generic code.
+ viewLen++
+ }
+ if viewLen != len(view) {
+ log.Panicf("golang.org/x/tools/go/packages: unexpected new packages during load of %s", lpkg.PkgPath)
+ }
+
+ lpkg.Types = tpkg
+ lpkg.IllTyped = false
+ return nil
+}
+
+// impliedLoadMode returns loadMode with its dependencies.
+func impliedLoadMode(loadMode LoadMode) LoadMode {
+ if loadMode&(NeedDeps|NeedTypes|NeedTypesInfo) != 0 {
+ // All these things require knowing the import graph.
+ loadMode |= NeedImports
+ }
+
+ return loadMode
+}
+
+func usesExportData(cfg *Config) bool {
+ return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0
+}
+
+var _ interface{} = io.Discard // assert build toolchain is go1.16 or later
diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go
new file mode 100644
index 00000000..a1dcc40b
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/visit.go
@@ -0,0 +1,59 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+import (
+ "fmt"
+ "os"
+ "sort"
+)
+
+// Visit visits all the packages in the import graph whose roots are
+// pkgs, calling the optional pre function the first time each package
+// is encountered (preorder), and the optional post function after a
+// package's dependencies have been visited (postorder).
+// The boolean result of pre(pkg) determines whether
+// the imports of package pkg are visited.
+func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
+ seen := make(map[*Package]bool)
+ var visit func(*Package)
+ visit = func(pkg *Package) {
+ if !seen[pkg] {
+ seen[pkg] = true
+
+ if pre == nil || pre(pkg) {
+ paths := make([]string, 0, len(pkg.Imports))
+ for path := range pkg.Imports {
+ paths = append(paths, path)
+ }
+ sort.Strings(paths) // Imports is a map, this makes visit stable
+ for _, path := range paths {
+ visit(pkg.Imports[path])
+ }
+ }
+
+ if post != nil {
+ post(pkg)
+ }
+ }
+ }
+ for _, pkg := range pkgs {
+ visit(pkg)
+ }
+}
+
+// PrintErrors prints to os.Stderr the accumulated errors of all
+// packages in the import graph rooted at pkgs, dependencies first.
+// PrintErrors returns the number of errors printed.
+func PrintErrors(pkgs []*Package) int {
+ var n int
+ Visit(pkgs, nil, func(pkg *Package) {
+ for _, err := range pkg.Errors {
+ fmt.Fprintln(os.Stderr, err)
+ n++
+ }
+ })
+ return n
+}
diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
new file mode 100644
index 00000000..d648c3d0
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
@@ -0,0 +1,772 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package objectpath defines a naming scheme for types.Objects
+// (that is, named entities in Go programs) relative to their enclosing
+// package.
+//
+// Type-checker objects are canonical, so they are usually identified by
+// their address in memory (a pointer), but a pointer has meaning only
+// within one address space. By contrast, objectpath names allow the
+// identity of an object to be sent from one program to another,
+// establishing a correspondence between types.Object variables that are
+// distinct but logically equivalent.
+//
+// A single object may have multiple paths. In this example,
+//
+// type A struct{ X int }
+// type B A
+//
+// the field X has two paths due to its membership of both A and B.
+// The For(obj) function always returns one of these paths, arbitrarily
+// but consistently.
+package objectpath
+
+import (
+ "fmt"
+ "go/types"
+ "strconv"
+ "strings"
+
+ "golang.org/x/tools/internal/aliases"
+ "golang.org/x/tools/internal/typesinternal"
+)
+
+// TODO(adonovan): think about generic aliases.
+
+// A Path is an opaque name that identifies a types.Object
+// relative to its package. Conceptually, the name consists of a
+// sequence of destructuring operations applied to the package scope
+// to obtain the original object.
+// The name does not include the package itself.
+type Path string
+
+// Encoding
+//
+// An object path is a textual and (with training) human-readable encoding
+// of a sequence of destructuring operators, starting from a types.Package.
+// The sequences represent a path through the package/object/type graph.
+// We classify these operators by their type:
+//
+// PO package->object Package.Scope.Lookup
+// OT object->type Object.Type
+// TT type->type Type.{Elem,Key,{,{,Recv}Type}Params,Results,Underlying} [EKPRUTrC]
+// TO type->object Type.{At,Field,Method,Obj} [AFMO]
+//
+// All valid paths start with a package and end at an object
+// and thus may be defined by the regular language:
+//
+// objectpath = PO (OT TT* TO)*
+//
+// The concrete encoding follows directly:
+// - The only PO operator is Package.Scope.Lookup, which requires an identifier.
+// - The only OT operator is Object.Type,
+// which we encode as '.' because dot cannot appear in an identifier.
+// - The TT operators are encoded as [EKPRUTrC];
+// two of these ({,Recv}TypeParams) require an integer operand,
+// which is encoded as a string of decimal digits.
+// - The TO operators are encoded as [AFMO];
+// three of these (At,Field,Method) require an integer operand,
+// which is encoded as a string of decimal digits.
+// These indices are stable across different representations
+// of the same package, even source and export data.
+// The indices used are implementation specific and may not correspond to
+// the argument to the go/types function.
+//
+// In the example below,
+//
+// package p
+//
+// type T interface {
+// f() (a string, b struct{ X int })
+// }
+//
+// field X has the path "T.UM0.RA1.F0",
+// representing the following sequence of operations:
+//
+// p.Lookup("T") T
+// .Type().Underlying().Method(0). f
+// .Type().Results().At(1) b
+// .Type().Field(0) X
+//
+// The encoding is not maximally compact---every R or P is
+// followed by an A, for example---but this simplifies the
+// encoder and decoder.
+const (
+ // object->type operators
+ opType = '.' // .Type() (Object)
+
+ // type->type operators
+ opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map)
+ opKey = 'K' // .Key() (Map)
+ opParams = 'P' // .Params() (Signature)
+ opResults = 'R' // .Results() (Signature)
+ opUnderlying = 'U' // .Underlying() (Named)
+ opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature)
+ opRecvTypeParam = 'r' // .RecvTypeParams.At(i) (Signature)
+ opConstraint = 'C' // .Constraint() (TypeParam)
+
+ // type->object operators
+ opAt = 'A' // .At(i) (Tuple)
+ opField = 'F' // .Field(i) (Struct)
+ opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored)
+ opObj = 'O' // .Obj() (Named, TypeParam)
+)
+
+// For is equivalent to new(Encoder).For(obj).
+//
+// It may be more efficient to reuse a single Encoder across several calls.
+func For(obj types.Object) (Path, error) {
+ return new(Encoder).For(obj)
+}
+
+// An Encoder amortizes the cost of encoding the paths of multiple objects.
+// The zero value of an Encoder is ready to use.
+type Encoder struct {
+ scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects
+}
+
+// For returns the path to an object relative to its package,
+// or an error if the object is not accessible from the package's Scope.
+//
+// The For function guarantees to return a path only for the following objects:
+// - package-level types
+// - exported package-level non-types
+// - methods
+// - parameter and result variables
+// - struct fields
+// These objects are sufficient to define the API of their package.
+// The objects described by a package's export data are drawn from this set.
+//
+// The set of objects accessible from a package's Scope depends on
+// whether the package was produced by type-checking syntax, or
+// reading export data; the latter may have a smaller Scope since
+// export data trims objects that are not reachable from an exported
+// declaration. For example, the For function will return a path for
+// an exported method of an unexported type that is not reachable
+// from any public declaration; this path will cause the Object
+// function to fail if called on a package loaded from export data.
+// TODO(adonovan): is this a bug or feature? Should this package
+// compute accessibility in the same way?
+//
+// For does not return a path for predeclared names, imported package
+// names, local names, and unexported package-level names (except
+// types).
+//
+// Example: given this definition,
+//
+// package p
+//
+// type T interface {
+// f() (a string, b struct{ X int })
+// }
+//
+// For(X) would return a path that denotes the following sequence of operations:
+//
+// p.Scope().Lookup("T") (TypeName T)
+// .Type().Underlying().Method(0). (method Func f)
+// .Type().Results().At(1) (field Var b)
+// .Type().Field(0) (field Var X)
+//
+// where p is the package (*types.Package) to which X belongs.
+func (enc *Encoder) For(obj types.Object) (Path, error) {
+ pkg := obj.Pkg()
+
+ // This table lists the cases of interest.
+ //
+ // Object Action
+ // ------ ------
+ // nil reject
+ // builtin reject
+ // pkgname reject
+ // label reject
+ // var
+ // package-level accept
+ // func param/result accept
+ // local reject
+ // struct field accept
+ // const
+ // package-level accept
+ // local reject
+ // func
+ // package-level accept
+ // init functions reject
+ // concrete method accept
+ // interface method accept
+ // type
+ // package-level accept
+ // local reject
+ //
+ // The only accessible package-level objects are members of pkg itself.
+ //
+ // The cases are handled in four steps:
+ //
+ // 1. reject nil and builtin
+ // 2. accept package-level objects
+ // 3. reject obviously invalid objects
+ // 4. search the API for the path to the param/result/field/method.
+
+ // 1. reference to nil or builtin?
+ if pkg == nil {
+ return "", fmt.Errorf("predeclared %s has no path", obj)
+ }
+ scope := pkg.Scope()
+
+ // 2. package-level object?
+ if scope.Lookup(obj.Name()) == obj {
+ // Only exported objects (and non-exported types) have a path.
+ // Non-exported types may be referenced by other objects.
+ if _, ok := obj.(*types.TypeName); !ok && !obj.Exported() {
+ return "", fmt.Errorf("no path for non-exported %v", obj)
+ }
+ return Path(obj.Name()), nil
+ }
+
+ // 3. Not a package-level object.
+ // Reject obviously non-viable cases.
+ switch obj := obj.(type) {
+ case *types.TypeName:
+ if _, ok := aliases.Unalias(obj.Type()).(*types.TypeParam); !ok {
+ // With the exception of type parameters, only package-level type names
+ // have a path.
+ return "", fmt.Errorf("no path for %v", obj)
+ }
+ case *types.Const, // Only package-level constants have a path.
+ *types.Label, // Labels are function-local.
+ *types.PkgName: // PkgNames are file-local.
+ return "", fmt.Errorf("no path for %v", obj)
+
+ case *types.Var:
+ // Could be:
+ // - a field (obj.IsField())
+ // - a func parameter or result
+ // - a local var.
+ // Sadly there is no way to distinguish
+ // a param/result from a local
+ // so we must proceed to the find.
+
+ case *types.Func:
+ // A func, if not package-level, must be a method.
+ if recv := obj.Type().(*types.Signature).Recv(); recv == nil {
+ return "", fmt.Errorf("func is not a method: %v", obj)
+ }
+
+ if path, ok := enc.concreteMethod(obj); ok {
+ // Fast path for concrete methods that avoids looping over scope.
+ return path, nil
+ }
+
+ default:
+ panic(obj)
+ }
+
+ // 4. Search the API for the path to the var (field/param/result) or method.
+
+ // First inspect package-level named types.
+ // In the presence of path aliases, these give
+ // the best paths because non-types may
+ // refer to types, but not the reverse.
+ empty := make([]byte, 0, 48) // initial space
+ objs := enc.scopeObjects(scope)
+ for _, o := range objs {
+ tname, ok := o.(*types.TypeName)
+ if !ok {
+ continue // handle non-types in second pass
+ }
+
+ path := append(empty, o.Name()...)
+ path = append(path, opType)
+
+ T := o.Type()
+
+ if tname.IsAlias() {
+ // type alias
+ if r := find(obj, T, path, nil); r != nil {
+ return Path(r), nil
+ }
+ } else {
+ if named, _ := T.(*types.Named); named != nil {
+ if r := findTypeParam(obj, named.TypeParams(), path, opTypeParam, nil); r != nil {
+ // generic named type
+ return Path(r), nil
+ }
+ }
+ // defined (named) type
+ if r := find(obj, T.Underlying(), append(path, opUnderlying), nil); r != nil {
+ return Path(r), nil
+ }
+ }
+ }
+
+ // Then inspect everything else:
+ // non-types, and declared methods of defined types.
+ for _, o := range objs {
+ path := append(empty, o.Name()...)
+ if _, ok := o.(*types.TypeName); !ok {
+ if o.Exported() {
+ // exported non-type (const, var, func)
+ if r := find(obj, o.Type(), append(path, opType), nil); r != nil {
+ return Path(r), nil
+ }
+ }
+ continue
+ }
+
+ // Inspect declared methods of defined types.
+ if T, ok := aliases.Unalias(o.Type()).(*types.Named); ok {
+ path = append(path, opType)
+ // The method index here is always with respect
+ // to the underlying go/types data structures,
+ // which ultimately derives from source order
+ // and must be preserved by export data.
+ for i := 0; i < T.NumMethods(); i++ {
+ m := T.Method(i)
+ path2 := appendOpArg(path, opMethod, i)
+ if m == obj {
+ return Path(path2), nil // found declared method
+ }
+ if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
+ return Path(r), nil
+ }
+ }
+ }
+ }
+
+ return "", fmt.Errorf("can't find path for %v in %s", obj, pkg.Path())
+}
+
+func appendOpArg(path []byte, op byte, arg int) []byte {
+ path = append(path, op)
+ path = strconv.AppendInt(path, int64(arg), 10)
+ return path
+}
+
+// concreteMethod returns the path for meth, which must have a non-nil receiver.
+// The second return value indicates success and may be false if the method is
+// an interface method or if it is an instantiated method.
+//
+// This function is just an optimization that avoids the general scope walking
+// approach. You are expected to fall back to the general approach if this
+// function fails.
+func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
+ // Concrete methods can only be declared on package-scoped named types. For
+ // that reason we can skip the expensive walk over the package scope: the
+ // path will always be package -> named type -> method. We can trivially get
+ // the type name from the receiver, and only have to look over the type's
+ // methods to find the method index.
+ //
+ // Methods on generic types require special consideration, however. Consider
+ // the following package:
+ //
+ // L1: type S[T any] struct{}
+ // L2: func (recv S[A]) Foo() { recv.Bar() }
+ // L3: func (recv S[B]) Bar() { }
+ // L4: type Alias = S[int]
+ // L5: func _[T any]() { var s S[int]; s.Foo() }
+ //
+ // The receivers of methods on generic types are instantiations. L2 and L3
+ // instantiate S with the type-parameters A and B, which are scoped to the
+ // respective methods. L4 and L5 each instantiate S with int. Each of these
+ // instantiations has its own method set, full of methods (and thus objects)
+ // with receivers whose types are the respective instantiations. In other
+ // words, we have
+ //
+ // S[A].Foo, S[A].Bar
+ // S[B].Foo, S[B].Bar
+ // S[int].Foo, S[int].Bar
+ //
+ // We may thus be trying to produce object paths for any of these objects.
+ //
+ // S[A].Foo and S[B].Bar are the origin methods, and their paths are S.Foo
+ // and S.Bar, which are the paths that this function naturally produces.
+ //
+ // S[A].Bar, S[B].Foo, and both methods on S[int] are instantiations that
+ // don't correspond to the origin methods. For S[int], this is significant.
+ // The most precise object path for S[int].Foo, for example, is Alias.Foo,
+ // not S.Foo. Our function, however, would produce S.Foo, which would
+ // resolve to a different object.
+ //
+ // For S[A].Bar and S[B].Foo it could be argued that S.Bar and S.Foo are
+ // still the correct paths, since only the origin methods have meaningful
+ // paths. But this is likely only true for trivial cases and has edge cases.
+ // Since this function is only an optimization, we err on the side of giving
+ // up, deferring to the slower but definitely correct algorithm. Most users
+ // of objectpath will only be giving us origin methods, anyway, as referring
+ // to instantiated methods is usually not useful.
+
+ if meth.Origin() != meth {
+ return "", false
+ }
+
+ _, named := typesinternal.ReceiverNamed(meth.Type().(*types.Signature).Recv())
+ if named == nil {
+ return "", false
+ }
+
+ if types.IsInterface(named) {
+ // Named interfaces don't have to be package-scoped
+ //
+ // TODO(dominikh): opt: if scope.Lookup(name) == named, then we can apply this optimization to interface
+ // methods, too, I think.
+ return "", false
+ }
+
+ // Preallocate space for the name, opType, opMethod, and some digits.
+ name := named.Obj().Name()
+ path := make([]byte, 0, len(name)+8)
+ path = append(path, name...)
+ path = append(path, opType)
+
+ // Method indices are w.r.t. the go/types data structures,
+ // ultimately deriving from source order,
+ // which is preserved by export data.
+ for i := 0; i < named.NumMethods(); i++ {
+ if named.Method(i) == meth {
+ path = appendOpArg(path, opMethod, i)
+ return Path(path), true
+ }
+ }
+
+ // Due to golang/go#59944, go/types fails to associate the receiver with
+ // certain methods on cgo types.
+ //
+ // TODO(rfindley): replace this panic once golang/go#59944 is fixed in all Go
+ // versions gopls supports.
+ return "", false
+ // panic(fmt.Sprintf("couldn't find method %s on type %s; methods: %#v", meth, named, enc.namedMethods(named)))
+}
+
+// find finds obj within type T, returning the path to it, or nil if not found.
+//
+// The seen map is used to short circuit cycles through type parameters. If
+// nil, it will be allocated as necessary.
+func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte {
+ switch T := T.(type) {
+ case *aliases.Alias:
+ return find(obj, aliases.Unalias(T), path, seen)
+ case *types.Basic, *types.Named:
+ // Named types belonging to pkg were handled already,
+ // so T must belong to another package. No path.
+ return nil
+ case *types.Pointer:
+ return find(obj, T.Elem(), append(path, opElem), seen)
+ case *types.Slice:
+ return find(obj, T.Elem(), append(path, opElem), seen)
+ case *types.Array:
+ return find(obj, T.Elem(), append(path, opElem), seen)
+ case *types.Chan:
+ return find(obj, T.Elem(), append(path, opElem), seen)
+ case *types.Map:
+ if r := find(obj, T.Key(), append(path, opKey), seen); r != nil {
+ return r
+ }
+ return find(obj, T.Elem(), append(path, opElem), seen)
+ case *types.Signature:
+ if r := findTypeParam(obj, T.RecvTypeParams(), path, opRecvTypeParam, nil); r != nil {
+ return r
+ }
+ if r := findTypeParam(obj, T.TypeParams(), path, opTypeParam, seen); r != nil {
+ return r
+ }
+ if r := find(obj, T.Params(), append(path, opParams), seen); r != nil {
+ return r
+ }
+ return find(obj, T.Results(), append(path, opResults), seen)
+ case *types.Struct:
+ for i := 0; i < T.NumFields(); i++ {
+ fld := T.Field(i)
+ path2 := appendOpArg(path, opField, i)
+ if fld == obj {
+ return path2 // found field var
+ }
+ if r := find(obj, fld.Type(), append(path2, opType), seen); r != nil {
+ return r
+ }
+ }
+ return nil
+ case *types.Tuple:
+ for i := 0; i < T.Len(); i++ {
+ v := T.At(i)
+ path2 := appendOpArg(path, opAt, i)
+ if v == obj {
+ return path2 // found param/result var
+ }
+ if r := find(obj, v.Type(), append(path2, opType), seen); r != nil {
+ return r
+ }
+ }
+ return nil
+ case *types.Interface:
+ for i := 0; i < T.NumMethods(); i++ {
+ m := T.Method(i)
+ path2 := appendOpArg(path, opMethod, i)
+ if m == obj {
+ return path2 // found interface method
+ }
+ if r := find(obj, m.Type(), append(path2, opType), seen); r != nil {
+ return r
+ }
+ }
+ return nil
+ case *types.TypeParam:
+ name := T.Obj()
+ if name == obj {
+ return append(path, opObj)
+ }
+ if seen[name] {
+ return nil
+ }
+ if seen == nil {
+ seen = make(map[*types.TypeName]bool)
+ }
+ seen[name] = true
+ if r := find(obj, T.Constraint(), append(path, opConstraint), seen); r != nil {
+ return r
+ }
+ return nil
+ }
+ panic(T)
+}
+
+func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, op byte, seen map[*types.TypeName]bool) []byte {
+ for i := 0; i < list.Len(); i++ {
+ tparam := list.At(i)
+ path2 := appendOpArg(path, op, i)
+ if r := find(obj, tparam, path2, seen); r != nil {
+ return r
+ }
+ }
+ return nil
+}
+
+// Object returns the object denoted by path p within the package pkg.
+func Object(pkg *types.Package, p Path) (types.Object, error) {
+ pathstr := string(p)
+ if pathstr == "" {
+ return nil, fmt.Errorf("empty path")
+ }
+
+ var pkgobj, suffix string
+ if dot := strings.IndexByte(pathstr, opType); dot < 0 {
+ pkgobj = pathstr
+ } else {
+ pkgobj = pathstr[:dot]
+ suffix = pathstr[dot:] // suffix starts with "."
+ }
+
+ obj := pkg.Scope().Lookup(pkgobj)
+ if obj == nil {
+ return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj)
+ }
+
+ // abstraction of *types.{Pointer,Slice,Array,Chan,Map}
+ type hasElem interface {
+ Elem() types.Type
+ }
+ // abstraction of *types.{Named,Signature}
+ type hasTypeParams interface {
+ TypeParams() *types.TypeParamList
+ }
+ // abstraction of *types.{Named,TypeParam}
+ type hasObj interface {
+ Obj() *types.TypeName
+ }
+
+ // The loop state is the pair (t, obj),
+ // exactly one of which is non-nil, initially obj.
+ // All suffixes start with '.' (the only object->type operation),
+ // followed by optional type->type operations,
+ // then a type->object operation.
+ // The cycle then repeats.
+ var t types.Type
+ for suffix != "" {
+ code := suffix[0]
+ suffix = suffix[1:]
+
+ // Codes [AFMTr] have an integer operand.
+ var index int
+ switch code {
+ case opAt, opField, opMethod, opTypeParam, opRecvTypeParam:
+ rest := strings.TrimLeft(suffix, "0123456789")
+ numerals := suffix[:len(suffix)-len(rest)]
+ suffix = rest
+ i, err := strconv.Atoi(numerals)
+ if err != nil {
+ return nil, fmt.Errorf("invalid path: bad numeric operand %q for code %q", numerals, code)
+ }
+ index = int(i)
+ case opObj:
+ // no operand
+ default:
+ // The suffix must end with a type->object operation.
+ if suffix == "" {
+ return nil, fmt.Errorf("invalid path: ends with %q, want [AFMO]", code)
+ }
+ }
+
+ if code == opType {
+ if t != nil {
+ return nil, fmt.Errorf("invalid path: unexpected %q in type context", opType)
+ }
+ t = obj.Type()
+ obj = nil
+ continue
+ }
+
+ if t == nil {
+ return nil, fmt.Errorf("invalid path: code %q in object context", code)
+ }
+
+ // Inv: t != nil, obj == nil
+
+ t = aliases.Unalias(t)
+ switch code {
+ case opElem:
+ hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want pointer, slice, array, chan or map)", code, t, t)
+ }
+ t = hasElem.Elem()
+
+ case opKey:
+ mapType, ok := t.(*types.Map)
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want map)", code, t, t)
+ }
+ t = mapType.Key()
+
+ case opParams:
+ sig, ok := t.(*types.Signature)
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t)
+ }
+ t = sig.Params()
+
+ case opResults:
+ sig, ok := t.(*types.Signature)
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t)
+ }
+ t = sig.Results()
+
+ case opUnderlying:
+ named, ok := t.(*types.Named)
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named)", code, t, t)
+ }
+ t = named.Underlying()
+
+ case opTypeParam:
+ hasTypeParams, ok := t.(hasTypeParams) // Named, Signature
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or signature)", code, t, t)
+ }
+ tparams := hasTypeParams.TypeParams()
+ if n := tparams.Len(); index >= n {
+ return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n)
+ }
+ t = tparams.At(index)
+
+ case opRecvTypeParam:
+ sig, ok := t.(*types.Signature) // Signature
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t)
+ }
+ rtparams := sig.RecvTypeParams()
+ if n := rtparams.Len(); index >= n {
+ return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n)
+ }
+ t = rtparams.At(index)
+
+ case opConstraint:
+ tparam, ok := t.(*types.TypeParam)
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t)
+ }
+ t = tparam.Constraint()
+
+ case opAt:
+ tuple, ok := t.(*types.Tuple)
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want tuple)", code, t, t)
+ }
+ if n := tuple.Len(); index >= n {
+ return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n)
+ }
+ obj = tuple.At(index)
+ t = nil
+
+ case opField:
+ structType, ok := t.(*types.Struct)
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want struct)", code, t, t)
+ }
+ if n := structType.NumFields(); index >= n {
+ return nil, fmt.Errorf("field index %d out of range [0-%d)", index, n)
+ }
+ obj = structType.Field(index)
+ t = nil
+
+ case opMethod:
+ switch t := t.(type) {
+ case *types.Interface:
+ if index >= t.NumMethods() {
+ return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods())
+ }
+ obj = t.Method(index) // Id-ordered
+
+ case *types.Named:
+ if index >= t.NumMethods() {
+ return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods())
+ }
+ obj = t.Method(index)
+
+ default:
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t)
+ }
+ t = nil
+
+ case opObj:
+ hasObj, ok := t.(hasObj)
+ if !ok {
+ return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or type param)", code, t, t)
+ }
+ obj = hasObj.Obj()
+ t = nil
+
+ default:
+ return nil, fmt.Errorf("invalid path: unknown code %q", code)
+ }
+ }
+
+ if obj == nil {
+ panic(p) // path does not end in an object-valued operator
+ }
+
+ if obj.Pkg() != pkg {
+ return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj)
+ }
+
+ return obj, nil // success
+}
+
+// scopeObjects is a memoization of scope objects.
+// Callers must not modify the result.
+func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object {
+ m := enc.scopeMemo
+ if m == nil {
+ m = make(map[*types.Scope][]types.Object)
+ enc.scopeMemo = m
+ }
+ objs, ok := m[scope]
+ if !ok {
+ names := scope.Names() // allocates and sorts
+ objs = make([]types.Object, len(names))
+ for i, name := range names {
+ objs[i] = scope.Lookup(name)
+ }
+ m[scope] = objs
+ }
+ return objs
+}
diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases.go b/vendor/golang.org/x/tools/internal/aliases/aliases.go
new file mode 100644
index 00000000..c24c2eee
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/aliases/aliases.go
@@ -0,0 +1,32 @@
+// 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 aliases
+
+import (
+ "go/token"
+ "go/types"
+)
+
+// Package aliases defines backward compatible shims
+// for the types.Alias type representation added in 1.22.
+// This defines placeholders for x/tools until 1.26.
+
+// NewAlias creates a new TypeName in Package pkg that
+// is an alias for the type rhs.
+//
+// The enabled parameter determines whether the resulting [TypeName]'s
+// type is an [types.Alias]. Its value must be the result of a call to
+// [Enabled], which computes the effective value of
+// GODEBUG=gotypesalias=... by invoking the type checker. The Enabled
+// function is expensive and should be called once per task (e.g.
+// package import), not once per call to NewAlias.
+func NewAlias(enabled bool, pos token.Pos, pkg *types.Package, name string, rhs types.Type) *types.TypeName {
+ if enabled {
+ tname := types.NewTypeName(pos, pkg, name, nil)
+ newAlias(tname, rhs)
+ return tname
+ }
+ return types.NewTypeName(pos, pkg, name, rhs)
+}
diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go b/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go
new file mode 100644
index 00000000..c027b9f3
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go
@@ -0,0 +1,31 @@
+// 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 !go1.22
+// +build !go1.22
+
+package aliases
+
+import (
+ "go/types"
+)
+
+// Alias is a placeholder for a go/types.Alias for <=1.21.
+// It will never be created by go/types.
+type Alias struct{}
+
+func (*Alias) String() string { panic("unreachable") }
+func (*Alias) Underlying() types.Type { panic("unreachable") }
+func (*Alias) Obj() *types.TypeName { panic("unreachable") }
+func Rhs(alias *Alias) types.Type { panic("unreachable") }
+
+// Unalias returns the type t for go <=1.21.
+func Unalias(t types.Type) types.Type { return t }
+
+func newAlias(name *types.TypeName, rhs types.Type) *Alias { panic("unreachable") }
+
+// Enabled reports whether [NewAlias] should create [types.Alias] types.
+//
+// Before go1.22, this function always returns false.
+func Enabled() bool { return false }
diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go b/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go
new file mode 100644
index 00000000..b3299548
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go
@@ -0,0 +1,63 @@
+// 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 go1.22
+// +build go1.22
+
+package aliases
+
+import (
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "go/types"
+)
+
+// Alias is an alias of types.Alias.
+type Alias = types.Alias
+
+// Rhs returns the type on the right-hand side of the alias declaration.
+func Rhs(alias *Alias) types.Type {
+ if alias, ok := any(alias).(interface{ Rhs() types.Type }); ok {
+ return alias.Rhs() // go1.23+
+ }
+
+ // go1.22's Alias didn't have the Rhs method,
+ // so Unalias is the best we can do.
+ return Unalias(alias)
+}
+
+// Unalias is a wrapper of types.Unalias.
+func Unalias(t types.Type) types.Type { return types.Unalias(t) }
+
+// newAlias is an internal alias around types.NewAlias.
+// Direct usage is discouraged as the moment.
+// Try to use NewAlias instead.
+func newAlias(tname *types.TypeName, rhs types.Type) *Alias {
+ a := types.NewAlias(tname, rhs)
+ // TODO(go.dev/issue/65455): Remove kludgy workaround to set a.actual as a side-effect.
+ Unalias(a)
+ return a
+}
+
+// Enabled reports whether [NewAlias] should create [types.Alias] types.
+//
+// This function is expensive! Call it sparingly.
+func Enabled() bool {
+ // The only reliable way to compute the answer is to invoke go/types.
+ // We don't parse the GODEBUG environment variable, because
+ // (a) it's tricky to do so in a manner that is consistent
+ // with the godebug package; in particular, a simple
+ // substring check is not good enough. The value is a
+ // rightmost-wins list of options. But more importantly:
+ // (b) it is impossible to detect changes to the effective
+ // setting caused by os.Setenv("GODEBUG"), as happens in
+ // many tests. Therefore any attempt to cache the result
+ // is just incorrect.
+ fset := token.NewFileSet()
+ f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", 0)
+ pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil)
+ _, enabled := pkg.Scope().Lookup("A").Type().(*types.Alias)
+ return enabled
+}
diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go
new file mode 100644
index 00000000..a6cf0e64
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/core/event.go
@@ -0,0 +1,85 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package core provides support for event based telemetry.
+package core
+
+import (
+ "fmt"
+ "time"
+
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Event holds the information about an event of note that occurred.
+type Event struct {
+ at time.Time
+
+ // As events are often on the stack, storing the first few labels directly
+ // in the event can avoid an allocation at all for the very common cases of
+ // simple events.
+ // The length needs to be large enough to cope with the majority of events
+ // but no so large as to cause undue stack pressure.
+ // A log message with two values will use 3 labels (one for each value and
+ // one for the message itself).
+
+ static [3]label.Label // inline storage for the first few labels
+ dynamic []label.Label // dynamically sized storage for remaining labels
+}
+
+// eventLabelMap implements label.Map for a the labels of an Event.
+type eventLabelMap struct {
+ event Event
+}
+
+func (ev Event) At() time.Time { return ev.at }
+
+func (ev Event) Format(f fmt.State, r rune) {
+ if !ev.at.IsZero() {
+ fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 "))
+ }
+ for index := 0; ev.Valid(index); index++ {
+ if l := ev.Label(index); l.Valid() {
+ fmt.Fprintf(f, "\n\t%v", l)
+ }
+ }
+}
+
+func (ev Event) Valid(index int) bool {
+ return index >= 0 && index < len(ev.static)+len(ev.dynamic)
+}
+
+func (ev Event) Label(index int) label.Label {
+ if index < len(ev.static) {
+ return ev.static[index]
+ }
+ return ev.dynamic[index-len(ev.static)]
+}
+
+func (ev Event) Find(key label.Key) label.Label {
+ for _, l := range ev.static {
+ if l.Key() == key {
+ return l
+ }
+ }
+ for _, l := range ev.dynamic {
+ if l.Key() == key {
+ return l
+ }
+ }
+ return label.Label{}
+}
+
+func MakeEvent(static [3]label.Label, labels []label.Label) Event {
+ return Event{
+ static: static,
+ dynamic: labels,
+ }
+}
+
+// CloneEvent event returns a copy of the event with the time adjusted to at.
+func CloneEvent(ev Event, at time.Time) Event {
+ ev.at = at
+ return ev
+}
diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go
new file mode 100644
index 00000000..05f3a9a5
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/core/export.go
@@ -0,0 +1,70 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package core
+
+import (
+ "context"
+ "sync/atomic"
+ "time"
+ "unsafe"
+
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Exporter is a function that handles events.
+// It may return a modified context and event.
+type Exporter func(context.Context, Event, label.Map) context.Context
+
+var (
+ exporter unsafe.Pointer
+)
+
+// SetExporter sets the global exporter function that handles all events.
+// The exporter is called synchronously from the event call site, so it should
+// return quickly so as not to hold up user code.
+func SetExporter(e Exporter) {
+ p := unsafe.Pointer(&e)
+ if e == nil {
+ // &e is always valid, and so p is always valid, but for the early abort
+ // of ProcessEvent to be efficient it needs to make the nil check on the
+ // pointer without having to dereference it, so we make the nil function
+ // also a nil pointer
+ p = nil
+ }
+ atomic.StorePointer(&exporter, p)
+}
+
+// deliver is called to deliver an event to the supplied exporter.
+// it will fill in the time.
+func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context {
+ // add the current time to the event
+ ev.at = time.Now()
+ // hand the event off to the current exporter
+ return exporter(ctx, ev, ev)
+}
+
+// Export is called to deliver an event to the global exporter if set.
+func Export(ctx context.Context, ev Event) context.Context {
+ // get the global exporter and abort early if there is not one
+ exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
+ if exporterPtr == nil {
+ return ctx
+ }
+ return deliver(ctx, *exporterPtr, ev)
+}
+
+// ExportPair is called to deliver a start event to the supplied exporter.
+// It also returns a function that will deliver the end event to the same
+// exporter.
+// It will fill in the time.
+func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) {
+ // get the global exporter and abort early if there is not one
+ exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
+ if exporterPtr == nil {
+ return ctx, func() {}
+ }
+ ctx = deliver(ctx, *exporterPtr, begin)
+ return ctx, func() { deliver(ctx, *exporterPtr, end) }
+}
diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go
new file mode 100644
index 00000000..06c1d461
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/core/fast.go
@@ -0,0 +1,77 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package core
+
+import (
+ "context"
+
+ "golang.org/x/tools/internal/event/keys"
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Log1 takes a message and one label delivers a log event to the exporter.
+// It is a customized version of Print that is faster and does no allocation.
+func Log1(ctx context.Context, message string, t1 label.Label) {
+ Export(ctx, MakeEvent([3]label.Label{
+ keys.Msg.Of(message),
+ t1,
+ }, nil))
+}
+
+// Log2 takes a message and two labels and delivers a log event to the exporter.
+// It is a customized version of Print that is faster and does no allocation.
+func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) {
+ Export(ctx, MakeEvent([3]label.Label{
+ keys.Msg.Of(message),
+ t1,
+ t2,
+ }, nil))
+}
+
+// Metric1 sends a label event to the exporter with the supplied labels.
+func Metric1(ctx context.Context, t1 label.Label) context.Context {
+ return Export(ctx, MakeEvent([3]label.Label{
+ keys.Metric.New(),
+ t1,
+ }, nil))
+}
+
+// Metric2 sends a label event to the exporter with the supplied labels.
+func Metric2(ctx context.Context, t1, t2 label.Label) context.Context {
+ return Export(ctx, MakeEvent([3]label.Label{
+ keys.Metric.New(),
+ t1,
+ t2,
+ }, nil))
+}
+
+// Start1 sends a span start event with the supplied label list to the exporter.
+// It also returns a function that will end the span, which should normally be
+// deferred.
+func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) {
+ return ExportPair(ctx,
+ MakeEvent([3]label.Label{
+ keys.Start.Of(name),
+ t1,
+ }, nil),
+ MakeEvent([3]label.Label{
+ keys.End.New(),
+ }, nil))
+}
+
+// Start2 sends a span start event with the supplied label list to the exporter.
+// It also returns a function that will end the span, which should normally be
+// deferred.
+func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) {
+ return ExportPair(ctx,
+ MakeEvent([3]label.Label{
+ keys.Start.Of(name),
+ t1,
+ t2,
+ }, nil),
+ MakeEvent([3]label.Label{
+ keys.End.New(),
+ }, nil))
+}
diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go
new file mode 100644
index 00000000..5dc6e6ba
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/doc.go
@@ -0,0 +1,7 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package event provides a set of packages that cover the main
+// concepts of telemetry in an implementation agnostic way.
+package event
diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go
new file mode 100644
index 00000000..4d55e577
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/event.go
@@ -0,0 +1,127 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package event
+
+import (
+ "context"
+
+ "golang.org/x/tools/internal/event/core"
+ "golang.org/x/tools/internal/event/keys"
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Exporter is a function that handles events.
+// It may return a modified context and event.
+type Exporter func(context.Context, core.Event, label.Map) context.Context
+
+// SetExporter sets the global exporter function that handles all events.
+// The exporter is called synchronously from the event call site, so it should
+// return quickly so as not to hold up user code.
+func SetExporter(e Exporter) {
+ core.SetExporter(core.Exporter(e))
+}
+
+// Log takes a message and a label list and combines them into a single event
+// before delivering them to the exporter.
+func Log(ctx context.Context, message string, labels ...label.Label) {
+ core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Msg.Of(message),
+ }, labels))
+}
+
+// IsLog returns true if the event was built by the Log function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsLog(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Msg
+}
+
+// Error takes a message and a label list and combines them into a single event
+// before delivering them to the exporter. It captures the error in the
+// delivered event.
+func Error(ctx context.Context, message string, err error, labels ...label.Label) {
+ core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Msg.Of(message),
+ keys.Err.Of(err),
+ }, labels))
+}
+
+// IsError returns true if the event was built by the Error function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsError(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Msg &&
+ ev.Label(1).Key() == keys.Err
+}
+
+// Metric sends a label event to the exporter with the supplied labels.
+func Metric(ctx context.Context, labels ...label.Label) {
+ core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Metric.New(),
+ }, labels))
+}
+
+// IsMetric returns true if the event was built by the Metric function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsMetric(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Metric
+}
+
+// Label sends a label event to the exporter with the supplied labels.
+func Label(ctx context.Context, labels ...label.Label) context.Context {
+ return core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Label.New(),
+ }, labels))
+}
+
+// IsLabel returns true if the event was built by the Label function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsLabel(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Label
+}
+
+// Start sends a span start event with the supplied label list to the exporter.
+// It also returns a function that will end the span, which should normally be
+// deferred.
+func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) {
+ return core.ExportPair(ctx,
+ core.MakeEvent([3]label.Label{
+ keys.Start.Of(name),
+ }, labels),
+ core.MakeEvent([3]label.Label{
+ keys.End.New(),
+ }, nil))
+}
+
+// IsStart returns true if the event was built by the Start function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsStart(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Start
+}
+
+// IsEnd returns true if the event was built by the End function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsEnd(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.End
+}
+
+// Detach returns a context without an associated span.
+// This allows the creation of spans that are not children of the current span.
+func Detach(ctx context.Context) context.Context {
+ return core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Detach.New(),
+ }, nil))
+}
+
+// IsDetach returns true if the event was built by the Detach function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsDetach(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Detach
+}
diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go
new file mode 100644
index 00000000..a02206e3
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/keys/keys.go
@@ -0,0 +1,564 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package keys
+
+import (
+ "fmt"
+ "io"
+ "math"
+ "strconv"
+
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Value represents a key for untyped values.
+type Value struct {
+ name string
+ description string
+}
+
+// New creates a new Key for untyped values.
+func New(name, description string) *Value {
+ return &Value{name: name, description: description}
+}
+
+func (k *Value) Name() string { return k.name }
+func (k *Value) Description() string { return k.description }
+
+func (k *Value) Format(w io.Writer, buf []byte, l label.Label) {
+ fmt.Fprint(w, k.From(l))
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Value) Get(lm label.Map) interface{} {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return nil
+}
+
+// From can be used to get a value from a Label.
+func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() }
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) }
+
+// Tag represents a key for tagging labels that have no value.
+// These are used when the existence of the label is the entire information it
+// carries, such as marking events to be of a specific kind, or from a specific
+// package.
+type Tag struct {
+ name string
+ description string
+}
+
+// NewTag creates a new Key for tagging labels.
+func NewTag(name, description string) *Tag {
+ return &Tag{name: name, description: description}
+}
+
+func (k *Tag) Name() string { return k.name }
+func (k *Tag) Description() string { return k.description }
+
+func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {}
+
+// New creates a new Label with this key.
+func (k *Tag) New() label.Label { return label.OfValue(k, nil) }
+
+// Int represents a key
+type Int struct {
+ name string
+ description string
+}
+
+// NewInt creates a new Key for int values.
+func NewInt(name, description string) *Int {
+ return &Int{name: name, description: description}
+}
+
+func (k *Int) Name() string { return k.name }
+func (k *Int) Description() string { return k.description }
+
+func (k *Int) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int) Get(lm label.Map) int {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int) From(t label.Label) int { return int(t.Unpack64()) }
+
+// Int8 represents a key
+type Int8 struct {
+ name string
+ description string
+}
+
+// NewInt8 creates a new Key for int8 values.
+func NewInt8(name, description string) *Int8 {
+ return &Int8{name: name, description: description}
+}
+
+func (k *Int8) Name() string { return k.name }
+func (k *Int8) Description() string { return k.description }
+
+func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int8) Get(lm label.Map) int8 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) }
+
+// Int16 represents a key
+type Int16 struct {
+ name string
+ description string
+}
+
+// NewInt16 creates a new Key for int16 values.
+func NewInt16(name, description string) *Int16 {
+ return &Int16{name: name, description: description}
+}
+
+func (k *Int16) Name() string { return k.name }
+func (k *Int16) Description() string { return k.description }
+
+func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int16) Get(lm label.Map) int16 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) }
+
+// Int32 represents a key
+type Int32 struct {
+ name string
+ description string
+}
+
+// NewInt32 creates a new Key for int32 values.
+func NewInt32(name, description string) *Int32 {
+ return &Int32{name: name, description: description}
+}
+
+func (k *Int32) Name() string { return k.name }
+func (k *Int32) Description() string { return k.description }
+
+func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int32) Get(lm label.Map) int32 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) }
+
+// Int64 represents a key
+type Int64 struct {
+ name string
+ description string
+}
+
+// NewInt64 creates a new Key for int64 values.
+func NewInt64(name, description string) *Int64 {
+ return &Int64{name: name, description: description}
+}
+
+func (k *Int64) Name() string { return k.name }
+func (k *Int64) Description() string { return k.description }
+
+func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, k.From(l), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int64) Get(lm label.Map) int64 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) }
+
+// UInt represents a key
+type UInt struct {
+ name string
+ description string
+}
+
+// NewUInt creates a new Key for uint values.
+func NewUInt(name, description string) *UInt {
+ return &UInt{name: name, description: description}
+}
+
+func (k *UInt) Name() string { return k.name }
+func (k *UInt) Description() string { return k.description }
+
+func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt) Get(lm label.Map) uint {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) }
+
+// UInt8 represents a key
+type UInt8 struct {
+ name string
+ description string
+}
+
+// NewUInt8 creates a new Key for uint8 values.
+func NewUInt8(name, description string) *UInt8 {
+ return &UInt8{name: name, description: description}
+}
+
+func (k *UInt8) Name() string { return k.name }
+func (k *UInt8) Description() string { return k.description }
+
+func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt8) Get(lm label.Map) uint8 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) }
+
+// UInt16 represents a key
+type UInt16 struct {
+ name string
+ description string
+}
+
+// NewUInt16 creates a new Key for uint16 values.
+func NewUInt16(name, description string) *UInt16 {
+ return &UInt16{name: name, description: description}
+}
+
+func (k *UInt16) Name() string { return k.name }
+func (k *UInt16) Description() string { return k.description }
+
+func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt16) Get(lm label.Map) uint16 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) }
+
+// UInt32 represents a key
+type UInt32 struct {
+ name string
+ description string
+}
+
+// NewUInt32 creates a new Key for uint32 values.
+func NewUInt32(name, description string) *UInt32 {
+ return &UInt32{name: name, description: description}
+}
+
+func (k *UInt32) Name() string { return k.name }
+func (k *UInt32) Description() string { return k.description }
+
+func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt32) Get(lm label.Map) uint32 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) }
+
+// UInt64 represents a key
+type UInt64 struct {
+ name string
+ description string
+}
+
+// NewUInt64 creates a new Key for uint64 values.
+func NewUInt64(name, description string) *UInt64 {
+ return &UInt64{name: name, description: description}
+}
+
+func (k *UInt64) Name() string { return k.name }
+func (k *UInt64) Description() string { return k.description }
+
+func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, k.From(l), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt64) Get(lm label.Map) uint64 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() }
+
+// Float32 represents a key
+type Float32 struct {
+ name string
+ description string
+}
+
+// NewFloat32 creates a new Key for float32 values.
+func NewFloat32(name, description string) *Float32 {
+ return &Float32{name: name, description: description}
+}
+
+func (k *Float32) Name() string { return k.name }
+func (k *Float32) Description() string { return k.description }
+
+func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Float32) Of(v float32) label.Label {
+ return label.Of64(k, uint64(math.Float32bits(v)))
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Float32) Get(lm label.Map) float32 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Float32) From(t label.Label) float32 {
+ return math.Float32frombits(uint32(t.Unpack64()))
+}
+
+// Float64 represents a key
+type Float64 struct {
+ name string
+ description string
+}
+
+// NewFloat64 creates a new Key for int64 values.
+func NewFloat64(name, description string) *Float64 {
+ return &Float64{name: name, description: description}
+}
+
+func (k *Float64) Name() string { return k.name }
+func (k *Float64) Description() string { return k.description }
+
+func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Float64) Of(v float64) label.Label {
+ return label.Of64(k, math.Float64bits(v))
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Float64) Get(lm label.Map) float64 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Float64) From(t label.Label) float64 {
+ return math.Float64frombits(t.Unpack64())
+}
+
+// String represents a key
+type String struct {
+ name string
+ description string
+}
+
+// NewString creates a new Key for int64 values.
+func NewString(name, description string) *String {
+ return &String{name: name, description: description}
+}
+
+func (k *String) Name() string { return k.name }
+func (k *String) Description() string { return k.description }
+
+func (k *String) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendQuote(buf, k.From(l)))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *String) Of(v string) label.Label { return label.OfString(k, v) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *String) Get(lm label.Map) string {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return ""
+}
+
+// From can be used to get a value from a Label.
+func (k *String) From(t label.Label) string { return t.UnpackString() }
+
+// Boolean represents a key
+type Boolean struct {
+ name string
+ description string
+}
+
+// NewBoolean creates a new Key for bool values.
+func NewBoolean(name, description string) *Boolean {
+ return &Boolean{name: name, description: description}
+}
+
+func (k *Boolean) Name() string { return k.name }
+func (k *Boolean) Description() string { return k.description }
+
+func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendBool(buf, k.From(l)))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Boolean) Of(v bool) label.Label {
+ if v {
+ return label.Of64(k, 1)
+ }
+ return label.Of64(k, 0)
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Boolean) Get(lm label.Map) bool {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return false
+}
+
+// From can be used to get a value from a Label.
+func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 }
+
+// Error represents a key
+type Error struct {
+ name string
+ description string
+}
+
+// NewError creates a new Key for int64 values.
+func NewError(name, description string) *Error {
+ return &Error{name: name, description: description}
+}
+
+func (k *Error) Name() string { return k.name }
+func (k *Error) Description() string { return k.description }
+
+func (k *Error) Format(w io.Writer, buf []byte, l label.Label) {
+ io.WriteString(w, k.From(l).Error())
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Error) Get(lm label.Map) error {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return nil
+}
+
+// From can be used to get a value from a Label.
+func (k *Error) From(t label.Label) error {
+ err, _ := t.UnpackValue().(error)
+ return err
+}
diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go
new file mode 100644
index 00000000..7e958665
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/keys/standard.go
@@ -0,0 +1,22 @@
+// 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.
+
+package keys
+
+var (
+ // Msg is a key used to add message strings to label lists.
+ Msg = NewString("message", "a readable message")
+ // Label is a key used to indicate an event adds labels to the context.
+ Label = NewTag("label", "a label context marker")
+ // Start is used for things like traces that have a name.
+ Start = NewString("start", "span start")
+ // Metric is a key used to indicate an event records metrics.
+ End = NewTag("end", "a span end marker")
+ // Metric is a key used to indicate an event records metrics.
+ Detach = NewTag("detach", "a span detach marker")
+ // Err is a key used to add error values to label lists.
+ Err = NewError("error", "an error that occurred")
+ // Metric is a key used to indicate an event records metrics.
+ Metric = NewTag("metric", "a metric event marker")
+)
diff --git a/vendor/golang.org/x/tools/internal/event/keys/util.go b/vendor/golang.org/x/tools/internal/event/keys/util.go
new file mode 100644
index 00000000..c0e8e731
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/keys/util.go
@@ -0,0 +1,21 @@
+// 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 keys
+
+import (
+ "sort"
+ "strings"
+)
+
+// Join returns a canonical join of the keys in S:
+// a sorted comma-separated string list.
+func Join[S ~[]T, T ~string](s S) string {
+ strs := make([]string, 0, len(s))
+ for _, v := range s {
+ strs = append(strs, string(v))
+ }
+ sort.Strings(strs)
+ return strings.Join(strs, ",")
+}
diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go
new file mode 100644
index 00000000..0f526e1f
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/label/label.go
@@ -0,0 +1,215 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package label
+
+import (
+ "fmt"
+ "io"
+ "reflect"
+ "unsafe"
+)
+
+// Key is used as the identity of a Label.
+// Keys are intended to be compared by pointer only, the name should be unique
+// for communicating with external systems, but it is not required or enforced.
+type Key interface {
+ // Name returns the key name.
+ Name() string
+ // Description returns a string that can be used to describe the value.
+ Description() string
+
+ // Format is used in formatting to append the value of the label to the
+ // supplied buffer.
+ // The formatter may use the supplied buf as a scratch area to avoid
+ // allocations.
+ Format(w io.Writer, buf []byte, l Label)
+}
+
+// Label holds a key and value pair.
+// It is normally used when passing around lists of labels.
+type Label struct {
+ key Key
+ packed uint64
+ untyped interface{}
+}
+
+// Map is the interface to a collection of Labels indexed by key.
+type Map interface {
+ // Find returns the label that matches the supplied key.
+ Find(key Key) Label
+}
+
+// List is the interface to something that provides an iterable
+// list of labels.
+// Iteration should start from 0 and continue until Valid returns false.
+type List interface {
+ // Valid returns true if the index is within range for the list.
+ // It does not imply the label at that index will itself be valid.
+ Valid(index int) bool
+ // Label returns the label at the given index.
+ Label(index int) Label
+}
+
+// list implements LabelList for a list of Labels.
+type list struct {
+ labels []Label
+}
+
+// filter wraps a LabelList filtering out specific labels.
+type filter struct {
+ keys []Key
+ underlying List
+}
+
+// listMap implements LabelMap for a simple list of labels.
+type listMap struct {
+ labels []Label
+}
+
+// mapChain implements LabelMap for a list of underlying LabelMap.
+type mapChain struct {
+ maps []Map
+}
+
+// OfValue creates a new label from the key and value.
+// This method is for implementing new key types, label creation should
+// normally be done with the Of method of the key.
+func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} }
+
+// UnpackValue assumes the label was built using LabelOfValue and returns the value
+// that was passed to that constructor.
+// This method is for implementing new key types, for type safety normal
+// access should be done with the From method of the key.
+func (t Label) UnpackValue() interface{} { return t.untyped }
+
+// Of64 creates a new label from a key and a uint64. This is often
+// used for non uint64 values that can be packed into a uint64.
+// This method is for implementing new key types, label creation should
+// normally be done with the Of method of the key.
+func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} }
+
+// Unpack64 assumes the label was built using LabelOf64 and returns the value that
+// was passed to that constructor.
+// This method is for implementing new key types, for type safety normal
+// access should be done with the From method of the key.
+func (t Label) Unpack64() uint64 { return t.packed }
+
+type stringptr unsafe.Pointer
+
+// OfString creates a new label from a key and a string.
+// This method is for implementing new key types, label creation should
+// normally be done with the Of method of the key.
+func OfString(k Key, v string) Label {
+ hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
+ return Label{
+ key: k,
+ packed: uint64(hdr.Len),
+ untyped: stringptr(hdr.Data),
+ }
+}
+
+// UnpackString assumes the label was built using LabelOfString and returns the
+// value that was passed to that constructor.
+// This method is for implementing new key types, for type safety normal
+// access should be done with the From method of the key.
+func (t Label) UnpackString() string {
+ var v string
+ hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
+ hdr.Data = uintptr(t.untyped.(stringptr))
+ hdr.Len = int(t.packed)
+ return v
+}
+
+// Valid returns true if the Label is a valid one (it has a key).
+func (t Label) Valid() bool { return t.key != nil }
+
+// Key returns the key of this Label.
+func (t Label) Key() Key { return t.key }
+
+// Format is used for debug printing of labels.
+func (t Label) Format(f fmt.State, r rune) {
+ if !t.Valid() {
+ io.WriteString(f, `nil`)
+ return
+ }
+ io.WriteString(f, t.Key().Name())
+ io.WriteString(f, "=")
+ var buf [128]byte
+ t.Key().Format(f, buf[:0], t)
+}
+
+func (l *list) Valid(index int) bool {
+ return index >= 0 && index < len(l.labels)
+}
+
+func (l *list) Label(index int) Label {
+ return l.labels[index]
+}
+
+func (f *filter) Valid(index int) bool {
+ return f.underlying.Valid(index)
+}
+
+func (f *filter) Label(index int) Label {
+ l := f.underlying.Label(index)
+ for _, f := range f.keys {
+ if l.Key() == f {
+ return Label{}
+ }
+ }
+ return l
+}
+
+func (lm listMap) Find(key Key) Label {
+ for _, l := range lm.labels {
+ if l.Key() == key {
+ return l
+ }
+ }
+ return Label{}
+}
+
+func (c mapChain) Find(key Key) Label {
+ for _, src := range c.maps {
+ l := src.Find(key)
+ if l.Valid() {
+ return l
+ }
+ }
+ return Label{}
+}
+
+var emptyList = &list{}
+
+func NewList(labels ...Label) List {
+ if len(labels) == 0 {
+ return emptyList
+ }
+ return &list{labels: labels}
+}
+
+func Filter(l List, keys ...Key) List {
+ if len(keys) == 0 {
+ return l
+ }
+ return &filter{keys: keys, underlying: l}
+}
+
+func NewMap(labels ...Label) Map {
+ return listMap{labels: labels}
+}
+
+func MergeMaps(srcs ...Map) Map {
+ var nonNil []Map
+ for _, src := range srcs {
+ if src != nil {
+ nonNil = append(nonNil, src)
+ }
+ }
+ if len(nonNil) == 1 {
+ return nonNil[0]
+ }
+ return mapChain{maps: nonNil}
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go
new file mode 100644
index 00000000..d98b0db2
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go
@@ -0,0 +1,150 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the remaining vestiges of
+// $GOROOT/src/go/internal/gcimporter/bimport.go.
+
+package gcimporter
+
+import (
+ "fmt"
+ "go/token"
+ "go/types"
+ "sync"
+)
+
+func errorf(format string, args ...interface{}) {
+ panic(fmt.Sprintf(format, args...))
+}
+
+const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
+
+// Synthesize a token.Pos
+type fakeFileSet struct {
+ fset *token.FileSet
+ files map[string]*fileInfo
+}
+
+type fileInfo struct {
+ file *token.File
+ lastline int
+}
+
+const maxlines = 64 * 1024
+
+func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
+ // TODO(mdempsky): Make use of column.
+
+ // Since we don't know the set of needed file positions, we reserve maxlines
+ // positions per file. We delay calling token.File.SetLines until all
+ // positions have been calculated (by way of fakeFileSet.setLines), so that
+ // we can avoid setting unnecessary lines. See also golang/go#46586.
+ f := s.files[file]
+ if f == nil {
+ f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)}
+ s.files[file] = f
+ }
+ if line > maxlines {
+ line = 1
+ }
+ if line > f.lastline {
+ f.lastline = line
+ }
+
+ // Return a fake position assuming that f.file consists only of newlines.
+ return token.Pos(f.file.Base() + line - 1)
+}
+
+func (s *fakeFileSet) setLines() {
+ fakeLinesOnce.Do(func() {
+ fakeLines = make([]int, maxlines)
+ for i := range fakeLines {
+ fakeLines[i] = i
+ }
+ })
+ for _, f := range s.files {
+ f.file.SetLines(fakeLines[:f.lastline])
+ }
+}
+
+var (
+ fakeLines []int
+ fakeLinesOnce sync.Once
+)
+
+func chanDir(d int) types.ChanDir {
+ // tag values must match the constants in cmd/compile/internal/gc/go.go
+ switch d {
+ case 1 /* Crecv */ :
+ return types.RecvOnly
+ case 2 /* Csend */ :
+ return types.SendOnly
+ case 3 /* Cboth */ :
+ return types.SendRecv
+ default:
+ errorf("unexpected channel dir %d", d)
+ return 0
+ }
+}
+
+var predeclOnce sync.Once
+var predecl []types.Type // initialized lazily
+
+func predeclared() []types.Type {
+ predeclOnce.Do(func() {
+ // initialize lazily to be sure that all
+ // elements have been initialized before
+ predecl = []types.Type{ // basic types
+ types.Typ[types.Bool],
+ types.Typ[types.Int],
+ types.Typ[types.Int8],
+ types.Typ[types.Int16],
+ types.Typ[types.Int32],
+ types.Typ[types.Int64],
+ types.Typ[types.Uint],
+ types.Typ[types.Uint8],
+ types.Typ[types.Uint16],
+ types.Typ[types.Uint32],
+ types.Typ[types.Uint64],
+ types.Typ[types.Uintptr],
+ types.Typ[types.Float32],
+ types.Typ[types.Float64],
+ types.Typ[types.Complex64],
+ types.Typ[types.Complex128],
+ types.Typ[types.String],
+
+ // basic type aliases
+ types.Universe.Lookup("byte").Type(),
+ types.Universe.Lookup("rune").Type(),
+
+ // error
+ types.Universe.Lookup("error").Type(),
+
+ // untyped types
+ types.Typ[types.UntypedBool],
+ types.Typ[types.UntypedInt],
+ types.Typ[types.UntypedRune],
+ types.Typ[types.UntypedFloat],
+ types.Typ[types.UntypedComplex],
+ types.Typ[types.UntypedString],
+ types.Typ[types.UntypedNil],
+
+ // package unsafe
+ types.Typ[types.UnsafePointer],
+
+ // invalid type
+ types.Typ[types.Invalid], // only appears in packages with errors
+
+ // used internally by gc; never used by this package or in .a files
+ anyType{},
+ }
+ predecl = append(predecl, additionalPredeclared()...)
+ })
+ return predecl
+}
+
+type anyType struct{}
+
+func (t anyType) Underlying() types.Type { return t }
+func (t anyType) String() string { return "any" }
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go
new file mode 100644
index 00000000..f6437feb
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go
@@ -0,0 +1,99 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go.
+
+// This file implements FindExportData.
+
+package gcimporter
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+)
+
+func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) {
+ // See $GOROOT/include/ar.h.
+ hdr := make([]byte, 16+12+6+6+8+10+2)
+ _, err = io.ReadFull(r, hdr)
+ if err != nil {
+ return
+ }
+ // leave for debugging
+ if false {
+ fmt.Printf("header: %s", hdr)
+ }
+ s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
+ length, err := strconv.Atoi(s)
+ size = int64(length)
+ if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
+ err = fmt.Errorf("invalid archive header")
+ return
+ }
+ name = strings.TrimSpace(string(hdr[:16]))
+ return
+}
+
+// FindExportData positions the reader r at the beginning of the
+// export data section of an underlying GC-created object/archive
+// file by reading from it. The reader must be positioned at the
+// start of the file before calling this function. The hdr result
+// is the string before the export data, either "$$" or "$$B".
+// The size result is the length of the export data in bytes, or -1 if not known.
+func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) {
+ // Read first line to make sure this is an object file.
+ line, err := r.ReadSlice('\n')
+ if err != nil {
+ err = fmt.Errorf("can't find export data (%v)", err)
+ return
+ }
+
+ if string(line) == "!\n" {
+ // Archive file. Scan to __.PKGDEF.
+ var name string
+ if name, size, err = readGopackHeader(r); err != nil {
+ return
+ }
+
+ // First entry should be __.PKGDEF.
+ if name != "__.PKGDEF" {
+ err = fmt.Errorf("go archive is missing __.PKGDEF")
+ return
+ }
+
+ // Read first line of __.PKGDEF data, so that line
+ // is once again the first line of the input.
+ if line, err = r.ReadSlice('\n'); err != nil {
+ err = fmt.Errorf("can't find export data (%v)", err)
+ return
+ }
+ size -= int64(len(line))
+ }
+
+ // Now at __.PKGDEF in archive or still at beginning of file.
+ // Either way, line should begin with "go object ".
+ if !strings.HasPrefix(string(line), "go object ") {
+ err = fmt.Errorf("not a Go object file")
+ return
+ }
+
+ // Skip over object header to export data.
+ // Begins after first line starting with $$.
+ for line[0] != '$' {
+ if line, err = r.ReadSlice('\n'); err != nil {
+ err = fmt.Errorf("can't find export data (%v)", err)
+ return
+ }
+ size -= int64(len(line))
+ }
+ hdr = string(line)
+ if size < 0 {
+ size = -1
+ }
+
+ return
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
new file mode 100644
index 00000000..39df9112
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
@@ -0,0 +1,266 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a reduced copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go.
+
+// Package gcimporter provides various functions for reading
+// gc-generated object files that can be used to implement the
+// Importer interface defined by the Go 1.5 standard library package.
+//
+// The encoding is deterministic: if the encoder is applied twice to
+// the same types.Package data structure, both encodings are equal.
+// This property may be important to avoid spurious changes in
+// applications such as build systems.
+//
+// However, the encoder is not necessarily idempotent. Importing an
+// exported package may yield a types.Package that, while it
+// represents the same set of Go types as the original, may differ in
+// the details of its internal representation. Because of these
+// differences, re-encoding the imported package may yield a
+// different, but equally valid, encoding of the package.
+package gcimporter // import "golang.org/x/tools/internal/gcimporter"
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "go/build"
+ "go/token"
+ "go/types"
+ "io"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "sync"
+)
+
+const (
+ // Enable debug during development: it adds some additional checks, and
+ // prevents errors from being recovered.
+ debug = false
+
+ // If trace is set, debugging output is printed to std out.
+ trace = false
+)
+
+var exportMap sync.Map // package dir → func() (string, bool)
+
+// lookupGorootExport returns the location of the export data
+// (normally found in the build cache, but located in GOROOT/pkg
+// in prior Go releases) for the package located in pkgDir.
+//
+// (We use the package's directory instead of its import path
+// mainly to simplify handling of the packages in src/vendor
+// and cmd/vendor.)
+func lookupGorootExport(pkgDir string) (string, bool) {
+ f, ok := exportMap.Load(pkgDir)
+ if !ok {
+ var (
+ listOnce sync.Once
+ exportPath string
+ )
+ f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
+ listOnce.Do(func() {
+ cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir)
+ cmd.Dir = build.Default.GOROOT
+ var output []byte
+ output, err := cmd.Output()
+ if err != nil {
+ return
+ }
+
+ exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
+ if len(exports) != 1 {
+ return
+ }
+
+ exportPath = exports[0]
+ })
+
+ return exportPath, exportPath != ""
+ })
+ }
+
+ return f.(func() (string, bool))()
+}
+
+var pkgExts = [...]string{".a", ".o"}
+
+// FindPkg returns the filename and unique package id for an import
+// path based on package information provided by build.Import (using
+// the build.Default build.Context). A relative srcDir is interpreted
+// relative to the current working directory.
+// If no file was found, an empty filename is returned.
+func FindPkg(path, srcDir string) (filename, id string) {
+ if path == "" {
+ return
+ }
+
+ var noext string
+ switch {
+ default:
+ // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
+ // Don't require the source files to be present.
+ if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
+ srcDir = abs
+ }
+ bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
+ if bp.PkgObj == "" {
+ var ok bool
+ if bp.Goroot && bp.Dir != "" {
+ filename, ok = lookupGorootExport(bp.Dir)
+ }
+ if !ok {
+ id = path // make sure we have an id to print in error message
+ return
+ }
+ } else {
+ noext = strings.TrimSuffix(bp.PkgObj, ".a")
+ id = bp.ImportPath
+ }
+
+ case build.IsLocalImport(path):
+ // "./x" -> "/this/directory/x.ext", "/this/directory/x"
+ noext = filepath.Join(srcDir, path)
+ id = noext
+
+ case filepath.IsAbs(path):
+ // for completeness only - go/build.Import
+ // does not support absolute imports
+ // "/x" -> "/x.ext", "/x"
+ noext = path
+ id = path
+ }
+
+ if false { // for debugging
+ if path != id {
+ fmt.Printf("%s -> %s\n", path, id)
+ }
+ }
+
+ if filename != "" {
+ if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+ return
+ }
+ }
+
+ // try extensions
+ for _, ext := range pkgExts {
+ filename = noext + ext
+ if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+ return
+ }
+ }
+
+ filename = "" // not found
+ return
+}
+
+// Import imports a gc-generated package given its import path and srcDir, adds
+// the corresponding package object to the packages map, and returns the object.
+// The packages map must contain all packages already imported.
+func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
+ var rc io.ReadCloser
+ var filename, id string
+ if lookup != nil {
+ // With custom lookup specified, assume that caller has
+ // converted path to a canonical import path for use in the map.
+ if path == "unsafe" {
+ return types.Unsafe, nil
+ }
+ id = path
+
+ // No need to re-import if the package was imported completely before.
+ if pkg = packages[id]; pkg != nil && pkg.Complete() {
+ return
+ }
+ f, err := lookup(path)
+ if err != nil {
+ return nil, err
+ }
+ rc = f
+ } else {
+ filename, id = FindPkg(path, srcDir)
+ if filename == "" {
+ if path == "unsafe" {
+ return types.Unsafe, nil
+ }
+ return nil, fmt.Errorf("can't find import: %q", id)
+ }
+
+ // no need to re-import if the package was imported completely before
+ if pkg = packages[id]; pkg != nil && pkg.Complete() {
+ return
+ }
+
+ // open file
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ if err != nil {
+ // add file name to error
+ err = fmt.Errorf("%s: %v", filename, err)
+ }
+ }()
+ rc = f
+ }
+ defer rc.Close()
+
+ var hdr string
+ var size int64
+ buf := bufio.NewReader(rc)
+ if hdr, size, err = FindExportData(buf); err != nil {
+ return
+ }
+
+ switch hdr {
+ case "$$B\n":
+ var data []byte
+ data, err = io.ReadAll(buf)
+ if err != nil {
+ break
+ }
+
+ // TODO(gri): allow clients of go/importer to provide a FileSet.
+ // Or, define a new standard go/types/gcexportdata package.
+ fset := token.NewFileSet()
+
+ // Select appropriate importer.
+ if len(data) > 0 {
+ switch data[0] {
+ case 'v', 'c', 'd': // binary, till go1.10
+ return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0])
+
+ case 'i': // indexed, till go1.19
+ _, pkg, err := IImportData(fset, packages, data[1:], id)
+ return pkg, err
+
+ case 'u': // unified, from go1.20
+ _, pkg, err := UImportData(fset, packages, data[1:size], id)
+ return pkg, err
+
+ default:
+ l := len(data)
+ if l > 10 {
+ l = 10
+ }
+ return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), id)
+ }
+ }
+
+ default:
+ err = fmt.Errorf("unknown export data header: %q", hdr)
+ }
+
+ return
+}
+
+type byPath []*types.Package
+
+func (a byPath) Len() int { return len(a) }
+func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
new file mode 100644
index 00000000..deeb67f3
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
@@ -0,0 +1,1332 @@
+// 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.
+
+// Indexed binary package export.
+// This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go;
+// see that file for specification of the format.
+
+package gcimporter
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "go/constant"
+ "go/token"
+ "go/types"
+ "io"
+ "math/big"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+
+ "golang.org/x/tools/go/types/objectpath"
+ "golang.org/x/tools/internal/aliases"
+ "golang.org/x/tools/internal/tokeninternal"
+)
+
+// IExportShallow encodes "shallow" export data for the specified package.
+//
+// No promises are made about the encoding other than that it can be decoded by
+// the same version of IIExportShallow. If you plan to save export data in the
+// file system, be sure to include a cryptographic digest of the executable in
+// the key to avoid version skew.
+//
+// If the provided reportf func is non-nil, it will be used for reporting bugs
+// encountered during export.
+// TODO(rfindley): remove reportf when we are confident enough in the new
+// objectpath encoding.
+func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc) ([]byte, error) {
+ // In principle this operation can only fail if out.Write fails,
+ // but that's impossible for bytes.Buffer---and as a matter of
+ // fact iexportCommon doesn't even check for I/O errors.
+ // TODO(adonovan): handle I/O errors properly.
+ // TODO(adonovan): use byte slices throughout, avoiding copying.
+ const bundle, shallow = false, true
+ var out bytes.Buffer
+ err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
+ return out.Bytes(), err
+}
+
+// IImportShallow decodes "shallow" types.Package data encoded by
+// IExportShallow in the same executable. This function cannot import data from
+// cmd/compile or gcexportdata.Write.
+//
+// The importer calls getPackages to obtain package symbols for all
+// packages mentioned in the export data, including the one being
+// decoded.
+//
+// If the provided reportf func is non-nil, it will be used for reporting bugs
+// encountered during import.
+// TODO(rfindley): remove reportf when we are confident enough in the new
+// objectpath encoding.
+func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, path string, reportf ReportFunc) (*types.Package, error) {
+ const bundle = false
+ const shallow = true
+ pkgs, err := iimportCommon(fset, getPackages, data, bundle, path, shallow, reportf)
+ if err != nil {
+ return nil, err
+ }
+ return pkgs[0], nil
+}
+
+// ReportFunc is the type of a function used to report formatted bugs.
+type ReportFunc = func(string, ...interface{})
+
+// Current bundled export format version. Increase with each format change.
+// 0: initial implementation
+const bundleVersion = 0
+
+// IExportData writes indexed export data for pkg to out.
+//
+// If no file set is provided, position info will be missing.
+// The package path of the top-level package will not be recorded,
+// so that calls to IImportData can override with a provided package path.
+func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
+ const bundle, shallow = false, false
+ return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
+}
+
+// IExportBundle writes an indexed export bundle for pkgs to out.
+func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error {
+ const bundle, shallow = true, false
+ return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs)
+}
+
+func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package) (err error) {
+ if !debug {
+ defer func() {
+ if e := recover(); e != nil {
+ if ierr, ok := e.(internalError); ok {
+ err = ierr
+ return
+ }
+ // Not an internal error; panic again.
+ panic(e)
+ }
+ }()
+ }
+
+ p := iexporter{
+ fset: fset,
+ version: version,
+ shallow: shallow,
+ allPkgs: map[*types.Package]bool{},
+ stringIndex: map[string]uint64{},
+ declIndex: map[types.Object]uint64{},
+ tparamNames: map[types.Object]string{},
+ typIndex: map[types.Type]uint64{},
+ }
+ if !bundle {
+ p.localpkg = pkgs[0]
+ }
+
+ for i, pt := range predeclared() {
+ p.typIndex[pt] = uint64(i)
+ }
+ if len(p.typIndex) > predeclReserved {
+ panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved))
+ }
+
+ // Initialize work queue with exported declarations.
+ for _, pkg := range pkgs {
+ scope := pkg.Scope()
+ for _, name := range scope.Names() {
+ if token.IsExported(name) {
+ p.pushDecl(scope.Lookup(name))
+ }
+ }
+
+ if bundle {
+ // Ensure pkg and its imports are included in the index.
+ p.allPkgs[pkg] = true
+ for _, imp := range pkg.Imports() {
+ p.allPkgs[imp] = true
+ }
+ }
+ }
+
+ // Loop until no more work.
+ for !p.declTodo.empty() {
+ p.doDecl(p.declTodo.popHead())
+ }
+
+ // Produce index of offset of each file record in files.
+ var files intWriter
+ var fileOffset []uint64 // fileOffset[i] is offset in files of file encoded as i
+ if p.shallow {
+ fileOffset = make([]uint64, len(p.fileInfos))
+ for i, info := range p.fileInfos {
+ fileOffset[i] = uint64(files.Len())
+ p.encodeFile(&files, info.file, info.needed)
+ }
+ }
+
+ // Append indices to data0 section.
+ dataLen := uint64(p.data0.Len())
+ w := p.newWriter()
+ w.writeIndex(p.declIndex)
+
+ if bundle {
+ w.uint64(uint64(len(pkgs)))
+ for _, pkg := range pkgs {
+ w.pkg(pkg)
+ imps := pkg.Imports()
+ w.uint64(uint64(len(imps)))
+ for _, imp := range imps {
+ w.pkg(imp)
+ }
+ }
+ }
+ w.flush()
+
+ // Assemble header.
+ var hdr intWriter
+ if bundle {
+ hdr.uint64(bundleVersion)
+ }
+ hdr.uint64(uint64(p.version))
+ hdr.uint64(uint64(p.strings.Len()))
+ if p.shallow {
+ hdr.uint64(uint64(files.Len()))
+ hdr.uint64(uint64(len(fileOffset)))
+ for _, offset := range fileOffset {
+ hdr.uint64(offset)
+ }
+ }
+ hdr.uint64(dataLen)
+
+ // Flush output.
+ io.Copy(out, &hdr)
+ io.Copy(out, &p.strings)
+ if p.shallow {
+ io.Copy(out, &files)
+ }
+ io.Copy(out, &p.data0)
+
+ return nil
+}
+
+// encodeFile writes to w a representation of the file sufficient to
+// faithfully restore position information about all needed offsets.
+// Mutates the needed array.
+func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64) {
+ _ = needed[0] // precondition: needed is non-empty
+
+ w.uint64(p.stringOff(file.Name()))
+
+ size := uint64(file.Size())
+ w.uint64(size)
+
+ // Sort the set of needed offsets. Duplicates are harmless.
+ sort.Slice(needed, func(i, j int) bool { return needed[i] < needed[j] })
+
+ lines := tokeninternal.GetLines(file) // byte offset of each line start
+ w.uint64(uint64(len(lines)))
+
+ // Rather than record the entire array of line start offsets,
+ // we save only a sparse list of (index, offset) pairs for
+ // the start of each line that contains a needed position.
+ var sparse [][2]int // (index, offset) pairs
+outer:
+ for i, lineStart := range lines {
+ lineEnd := size
+ if i < len(lines)-1 {
+ lineEnd = uint64(lines[i+1])
+ }
+ // Does this line contains a needed offset?
+ if needed[0] < lineEnd {
+ sparse = append(sparse, [2]int{i, lineStart})
+ for needed[0] < lineEnd {
+ needed = needed[1:]
+ if len(needed) == 0 {
+ break outer
+ }
+ }
+ }
+ }
+
+ // Delta-encode the columns.
+ w.uint64(uint64(len(sparse)))
+ var prev [2]int
+ for _, pair := range sparse {
+ w.uint64(uint64(pair[0] - prev[0]))
+ w.uint64(uint64(pair[1] - prev[1]))
+ prev = pair
+ }
+}
+
+// writeIndex writes out an object index. mainIndex indicates whether
+// we're writing out the main index, which is also read by
+// non-compiler tools and includes a complete package description
+// (i.e., name and height).
+func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
+ type pkgObj struct {
+ obj types.Object
+ name string // qualified name; differs from obj.Name for type params
+ }
+ // Build a map from packages to objects from that package.
+ pkgObjs := map[*types.Package][]pkgObj{}
+
+ // For the main index, make sure to include every package that
+ // we reference, even if we're not exporting (or reexporting)
+ // any symbols from it.
+ if w.p.localpkg != nil {
+ pkgObjs[w.p.localpkg] = nil
+ }
+ for pkg := range w.p.allPkgs {
+ pkgObjs[pkg] = nil
+ }
+
+ for obj := range index {
+ name := w.p.exportName(obj)
+ pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name})
+ }
+
+ var pkgs []*types.Package
+ for pkg, objs := range pkgObjs {
+ pkgs = append(pkgs, pkg)
+
+ sort.Slice(objs, func(i, j int) bool {
+ return objs[i].name < objs[j].name
+ })
+ }
+
+ sort.Slice(pkgs, func(i, j int) bool {
+ return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j])
+ })
+
+ w.uint64(uint64(len(pkgs)))
+ for _, pkg := range pkgs {
+ w.string(w.exportPath(pkg))
+ w.string(pkg.Name())
+ w.uint64(uint64(0)) // package height is not needed for go/types
+
+ objs := pkgObjs[pkg]
+ w.uint64(uint64(len(objs)))
+ for _, obj := range objs {
+ w.string(obj.name)
+ w.uint64(index[obj.obj])
+ }
+ }
+}
+
+// exportName returns the 'exported' name of an object. It differs from
+// obj.Name() only for type parameters (see tparamExportName for details).
+func (p *iexporter) exportName(obj types.Object) (res string) {
+ if name := p.tparamNames[obj]; name != "" {
+ return name
+ }
+ return obj.Name()
+}
+
+type iexporter struct {
+ fset *token.FileSet
+ out *bytes.Buffer
+ version int
+
+ shallow bool // don't put types from other packages in the index
+ objEncoder *objectpath.Encoder // encodes objects from other packages in shallow mode; lazily allocated
+ localpkg *types.Package // (nil in bundle mode)
+
+ // allPkgs tracks all packages that have been referenced by
+ // the export data, so we can ensure to include them in the
+ // main index.
+ allPkgs map[*types.Package]bool
+
+ declTodo objQueue
+
+ strings intWriter
+ stringIndex map[string]uint64
+
+ // In shallow mode, object positions are encoded as (file, offset).
+ // Each file is recorded as a line-number table.
+ // Only the lines of needed positions are saved faithfully.
+ fileInfo map[*token.File]uint64 // value is index in fileInfos
+ fileInfos []*filePositions
+
+ data0 intWriter
+ declIndex map[types.Object]uint64
+ tparamNames map[types.Object]string // typeparam->exported name
+ typIndex map[types.Type]uint64
+
+ indent int // for tracing support
+}
+
+type filePositions struct {
+ file *token.File
+ needed []uint64 // unordered list of needed file offsets
+}
+
+func (p *iexporter) trace(format string, args ...interface{}) {
+ if !trace {
+ // Call sites should also be guarded, but having this check here allows
+ // easily enabling/disabling debug trace statements.
+ return
+ }
+ fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
+}
+
+// objectpathEncoder returns the lazily allocated objectpath.Encoder to use
+// when encoding objects in other packages during shallow export.
+//
+// Using a shared Encoder amortizes some of cost of objectpath search.
+func (p *iexporter) objectpathEncoder() *objectpath.Encoder {
+ if p.objEncoder == nil {
+ p.objEncoder = new(objectpath.Encoder)
+ }
+ return p.objEncoder
+}
+
+// stringOff returns the offset of s within the string section.
+// If not already present, it's added to the end.
+func (p *iexporter) stringOff(s string) uint64 {
+ off, ok := p.stringIndex[s]
+ if !ok {
+ off = uint64(p.strings.Len())
+ p.stringIndex[s] = off
+
+ p.strings.uint64(uint64(len(s)))
+ p.strings.WriteString(s)
+ }
+ return off
+}
+
+// fileIndexAndOffset returns the index of the token.File and the byte offset of pos within it.
+func (p *iexporter) fileIndexAndOffset(file *token.File, pos token.Pos) (uint64, uint64) {
+ index, ok := p.fileInfo[file]
+ if !ok {
+ index = uint64(len(p.fileInfo))
+ p.fileInfos = append(p.fileInfos, &filePositions{file: file})
+ if p.fileInfo == nil {
+ p.fileInfo = make(map[*token.File]uint64)
+ }
+ p.fileInfo[file] = index
+ }
+ // Record each needed offset.
+ info := p.fileInfos[index]
+ offset := uint64(file.Offset(pos))
+ info.needed = append(info.needed, offset)
+
+ return index, offset
+}
+
+// pushDecl adds n to the declaration work queue, if not already present.
+func (p *iexporter) pushDecl(obj types.Object) {
+ // Package unsafe is known to the compiler and predeclared.
+ // Caller should not ask us to do export it.
+ if obj.Pkg() == types.Unsafe {
+ panic("cannot export package unsafe")
+ }
+
+ // Shallow export data: don't index decls from other packages.
+ if p.shallow && obj.Pkg() != p.localpkg {
+ return
+ }
+
+ if _, ok := p.declIndex[obj]; ok {
+ return
+ }
+
+ p.declIndex[obj] = ^uint64(0) // mark obj present in work queue
+ p.declTodo.pushTail(obj)
+}
+
+// exportWriter handles writing out individual data section chunks.
+type exportWriter struct {
+ p *iexporter
+
+ data intWriter
+ prevFile string
+ prevLine int64
+ prevColumn int64
+}
+
+func (w *exportWriter) exportPath(pkg *types.Package) string {
+ if pkg == w.p.localpkg {
+ return ""
+ }
+ return pkg.Path()
+}
+
+func (p *iexporter) doDecl(obj types.Object) {
+ if trace {
+ p.trace("exporting decl %v (%T)", obj, obj)
+ p.indent++
+ defer func() {
+ p.indent--
+ p.trace("=> %s", obj)
+ }()
+ }
+ w := p.newWriter()
+
+ switch obj := obj.(type) {
+ case *types.Var:
+ w.tag(varTag)
+ w.pos(obj.Pos())
+ w.typ(obj.Type(), obj.Pkg())
+
+ case *types.Func:
+ sig, _ := obj.Type().(*types.Signature)
+ if sig.Recv() != nil {
+ // We shouldn't see methods in the package scope,
+ // but the type checker may repair "func () F() {}"
+ // to "func (Invalid) F()" and then treat it like "func F()",
+ // so allow that. See golang/go#57729.
+ if sig.Recv().Type() != types.Typ[types.Invalid] {
+ panic(internalErrorf("unexpected method: %v", sig))
+ }
+ }
+
+ // Function.
+ if sig.TypeParams().Len() == 0 {
+ w.tag(funcTag)
+ } else {
+ w.tag(genericFuncTag)
+ }
+ w.pos(obj.Pos())
+ // The tparam list of the function type is the declaration of the type
+ // params. So, write out the type params right now. Then those type params
+ // will be referenced via their type offset (via typOff) in all other
+ // places in the signature and function where they are used.
+ //
+ // While importing the type parameters, tparamList computes and records
+ // their export name, so that it can be later used when writing the index.
+ if tparams := sig.TypeParams(); tparams.Len() > 0 {
+ w.tparamList(obj.Name(), tparams, obj.Pkg())
+ }
+ w.signature(sig)
+
+ case *types.Const:
+ w.tag(constTag)
+ w.pos(obj.Pos())
+ w.value(obj.Type(), obj.Val())
+
+ case *types.TypeName:
+ t := obj.Type()
+
+ if tparam, ok := aliases.Unalias(t).(*types.TypeParam); ok {
+ w.tag(typeParamTag)
+ w.pos(obj.Pos())
+ constraint := tparam.Constraint()
+ if p.version >= iexportVersionGo1_18 {
+ implicit := false
+ if iface, _ := aliases.Unalias(constraint).(*types.Interface); iface != nil {
+ implicit = iface.IsImplicit()
+ }
+ w.bool(implicit)
+ }
+ w.typ(constraint, obj.Pkg())
+ break
+ }
+
+ if obj.IsAlias() {
+ w.tag(aliasTag)
+ w.pos(obj.Pos())
+ if alias, ok := t.(*aliases.Alias); ok {
+ // Preserve materialized aliases,
+ // even of non-exported types.
+ t = aliases.Rhs(alias)
+ }
+ w.typ(t, obj.Pkg())
+ break
+ }
+
+ // Defined type.
+ named, ok := t.(*types.Named)
+ if !ok {
+ panic(internalErrorf("%s is not a defined type", t))
+ }
+
+ if named.TypeParams().Len() == 0 {
+ w.tag(typeTag)
+ } else {
+ w.tag(genericTypeTag)
+ }
+ w.pos(obj.Pos())
+
+ if named.TypeParams().Len() > 0 {
+ // While importing the type parameters, tparamList computes and records
+ // their export name, so that it can be later used when writing the index.
+ w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg())
+ }
+
+ underlying := named.Underlying()
+ w.typ(underlying, obj.Pkg())
+
+ if types.IsInterface(t) {
+ break
+ }
+
+ n := named.NumMethods()
+ w.uint64(uint64(n))
+ for i := 0; i < n; i++ {
+ m := named.Method(i)
+ w.pos(m.Pos())
+ w.string(m.Name())
+ sig, _ := m.Type().(*types.Signature)
+
+ // Receiver type parameters are type arguments of the receiver type, so
+ // their name must be qualified before exporting recv.
+ if rparams := sig.RecvTypeParams(); rparams.Len() > 0 {
+ prefix := obj.Name() + "." + m.Name()
+ for i := 0; i < rparams.Len(); i++ {
+ rparam := rparams.At(i)
+ name := tparamExportName(prefix, rparam)
+ w.p.tparamNames[rparam.Obj()] = name
+ }
+ }
+ w.param(sig.Recv())
+ w.signature(sig)
+ }
+
+ default:
+ panic(internalErrorf("unexpected object: %v", obj))
+ }
+
+ p.declIndex[obj] = w.flush()
+}
+
+func (w *exportWriter) tag(tag byte) {
+ w.data.WriteByte(tag)
+}
+
+func (w *exportWriter) pos(pos token.Pos) {
+ if w.p.shallow {
+ w.posV2(pos)
+ } else if w.p.version >= iexportVersionPosCol {
+ w.posV1(pos)
+ } else {
+ w.posV0(pos)
+ }
+}
+
+// posV2 encoding (used only in shallow mode) records positions as
+// (file, offset), where file is the index in the token.File table
+// (which records the file name and newline offsets) and offset is a
+// byte offset. It effectively ignores //line directives.
+func (w *exportWriter) posV2(pos token.Pos) {
+ if pos == token.NoPos {
+ w.uint64(0)
+ return
+ }
+ file := w.p.fset.File(pos) // fset must be non-nil
+ index, offset := w.p.fileIndexAndOffset(file, pos)
+ w.uint64(1 + index)
+ w.uint64(offset)
+}
+
+func (w *exportWriter) posV1(pos token.Pos) {
+ if w.p.fset == nil {
+ w.int64(0)
+ return
+ }
+
+ p := w.p.fset.Position(pos)
+ file := p.Filename
+ line := int64(p.Line)
+ column := int64(p.Column)
+
+ deltaColumn := (column - w.prevColumn) << 1
+ deltaLine := (line - w.prevLine) << 1
+
+ if file != w.prevFile {
+ deltaLine |= 1
+ }
+ if deltaLine != 0 {
+ deltaColumn |= 1
+ }
+
+ w.int64(deltaColumn)
+ if deltaColumn&1 != 0 {
+ w.int64(deltaLine)
+ if deltaLine&1 != 0 {
+ w.string(file)
+ }
+ }
+
+ w.prevFile = file
+ w.prevLine = line
+ w.prevColumn = column
+}
+
+func (w *exportWriter) posV0(pos token.Pos) {
+ if w.p.fset == nil {
+ w.int64(0)
+ return
+ }
+
+ p := w.p.fset.Position(pos)
+ file := p.Filename
+ line := int64(p.Line)
+
+ // When file is the same as the last position (common case),
+ // we can save a few bytes by delta encoding just the line
+ // number.
+ //
+ // Note: Because data objects may be read out of order (or not
+ // at all), we can only apply delta encoding within a single
+ // object. This is handled implicitly by tracking prevFile and
+ // prevLine as fields of exportWriter.
+
+ if file == w.prevFile {
+ delta := line - w.prevLine
+ w.int64(delta)
+ if delta == deltaNewFile {
+ w.int64(-1)
+ }
+ } else {
+ w.int64(deltaNewFile)
+ w.int64(line) // line >= 0
+ w.string(file)
+ w.prevFile = file
+ }
+ w.prevLine = line
+}
+
+func (w *exportWriter) pkg(pkg *types.Package) {
+ // Ensure any referenced packages are declared in the main index.
+ w.p.allPkgs[pkg] = true
+
+ w.string(w.exportPath(pkg))
+}
+
+func (w *exportWriter) qualifiedType(obj *types.TypeName) {
+ name := w.p.exportName(obj)
+
+ // Ensure any referenced declarations are written out too.
+ w.p.pushDecl(obj)
+ w.string(name)
+ w.pkg(obj.Pkg())
+}
+
+// TODO(rfindley): what does 'pkg' even mean here? It would be better to pass
+// it in explicitly into signatures and structs that may use it for
+// constructing fields.
+func (w *exportWriter) typ(t types.Type, pkg *types.Package) {
+ w.data.uint64(w.p.typOff(t, pkg))
+}
+
+func (p *iexporter) newWriter() *exportWriter {
+ return &exportWriter{p: p}
+}
+
+func (w *exportWriter) flush() uint64 {
+ off := uint64(w.p.data0.Len())
+ io.Copy(&w.p.data0, &w.data)
+ return off
+}
+
+func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 {
+ off, ok := p.typIndex[t]
+ if !ok {
+ w := p.newWriter()
+ w.doTyp(t, pkg)
+ off = predeclReserved + w.flush()
+ p.typIndex[t] = off
+ }
+ return off
+}
+
+func (w *exportWriter) startType(k itag) {
+ w.data.uint64(uint64(k))
+}
+
+func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
+ if trace {
+ w.p.trace("exporting type %s (%T)", t, t)
+ w.p.indent++
+ defer func() {
+ w.p.indent--
+ w.p.trace("=> %s", t)
+ }()
+ }
+ switch t := t.(type) {
+ case *aliases.Alias:
+ // TODO(adonovan): support parameterized aliases, following *types.Named.
+ w.startType(aliasType)
+ w.qualifiedType(t.Obj())
+
+ case *types.Named:
+ if targs := t.TypeArgs(); targs.Len() > 0 {
+ w.startType(instanceType)
+ // TODO(rfindley): investigate if this position is correct, and if it
+ // matters.
+ w.pos(t.Obj().Pos())
+ w.typeList(targs, pkg)
+ w.typ(t.Origin(), pkg)
+ return
+ }
+ w.startType(definedType)
+ w.qualifiedType(t.Obj())
+
+ case *types.TypeParam:
+ w.startType(typeParamType)
+ w.qualifiedType(t.Obj())
+
+ case *types.Pointer:
+ w.startType(pointerType)
+ w.typ(t.Elem(), pkg)
+
+ case *types.Slice:
+ w.startType(sliceType)
+ w.typ(t.Elem(), pkg)
+
+ case *types.Array:
+ w.startType(arrayType)
+ w.uint64(uint64(t.Len()))
+ w.typ(t.Elem(), pkg)
+
+ case *types.Chan:
+ w.startType(chanType)
+ // 1 RecvOnly; 2 SendOnly; 3 SendRecv
+ var dir uint64
+ switch t.Dir() {
+ case types.RecvOnly:
+ dir = 1
+ case types.SendOnly:
+ dir = 2
+ case types.SendRecv:
+ dir = 3
+ }
+ w.uint64(dir)
+ w.typ(t.Elem(), pkg)
+
+ case *types.Map:
+ w.startType(mapType)
+ w.typ(t.Key(), pkg)
+ w.typ(t.Elem(), pkg)
+
+ case *types.Signature:
+ w.startType(signatureType)
+ w.pkg(pkg)
+ w.signature(t)
+
+ case *types.Struct:
+ w.startType(structType)
+ n := t.NumFields()
+ // Even for struct{} we must emit some qualifying package, because that's
+ // what the compiler does, and thus that's what the importer expects.
+ fieldPkg := pkg
+ if n > 0 {
+ fieldPkg = t.Field(0).Pkg()
+ }
+ if fieldPkg == nil {
+ // TODO(rfindley): improve this very hacky logic.
+ //
+ // The importer expects a package to be set for all struct types, even
+ // those with no fields. A better encoding might be to set NumFields
+ // before pkg. setPkg panics with a nil package, which may be possible
+ // to reach with invalid packages (and perhaps valid packages, too?), so
+ // (arbitrarily) set the localpkg if available.
+ //
+ // Alternatively, we may be able to simply guarantee that pkg != nil, by
+ // reconsidering the encoding of constant values.
+ if w.p.shallow {
+ fieldPkg = w.p.localpkg
+ } else {
+ panic(internalErrorf("no package to set for empty struct"))
+ }
+ }
+ w.pkg(fieldPkg)
+ w.uint64(uint64(n))
+
+ for i := 0; i < n; i++ {
+ f := t.Field(i)
+ if w.p.shallow {
+ w.objectPath(f)
+ }
+ w.pos(f.Pos())
+ w.string(f.Name()) // unexported fields implicitly qualified by prior setPkg
+ w.typ(f.Type(), fieldPkg)
+ w.bool(f.Anonymous())
+ w.string(t.Tag(i)) // note (or tag)
+ }
+
+ case *types.Interface:
+ w.startType(interfaceType)
+ w.pkg(pkg)
+
+ n := t.NumEmbeddeds()
+ w.uint64(uint64(n))
+ for i := 0; i < n; i++ {
+ ft := t.EmbeddedType(i)
+ tPkg := pkg
+ if named, _ := aliases.Unalias(ft).(*types.Named); named != nil {
+ w.pos(named.Obj().Pos())
+ } else {
+ w.pos(token.NoPos)
+ }
+ w.typ(ft, tPkg)
+ }
+
+ // See comment for struct fields. In shallow mode we change the encoding
+ // for interface methods that are promoted from other packages.
+
+ n = t.NumExplicitMethods()
+ w.uint64(uint64(n))
+ for i := 0; i < n; i++ {
+ m := t.ExplicitMethod(i)
+ if w.p.shallow {
+ w.objectPath(m)
+ }
+ w.pos(m.Pos())
+ w.string(m.Name())
+ sig, _ := m.Type().(*types.Signature)
+ w.signature(sig)
+ }
+
+ case *types.Union:
+ w.startType(unionType)
+ nt := t.Len()
+ w.uint64(uint64(nt))
+ for i := 0; i < nt; i++ {
+ term := t.Term(i)
+ w.bool(term.Tilde())
+ w.typ(term.Type(), pkg)
+ }
+
+ default:
+ panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t)))
+ }
+}
+
+// objectPath writes the package and objectPath to use to look up obj in a
+// different package, when encoding in "shallow" mode.
+//
+// When doing a shallow import, the importer creates only the local package,
+// and requests package symbols for dependencies from the client.
+// However, certain types defined in the local package may hold objects defined
+// (perhaps deeply) within another package.
+//
+// For example, consider the following:
+//
+// package a
+// func F() chan * map[string] struct { X int }
+//
+// package b
+// import "a"
+// var B = a.F()
+//
+// In this example, the type of b.B holds fields defined in package a.
+// In order to have the correct canonical objects for the field defined in the
+// type of B, they are encoded as objectPaths and later looked up in the
+// importer. The same problem applies to interface methods.
+func (w *exportWriter) objectPath(obj types.Object) {
+ if obj.Pkg() == nil || obj.Pkg() == w.p.localpkg {
+ // obj.Pkg() may be nil for the builtin error.Error.
+ // In this case, or if obj is declared in the local package, no need to
+ // encode.
+ w.string("")
+ return
+ }
+ objectPath, err := w.p.objectpathEncoder().For(obj)
+ if err != nil {
+ // Fall back to the empty string, which will cause the importer to create a
+ // new object, which matches earlier behavior. Creating a new object is
+ // sufficient for many purposes (such as type checking), but causes certain
+ // references algorithms to fail (golang/go#60819). However, we didn't
+ // notice this problem during months of gopls@v0.12.0 testing.
+ //
+ // TODO(golang/go#61674): this workaround is insufficient, as in the case
+ // where the field forwarded from an instantiated type that may not appear
+ // in the export data of the original package:
+ //
+ // // package a
+ // type A[P any] struct{ F P }
+ //
+ // // package b
+ // type B a.A[int]
+ //
+ // We need to update references algorithms not to depend on this
+ // de-duplication, at which point we may want to simply remove the
+ // workaround here.
+ w.string("")
+ return
+ }
+ w.string(string(objectPath))
+ w.pkg(obj.Pkg())
+}
+
+func (w *exportWriter) signature(sig *types.Signature) {
+ w.paramList(sig.Params())
+ w.paramList(sig.Results())
+ if sig.Params().Len() > 0 {
+ w.bool(sig.Variadic())
+ }
+}
+
+func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) {
+ w.uint64(uint64(ts.Len()))
+ for i := 0; i < ts.Len(); i++ {
+ w.typ(ts.At(i), pkg)
+ }
+}
+
+func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) {
+ ll := uint64(list.Len())
+ w.uint64(ll)
+ for i := 0; i < list.Len(); i++ {
+ tparam := list.At(i)
+ // Set the type parameter exportName before exporting its type.
+ exportName := tparamExportName(prefix, tparam)
+ w.p.tparamNames[tparam.Obj()] = exportName
+ w.typ(list.At(i), pkg)
+ }
+}
+
+const blankMarker = "$"
+
+// tparamExportName returns the 'exported' name of a type parameter, which
+// differs from its actual object name: it is prefixed with a qualifier, and
+// blank type parameter names are disambiguated by their index in the type
+// parameter list.
+func tparamExportName(prefix string, tparam *types.TypeParam) string {
+ assert(prefix != "")
+ name := tparam.Obj().Name()
+ if name == "_" {
+ name = blankMarker + strconv.Itoa(tparam.Index())
+ }
+ return prefix + "." + name
+}
+
+// tparamName returns the real name of a type parameter, after stripping its
+// qualifying prefix and reverting blank-name encoding. See tparamExportName
+// for details.
+func tparamName(exportName string) string {
+ // Remove the "path" from the type param name that makes it unique.
+ ix := strings.LastIndex(exportName, ".")
+ if ix < 0 {
+ errorf("malformed type parameter export name %s: missing prefix", exportName)
+ }
+ name := exportName[ix+1:]
+ if strings.HasPrefix(name, blankMarker) {
+ return "_"
+ }
+ return name
+}
+
+func (w *exportWriter) paramList(tup *types.Tuple) {
+ n := tup.Len()
+ w.uint64(uint64(n))
+ for i := 0; i < n; i++ {
+ w.param(tup.At(i))
+ }
+}
+
+func (w *exportWriter) param(obj types.Object) {
+ w.pos(obj.Pos())
+ w.localIdent(obj)
+ w.typ(obj.Type(), obj.Pkg())
+}
+
+func (w *exportWriter) value(typ types.Type, v constant.Value) {
+ w.typ(typ, nil)
+ if w.p.version >= iexportVersionGo1_18 {
+ w.int64(int64(v.Kind()))
+ }
+
+ if v.Kind() == constant.Unknown {
+ // golang/go#60605: treat unknown constant values as if they have invalid type
+ //
+ // This loses some fidelity over the package type-checked from source, but that
+ // is acceptable.
+ //
+ // TODO(rfindley): we should switch on the recorded constant kind rather
+ // than the constant type
+ return
+ }
+
+ switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
+ case types.IsBoolean:
+ w.bool(constant.BoolVal(v))
+ case types.IsInteger:
+ var i big.Int
+ if i64, exact := constant.Int64Val(v); exact {
+ i.SetInt64(i64)
+ } else if ui64, exact := constant.Uint64Val(v); exact {
+ i.SetUint64(ui64)
+ } else {
+ i.SetString(v.ExactString(), 10)
+ }
+ w.mpint(&i, typ)
+ case types.IsFloat:
+ f := constantToFloat(v)
+ w.mpfloat(f, typ)
+ case types.IsComplex:
+ w.mpfloat(constantToFloat(constant.Real(v)), typ)
+ w.mpfloat(constantToFloat(constant.Imag(v)), typ)
+ case types.IsString:
+ w.string(constant.StringVal(v))
+ default:
+ if b.Kind() == types.Invalid {
+ // package contains type errors
+ break
+ }
+ panic(internalErrorf("unexpected type %v (%v)", typ, typ.Underlying()))
+ }
+}
+
+// constantToFloat converts a constant.Value with kind constant.Float to a
+// big.Float.
+func constantToFloat(x constant.Value) *big.Float {
+ x = constant.ToFloat(x)
+ // Use the same floating-point precision (512) as cmd/compile
+ // (see Mpprec in cmd/compile/internal/gc/mpfloat.go).
+ const mpprec = 512
+ var f big.Float
+ f.SetPrec(mpprec)
+ if v, exact := constant.Float64Val(x); exact {
+ // float64
+ f.SetFloat64(v)
+ } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
+ // TODO(gri): add big.Rat accessor to constant.Value.
+ n := valueToRat(num)
+ d := valueToRat(denom)
+ f.SetRat(n.Quo(n, d))
+ } else {
+ // Value too large to represent as a fraction => inaccessible.
+ // TODO(gri): add big.Float accessor to constant.Value.
+ _, ok := f.SetString(x.ExactString())
+ assert(ok)
+ }
+ return &f
+}
+
+func valueToRat(x constant.Value) *big.Rat {
+ // Convert little-endian to big-endian.
+ // I can't believe this is necessary.
+ bytes := constant.Bytes(x)
+ for i := 0; i < len(bytes)/2; i++ {
+ bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i]
+ }
+ return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes))
+}
+
+// mpint exports a multi-precision integer.
+//
+// For unsigned types, small values are written out as a single
+// byte. Larger values are written out as a length-prefixed big-endian
+// byte string, where the length prefix is encoded as its complement.
+// For example, bytes 0, 1, and 2 directly represent the integer
+// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-,
+// 2-, and 3-byte big-endian string follow.
+//
+// Encoding for signed types use the same general approach as for
+// unsigned types, except small values use zig-zag encoding and the
+// bottom bit of length prefix byte for large values is reserved as a
+// sign bit.
+//
+// The exact boundary between small and large encodings varies
+// according to the maximum number of bytes needed to encode a value
+// of type typ. As a special case, 8-bit types are always encoded as a
+// single byte.
+//
+// TODO(mdempsky): Is this level of complexity really worthwhile?
+func (w *exportWriter) mpint(x *big.Int, typ types.Type) {
+ basic, ok := typ.Underlying().(*types.Basic)
+ if !ok {
+ panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying()))
+ }
+
+ signed, maxBytes := intSize(basic)
+
+ negative := x.Sign() < 0
+ if !signed && negative {
+ panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x))
+ }
+
+ b := x.Bytes()
+ if len(b) > 0 && b[0] == 0 {
+ panic(internalErrorf("leading zeros"))
+ }
+ if uint(len(b)) > maxBytes {
+ panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x))
+ }
+
+ maxSmall := 256 - maxBytes
+ if signed {
+ maxSmall = 256 - 2*maxBytes
+ }
+ if maxBytes == 1 {
+ maxSmall = 256
+ }
+
+ // Check if x can use small value encoding.
+ if len(b) <= 1 {
+ var ux uint
+ if len(b) == 1 {
+ ux = uint(b[0])
+ }
+ if signed {
+ ux <<= 1
+ if negative {
+ ux--
+ }
+ }
+ if ux < maxSmall {
+ w.data.WriteByte(byte(ux))
+ return
+ }
+ }
+
+ n := 256 - uint(len(b))
+ if signed {
+ n = 256 - 2*uint(len(b))
+ if negative {
+ n |= 1
+ }
+ }
+ if n < maxSmall || n >= 256 {
+ panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n))
+ }
+
+ w.data.WriteByte(byte(n))
+ w.data.Write(b)
+}
+
+// mpfloat exports a multi-precision floating point number.
+//
+// The number's value is decomposed into mantissa × 2**exponent, where
+// mantissa is an integer. The value is written out as mantissa (as a
+// multi-precision integer) and then the exponent, except exponent is
+// omitted if mantissa is zero.
+func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) {
+ if f.IsInf() {
+ panic("infinite constant")
+ }
+
+ // Break into f = mant × 2**exp, with 0.5 <= mant < 1.
+ var mant big.Float
+ exp := int64(f.MantExp(&mant))
+
+ // Scale so that mant is an integer.
+ prec := mant.MinPrec()
+ mant.SetMantExp(&mant, int(prec))
+ exp -= int64(prec)
+
+ manti, acc := mant.Int(nil)
+ if acc != big.Exact {
+ panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc))
+ }
+ w.mpint(manti, typ)
+ if manti.Sign() != 0 {
+ w.int64(exp)
+ }
+}
+
+func (w *exportWriter) bool(b bool) bool {
+ var x uint64
+ if b {
+ x = 1
+ }
+ w.uint64(x)
+ return b
+}
+
+func (w *exportWriter) int64(x int64) { w.data.int64(x) }
+func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
+func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
+
+func (w *exportWriter) localIdent(obj types.Object) {
+ // Anonymous parameters.
+ if obj == nil {
+ w.string("")
+ return
+ }
+
+ name := obj.Name()
+ if name == "_" {
+ w.string("_")
+ return
+ }
+
+ w.string(name)
+}
+
+type intWriter struct {
+ bytes.Buffer
+}
+
+func (w *intWriter) int64(x int64) {
+ var buf [binary.MaxVarintLen64]byte
+ n := binary.PutVarint(buf[:], x)
+ w.Write(buf[:n])
+}
+
+func (w *intWriter) uint64(x uint64) {
+ var buf [binary.MaxVarintLen64]byte
+ n := binary.PutUvarint(buf[:], x)
+ w.Write(buf[:n])
+}
+
+func assert(cond bool) {
+ if !cond {
+ panic("internal error: assertion failed")
+ }
+}
+
+// The below is copied from go/src/cmd/compile/internal/gc/syntax.go.
+
+// objQueue is a FIFO queue of types.Object. The zero value of objQueue is
+// a ready-to-use empty queue.
+type objQueue struct {
+ ring []types.Object
+ head, tail int
+}
+
+// empty returns true if q contains no Nodes.
+func (q *objQueue) empty() bool {
+ return q.head == q.tail
+}
+
+// pushTail appends n to the tail of the queue.
+func (q *objQueue) pushTail(obj types.Object) {
+ if len(q.ring) == 0 {
+ q.ring = make([]types.Object, 16)
+ } else if q.head+len(q.ring) == q.tail {
+ // Grow the ring.
+ nring := make([]types.Object, len(q.ring)*2)
+ // Copy the old elements.
+ part := q.ring[q.head%len(q.ring):]
+ if q.tail-q.head <= len(part) {
+ part = part[:q.tail-q.head]
+ copy(nring, part)
+ } else {
+ pos := copy(nring, part)
+ copy(nring[pos:], q.ring[:q.tail%len(q.ring)])
+ }
+ q.ring, q.head, q.tail = nring, 0, q.tail-q.head
+ }
+
+ q.ring[q.tail%len(q.ring)] = obj
+ q.tail++
+}
+
+// popHead pops a node from the head of the queue. It panics if q is empty.
+func (q *objQueue) popHead() types.Object {
+ if q.empty() {
+ panic("dequeue empty")
+ }
+ obj := q.ring[q.head%len(q.ring)]
+ q.head++
+ return obj
+}
+
+// internalError represents an error generated inside this package.
+type internalError string
+
+func (e internalError) Error() string { return "gcimporter: " + string(e) }
+
+// TODO(adonovan): make this call panic, so that it's symmetric with errorf.
+// Otherwise it's easy to forget to do anything with the error.
+//
+// TODO(adonovan): also, consider switching the names "errorf" and
+// "internalErrorf" as the former is used for bugs, whose cause is
+// internal inconsistency, whereas the latter is used for ordinary
+// situations like bad input, whose cause is external.
+func internalErrorf(format string, args ...interface{}) error {
+ return internalError(fmt.Sprintf(format, args...))
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go
new file mode 100644
index 00000000..136aa036
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go
@@ -0,0 +1,1100 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Indexed package import.
+// See cmd/compile/internal/gc/iexport.go for the export data format.
+
+// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go.
+
+package gcimporter
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "go/constant"
+ "go/token"
+ "go/types"
+ "io"
+ "math/big"
+ "sort"
+ "strings"
+
+ "golang.org/x/tools/go/types/objectpath"
+ "golang.org/x/tools/internal/aliases"
+ "golang.org/x/tools/internal/typesinternal"
+)
+
+type intReader struct {
+ *bytes.Reader
+ path string
+}
+
+func (r *intReader) int64() int64 {
+ i, err := binary.ReadVarint(r.Reader)
+ if err != nil {
+ errorf("import %q: read varint error: %v", r.path, err)
+ }
+ return i
+}
+
+func (r *intReader) uint64() uint64 {
+ i, err := binary.ReadUvarint(r.Reader)
+ if err != nil {
+ errorf("import %q: read varint error: %v", r.path, err)
+ }
+ return i
+}
+
+// Keep this in sync with constants in iexport.go.
+const (
+ iexportVersionGo1_11 = 0
+ iexportVersionPosCol = 1
+ iexportVersionGo1_18 = 2
+ iexportVersionGenerics = 2
+
+ iexportVersionCurrent = 2
+)
+
+type ident struct {
+ pkg *types.Package
+ name string
+}
+
+const predeclReserved = 32
+
+type itag uint64
+
+const (
+ // Types
+ definedType itag = iota
+ pointerType
+ sliceType
+ arrayType
+ chanType
+ mapType
+ signatureType
+ structType
+ interfaceType
+ typeParamType
+ instanceType
+ unionType
+ aliasType
+)
+
+// Object tags
+const (
+ varTag = 'V'
+ funcTag = 'F'
+ genericFuncTag = 'G'
+ constTag = 'C'
+ aliasTag = 'A'
+ genericAliasTag = 'B'
+ typeParamTag = 'P'
+ typeTag = 'T'
+ genericTypeTag = 'U'
+)
+
+// IImportData imports a package from the serialized package data
+// and returns 0 and a reference to the package.
+// If the export data version is not recognized or the format is otherwise
+// compromised, an error is returned.
+func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
+ pkgs, err := iimportCommon(fset, GetPackagesFromMap(imports), data, false, path, false, nil)
+ if err != nil {
+ return 0, nil, err
+ }
+ return 0, pkgs[0], nil
+}
+
+// IImportBundle imports a set of packages from the serialized package bundle.
+func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
+ return iimportCommon(fset, GetPackagesFromMap(imports), data, true, "", false, nil)
+}
+
+// A GetPackagesFunc function obtains the non-nil symbols for a set of
+// packages, creating and recursively importing them as needed. An
+// implementation should store each package symbol is in the Pkg
+// field of the items array.
+//
+// Any error causes importing to fail. This can be used to quickly read
+// the import manifest of an export data file without fully decoding it.
+type GetPackagesFunc = func(items []GetPackagesItem) error
+
+// A GetPackagesItem is a request from the importer for the package
+// symbol of the specified name and path.
+type GetPackagesItem struct {
+ Name, Path string
+ Pkg *types.Package // to be filled in by GetPackagesFunc call
+
+ // private importer state
+ pathOffset uint64
+ nameIndex map[string]uint64
+}
+
+// GetPackagesFromMap returns a GetPackagesFunc that retrieves
+// packages from the given map of package path to package.
+//
+// The returned function may mutate m: each requested package that is not
+// found is created with types.NewPackage and inserted into m.
+func GetPackagesFromMap(m map[string]*types.Package) GetPackagesFunc {
+ return func(items []GetPackagesItem) error {
+ for i, item := range items {
+ pkg, ok := m[item.Path]
+ if !ok {
+ pkg = types.NewPackage(item.Path, item.Name)
+ m[item.Path] = pkg
+ }
+ items[i].Pkg = pkg
+ }
+ return nil
+ }
+}
+
+func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, bundle bool, path string, shallow bool, reportf ReportFunc) (pkgs []*types.Package, err error) {
+ const currentVersion = iexportVersionCurrent
+ version := int64(-1)
+ if !debug {
+ defer func() {
+ if e := recover(); e != nil {
+ if bundle {
+ err = fmt.Errorf("%v", e)
+ } else if version > currentVersion {
+ err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
+ } else {
+ err = fmt.Errorf("internal error while importing %q (%v); please report an issue", path, e)
+ }
+ }
+ }()
+ }
+
+ r := &intReader{bytes.NewReader(data), path}
+
+ if bundle {
+ if v := r.uint64(); v != bundleVersion {
+ errorf("unknown bundle format version %d", v)
+ }
+ }
+
+ version = int64(r.uint64())
+ switch version {
+ case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
+ default:
+ if version > iexportVersionGo1_18 {
+ errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
+ } else {
+ errorf("unknown iexport format version %d", version)
+ }
+ }
+
+ sLen := int64(r.uint64())
+ var fLen int64
+ var fileOffset []uint64
+ if shallow {
+ // Shallow mode uses a different position encoding.
+ fLen = int64(r.uint64())
+ fileOffset = make([]uint64, r.uint64())
+ for i := range fileOffset {
+ fileOffset[i] = r.uint64()
+ }
+ }
+ dLen := int64(r.uint64())
+
+ whence, _ := r.Seek(0, io.SeekCurrent)
+ stringData := data[whence : whence+sLen]
+ fileData := data[whence+sLen : whence+sLen+fLen]
+ declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen]
+ r.Seek(sLen+fLen+dLen, io.SeekCurrent)
+
+ p := iimporter{
+ version: int(version),
+ ipath: path,
+ aliases: aliases.Enabled(),
+ shallow: shallow,
+ reportf: reportf,
+
+ stringData: stringData,
+ stringCache: make(map[uint64]string),
+ fileOffset: fileOffset,
+ fileData: fileData,
+ fileCache: make([]*token.File, len(fileOffset)),
+ pkgCache: make(map[uint64]*types.Package),
+
+ declData: declData,
+ pkgIndex: make(map[*types.Package]map[string]uint64),
+ typCache: make(map[uint64]types.Type),
+ // Separate map for typeparams, keyed by their package and unique
+ // name.
+ tparamIndex: make(map[ident]types.Type),
+
+ fake: fakeFileSet{
+ fset: fset,
+ files: make(map[string]*fileInfo),
+ },
+ }
+ defer p.fake.setLines() // set lines for files in fset
+
+ for i, pt := range predeclared() {
+ p.typCache[uint64(i)] = pt
+ }
+
+ // Gather the relevant packages from the manifest.
+ items := make([]GetPackagesItem, r.uint64())
+ uniquePkgPaths := make(map[string]bool)
+ for i := range items {
+ pkgPathOff := r.uint64()
+ pkgPath := p.stringAt(pkgPathOff)
+ pkgName := p.stringAt(r.uint64())
+ _ = r.uint64() // package height; unused by go/types
+
+ if pkgPath == "" {
+ pkgPath = path
+ }
+ items[i].Name = pkgName
+ items[i].Path = pkgPath
+ items[i].pathOffset = pkgPathOff
+
+ // Read index for package.
+ nameIndex := make(map[string]uint64)
+ nSyms := r.uint64()
+ // In shallow mode, only the current package (i=0) has an index.
+ assert(!(shallow && i > 0 && nSyms != 0))
+ for ; nSyms > 0; nSyms-- {
+ name := p.stringAt(r.uint64())
+ nameIndex[name] = r.uint64()
+ }
+
+ items[i].nameIndex = nameIndex
+
+ uniquePkgPaths[pkgPath] = true
+ }
+ // Debugging #63822; hypothesis: there are duplicate PkgPaths.
+ if len(uniquePkgPaths) != len(items) {
+ reportf("found duplicate PkgPaths while reading export data manifest: %v", items)
+ }
+
+ // Request packages all at once from the client,
+ // enabling a parallel implementation.
+ if err := getPackages(items); err != nil {
+ return nil, err // don't wrap this error
+ }
+
+ // Check the results and complete the index.
+ pkgList := make([]*types.Package, len(items))
+ for i, item := range items {
+ pkg := item.Pkg
+ if pkg == nil {
+ errorf("internal error: getPackages returned nil package for %q", item.Path)
+ } else if pkg.Path() != item.Path {
+ errorf("internal error: getPackages returned wrong path %q, want %q", pkg.Path(), item.Path)
+ } else if pkg.Name() != item.Name {
+ errorf("internal error: getPackages returned wrong name %s for package %q, want %s", pkg.Name(), item.Path, item.Name)
+ }
+ p.pkgCache[item.pathOffset] = pkg
+ p.pkgIndex[pkg] = item.nameIndex
+ pkgList[i] = pkg
+ }
+
+ if bundle {
+ pkgs = make([]*types.Package, r.uint64())
+ for i := range pkgs {
+ pkg := p.pkgAt(r.uint64())
+ imps := make([]*types.Package, r.uint64())
+ for j := range imps {
+ imps[j] = p.pkgAt(r.uint64())
+ }
+ pkg.SetImports(imps)
+ pkgs[i] = pkg
+ }
+ } else {
+ if len(pkgList) == 0 {
+ errorf("no packages found for %s", path)
+ panic("unreachable")
+ }
+ pkgs = pkgList[:1]
+
+ // record all referenced packages as imports
+ list := append(([]*types.Package)(nil), pkgList[1:]...)
+ sort.Sort(byPath(list))
+ pkgs[0].SetImports(list)
+ }
+
+ for _, pkg := range pkgs {
+ if pkg.Complete() {
+ continue
+ }
+
+ names := make([]string, 0, len(p.pkgIndex[pkg]))
+ for name := range p.pkgIndex[pkg] {
+ names = append(names, name)
+ }
+ sort.Strings(names)
+ for _, name := range names {
+ p.doDecl(pkg, name)
+ }
+
+ // package was imported completely and without errors
+ pkg.MarkComplete()
+ }
+
+ // SetConstraint can't be called if the constraint type is not yet complete.
+ // When type params are created in the typeParamTag case of (*importReader).obj(),
+ // the associated constraint type may not be complete due to recursion.
+ // Therefore, we defer calling SetConstraint there, and call it here instead
+ // after all types are complete.
+ for _, d := range p.later {
+ d.t.SetConstraint(d.constraint)
+ }
+
+ for _, typ := range p.interfaceList {
+ typ.Complete()
+ }
+
+ // Workaround for golang/go#61561. See the doc for instanceList for details.
+ for _, typ := range p.instanceList {
+ if iface, _ := typ.Underlying().(*types.Interface); iface != nil {
+ iface.Complete()
+ }
+ }
+
+ return pkgs, nil
+}
+
+type setConstraintArgs struct {
+ t *types.TypeParam
+ constraint types.Type
+}
+
+type iimporter struct {
+ version int
+ ipath string
+
+ aliases bool
+ shallow bool
+ reportf ReportFunc // if non-nil, used to report bugs
+
+ stringData []byte
+ stringCache map[uint64]string
+ fileOffset []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i
+ fileData []byte
+ fileCache []*token.File // memoized decoding of file encoded as i
+ pkgCache map[uint64]*types.Package
+
+ declData []byte
+ pkgIndex map[*types.Package]map[string]uint64
+ typCache map[uint64]types.Type
+ tparamIndex map[ident]types.Type
+
+ fake fakeFileSet
+ interfaceList []*types.Interface
+
+ // Workaround for the go/types bug golang/go#61561: instances produced during
+ // instantiation may contain incomplete interfaces. Here we only complete the
+ // underlying type of the instance, which is the most common case but doesn't
+ // handle parameterized interface literals defined deeper in the type.
+ instanceList []types.Type // instances for later completion (see golang/go#61561)
+
+ // Arguments for calls to SetConstraint that are deferred due to recursive types
+ later []setConstraintArgs
+
+ indent int // for tracing support
+}
+
+func (p *iimporter) trace(format string, args ...interface{}) {
+ if !trace {
+ // Call sites should also be guarded, but having this check here allows
+ // easily enabling/disabling debug trace statements.
+ return
+ }
+ fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
+}
+
+func (p *iimporter) doDecl(pkg *types.Package, name string) {
+ if debug {
+ p.trace("import decl %s", name)
+ p.indent++
+ defer func() {
+ p.indent--
+ p.trace("=> %s", name)
+ }()
+ }
+ // See if we've already imported this declaration.
+ if obj := pkg.Scope().Lookup(name); obj != nil {
+ return
+ }
+
+ off, ok := p.pkgIndex[pkg][name]
+ if !ok {
+ // In deep mode, the index should be complete. In shallow
+ // mode, we should have already recursively loaded necessary
+ // dependencies so the above Lookup succeeds.
+ errorf("%v.%v not in index", pkg, name)
+ }
+
+ r := &importReader{p: p, currPkg: pkg}
+ r.declReader.Reset(p.declData[off:])
+
+ r.obj(name)
+}
+
+func (p *iimporter) stringAt(off uint64) string {
+ if s, ok := p.stringCache[off]; ok {
+ return s
+ }
+
+ slen, n := binary.Uvarint(p.stringData[off:])
+ if n <= 0 {
+ errorf("varint failed")
+ }
+ spos := off + uint64(n)
+ s := string(p.stringData[spos : spos+slen])
+ p.stringCache[off] = s
+ return s
+}
+
+func (p *iimporter) fileAt(index uint64) *token.File {
+ file := p.fileCache[index]
+ if file == nil {
+ off := p.fileOffset[index]
+ file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath})
+ p.fileCache[index] = file
+ }
+ return file
+}
+
+func (p *iimporter) decodeFile(rd intReader) *token.File {
+ filename := p.stringAt(rd.uint64())
+ size := int(rd.uint64())
+ file := p.fake.fset.AddFile(filename, -1, size)
+
+ // SetLines requires a nondecreasing sequence.
+ // Because it is common for clients to derive the interval
+ // [start, start+len(name)] from a start position, and we
+ // want to ensure that the end offset is on the same line,
+ // we fill in the gaps of the sparse encoding with values
+ // that strictly increase by the largest possible amount.
+ // This allows us to avoid having to record the actual end
+ // offset of each needed line.
+
+ lines := make([]int, int(rd.uint64()))
+ var index, offset int
+ for i, n := 0, int(rd.uint64()); i < n; i++ {
+ index += int(rd.uint64())
+ offset += int(rd.uint64())
+ lines[index] = offset
+
+ // Ensure monotonicity between points.
+ for j := index - 1; j > 0 && lines[j] == 0; j-- {
+ lines[j] = lines[j+1] - 1
+ }
+ }
+
+ // Ensure monotonicity after last point.
+ for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- {
+ size--
+ lines[j] = size
+ }
+
+ if !file.SetLines(lines) {
+ errorf("SetLines failed: %d", lines) // can't happen
+ }
+ return file
+}
+
+func (p *iimporter) pkgAt(off uint64) *types.Package {
+ if pkg, ok := p.pkgCache[off]; ok {
+ return pkg
+ }
+ path := p.stringAt(off)
+ errorf("missing package %q in %q", path, p.ipath)
+ return nil
+}
+
+func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
+ if t, ok := p.typCache[off]; ok && canReuse(base, t) {
+ return t
+ }
+
+ if off < predeclReserved {
+ errorf("predeclared type missing from cache: %v", off)
+ }
+
+ r := &importReader{p: p}
+ r.declReader.Reset(p.declData[off-predeclReserved:])
+ t := r.doType(base)
+
+ if canReuse(base, t) {
+ p.typCache[off] = t
+ }
+ return t
+}
+
+// canReuse reports whether the type rhs on the RHS of the declaration for def
+// may be re-used.
+//
+// Specifically, if def is non-nil and rhs is an interface type with methods, it
+// may not be re-used because we have a convention of setting the receiver type
+// for interface methods to def.
+func canReuse(def *types.Named, rhs types.Type) bool {
+ if def == nil {
+ return true
+ }
+ iface, _ := aliases.Unalias(rhs).(*types.Interface)
+ if iface == nil {
+ return true
+ }
+ // Don't use iface.Empty() here as iface may not be complete.
+ return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0
+}
+
+type importReader struct {
+ p *iimporter
+ declReader bytes.Reader
+ currPkg *types.Package
+ prevFile string
+ prevLine int64
+ prevColumn int64
+}
+
+func (r *importReader) obj(name string) {
+ tag := r.byte()
+ pos := r.pos()
+
+ switch tag {
+ case aliasTag:
+ typ := r.typ()
+ // TODO(adonovan): support generic aliases:
+ // if tag == genericAliasTag {
+ // tparams := r.tparamList()
+ // alias.SetTypeParams(tparams)
+ // }
+ r.declare(aliases.NewAlias(r.p.aliases, pos, r.currPkg, name, typ))
+
+ case constTag:
+ typ, val := r.value()
+
+ r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
+
+ case funcTag, genericFuncTag:
+ var tparams []*types.TypeParam
+ if tag == genericFuncTag {
+ tparams = r.tparamList()
+ }
+ sig := r.signature(nil, nil, tparams)
+ r.declare(types.NewFunc(pos, r.currPkg, name, sig))
+
+ case typeTag, genericTypeTag:
+ // Types can be recursive. We need to setup a stub
+ // declaration before recursing.
+ obj := types.NewTypeName(pos, r.currPkg, name, nil)
+ named := types.NewNamed(obj, nil, nil)
+ // Declare obj before calling r.tparamList, so the new type name is recognized
+ // if used in the constraint of one of its own typeparams (see #48280).
+ r.declare(obj)
+ if tag == genericTypeTag {
+ tparams := r.tparamList()
+ named.SetTypeParams(tparams)
+ }
+
+ underlying := r.p.typAt(r.uint64(), named).Underlying()
+ named.SetUnderlying(underlying)
+
+ if !isInterface(underlying) {
+ for n := r.uint64(); n > 0; n-- {
+ mpos := r.pos()
+ mname := r.ident()
+ recv := r.param()
+
+ // If the receiver has any targs, set those as the
+ // rparams of the method (since those are the
+ // typeparams being used in the method sig/body).
+ _, recvNamed := typesinternal.ReceiverNamed(recv)
+ targs := recvNamed.TypeArgs()
+ var rparams []*types.TypeParam
+ if targs.Len() > 0 {
+ rparams = make([]*types.TypeParam, targs.Len())
+ for i := range rparams {
+ rparams[i] = aliases.Unalias(targs.At(i)).(*types.TypeParam)
+ }
+ }
+ msig := r.signature(recv, rparams, nil)
+
+ named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
+ }
+ }
+
+ case typeParamTag:
+ // We need to "declare" a typeparam in order to have a name that
+ // can be referenced recursively (if needed) in the type param's
+ // bound.
+ if r.p.version < iexportVersionGenerics {
+ errorf("unexpected type param type")
+ }
+ name0 := tparamName(name)
+ tn := types.NewTypeName(pos, r.currPkg, name0, nil)
+ t := types.NewTypeParam(tn, nil)
+
+ // To handle recursive references to the typeparam within its
+ // bound, save the partial type in tparamIndex before reading the bounds.
+ id := ident{r.currPkg, name}
+ r.p.tparamIndex[id] = t
+ var implicit bool
+ if r.p.version >= iexportVersionGo1_18 {
+ implicit = r.bool()
+ }
+ constraint := r.typ()
+ if implicit {
+ iface, _ := aliases.Unalias(constraint).(*types.Interface)
+ if iface == nil {
+ errorf("non-interface constraint marked implicit")
+ }
+ iface.MarkImplicit()
+ }
+ // The constraint type may not be complete, if we
+ // are in the middle of a type recursion involving type
+ // constraints. So, we defer SetConstraint until we have
+ // completely set up all types in ImportData.
+ r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint})
+
+ case varTag:
+ typ := r.typ()
+
+ r.declare(types.NewVar(pos, r.currPkg, name, typ))
+
+ default:
+ errorf("unexpected tag: %v", tag)
+ }
+}
+
+func (r *importReader) declare(obj types.Object) {
+ obj.Pkg().Scope().Insert(obj)
+}
+
+func (r *importReader) value() (typ types.Type, val constant.Value) {
+ typ = r.typ()
+ if r.p.version >= iexportVersionGo1_18 {
+ // TODO: add support for using the kind.
+ _ = constant.Kind(r.int64())
+ }
+
+ switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
+ case types.IsBoolean:
+ val = constant.MakeBool(r.bool())
+
+ case types.IsString:
+ val = constant.MakeString(r.string())
+
+ case types.IsInteger:
+ var x big.Int
+ r.mpint(&x, b)
+ val = constant.Make(&x)
+
+ case types.IsFloat:
+ val = r.mpfloat(b)
+
+ case types.IsComplex:
+ re := r.mpfloat(b)
+ im := r.mpfloat(b)
+ val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+
+ default:
+ if b.Kind() == types.Invalid {
+ val = constant.MakeUnknown()
+ return
+ }
+ errorf("unexpected type %v", typ) // panics
+ panic("unreachable")
+ }
+
+ return
+}
+
+func intSize(b *types.Basic) (signed bool, maxBytes uint) {
+ if (b.Info() & types.IsUntyped) != 0 {
+ return true, 64
+ }
+
+ switch b.Kind() {
+ case types.Float32, types.Complex64:
+ return true, 3
+ case types.Float64, types.Complex128:
+ return true, 7
+ }
+
+ signed = (b.Info() & types.IsUnsigned) == 0
+ switch b.Kind() {
+ case types.Int8, types.Uint8:
+ maxBytes = 1
+ case types.Int16, types.Uint16:
+ maxBytes = 2
+ case types.Int32, types.Uint32:
+ maxBytes = 4
+ default:
+ maxBytes = 8
+ }
+
+ return
+}
+
+func (r *importReader) mpint(x *big.Int, typ *types.Basic) {
+ signed, maxBytes := intSize(typ)
+
+ maxSmall := 256 - maxBytes
+ if signed {
+ maxSmall = 256 - 2*maxBytes
+ }
+ if maxBytes == 1 {
+ maxSmall = 256
+ }
+
+ n, _ := r.declReader.ReadByte()
+ if uint(n) < maxSmall {
+ v := int64(n)
+ if signed {
+ v >>= 1
+ if n&1 != 0 {
+ v = ^v
+ }
+ }
+ x.SetInt64(v)
+ return
+ }
+
+ v := -n
+ if signed {
+ v = -(n &^ 1) >> 1
+ }
+ if v < 1 || uint(v) > maxBytes {
+ errorf("weird decoding: %v, %v => %v", n, signed, v)
+ }
+ b := make([]byte, v)
+ io.ReadFull(&r.declReader, b)
+ x.SetBytes(b)
+ if signed && n&1 != 0 {
+ x.Neg(x)
+ }
+}
+
+func (r *importReader) mpfloat(typ *types.Basic) constant.Value {
+ var mant big.Int
+ r.mpint(&mant, typ)
+ var f big.Float
+ f.SetInt(&mant)
+ if f.Sign() != 0 {
+ f.SetMantExp(&f, int(r.int64()))
+ }
+ return constant.Make(&f)
+}
+
+func (r *importReader) ident() string {
+ return r.string()
+}
+
+func (r *importReader) qualifiedIdent() (*types.Package, string) {
+ name := r.string()
+ pkg := r.pkg()
+ return pkg, name
+}
+
+func (r *importReader) pos() token.Pos {
+ if r.p.shallow {
+ // precise offsets are encoded only in shallow mode
+ return r.posv2()
+ }
+ if r.p.version >= iexportVersionPosCol {
+ r.posv1()
+ } else {
+ r.posv0()
+ }
+
+ if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
+ return token.NoPos
+ }
+ return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn))
+}
+
+func (r *importReader) posv0() {
+ delta := r.int64()
+ if delta != deltaNewFile {
+ r.prevLine += delta
+ } else if l := r.int64(); l == -1 {
+ r.prevLine += deltaNewFile
+ } else {
+ r.prevFile = r.string()
+ r.prevLine = l
+ }
+}
+
+func (r *importReader) posv1() {
+ delta := r.int64()
+ r.prevColumn += delta >> 1
+ if delta&1 != 0 {
+ delta = r.int64()
+ r.prevLine += delta >> 1
+ if delta&1 != 0 {
+ r.prevFile = r.string()
+ }
+ }
+}
+
+func (r *importReader) posv2() token.Pos {
+ file := r.uint64()
+ if file == 0 {
+ return token.NoPos
+ }
+ tf := r.p.fileAt(file - 1)
+ return tf.Pos(int(r.uint64()))
+}
+
+func (r *importReader) typ() types.Type {
+ return r.p.typAt(r.uint64(), nil)
+}
+
+func isInterface(t types.Type) bool {
+ _, ok := aliases.Unalias(t).(*types.Interface)
+ return ok
+}
+
+func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
+func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
+
+func (r *importReader) doType(base *types.Named) (res types.Type) {
+ k := r.kind()
+ if debug {
+ r.p.trace("importing type %d (base: %s)", k, base)
+ r.p.indent++
+ defer func() {
+ r.p.indent--
+ r.p.trace("=> %s", res)
+ }()
+ }
+ switch k {
+ default:
+ errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
+ return nil
+
+ case aliasType, definedType:
+ pkg, name := r.qualifiedIdent()
+ r.p.doDecl(pkg, name)
+ return pkg.Scope().Lookup(name).(*types.TypeName).Type()
+ case pointerType:
+ return types.NewPointer(r.typ())
+ case sliceType:
+ return types.NewSlice(r.typ())
+ case arrayType:
+ n := r.uint64()
+ return types.NewArray(r.typ(), int64(n))
+ case chanType:
+ dir := chanDir(int(r.uint64()))
+ return types.NewChan(dir, r.typ())
+ case mapType:
+ return types.NewMap(r.typ(), r.typ())
+ case signatureType:
+ r.currPkg = r.pkg()
+ return r.signature(nil, nil, nil)
+
+ case structType:
+ r.currPkg = r.pkg()
+
+ fields := make([]*types.Var, r.uint64())
+ tags := make([]string, len(fields))
+ for i := range fields {
+ var field *types.Var
+ if r.p.shallow {
+ field, _ = r.objectPathObject().(*types.Var)
+ }
+
+ fpos := r.pos()
+ fname := r.ident()
+ ftyp := r.typ()
+ emb := r.bool()
+ tag := r.string()
+
+ // Either this is not a shallow import, the field is local, or the
+ // encoded objectPath failed to produce an object (a bug).
+ //
+ // Even in this last, buggy case, fall back on creating a new field. As
+ // discussed in iexport.go, this is not correct, but mostly works and is
+ // preferable to failing (for now at least).
+ if field == nil {
+ field = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
+ }
+
+ fields[i] = field
+ tags[i] = tag
+ }
+ return types.NewStruct(fields, tags)
+
+ case interfaceType:
+ r.currPkg = r.pkg()
+
+ embeddeds := make([]types.Type, r.uint64())
+ for i := range embeddeds {
+ _ = r.pos()
+ embeddeds[i] = r.typ()
+ }
+
+ methods := make([]*types.Func, r.uint64())
+ for i := range methods {
+ var method *types.Func
+ if r.p.shallow {
+ method, _ = r.objectPathObject().(*types.Func)
+ }
+
+ mpos := r.pos()
+ mname := r.ident()
+
+ // TODO(mdempsky): Matches bimport.go, but I
+ // don't agree with this.
+ var recv *types.Var
+ if base != nil {
+ recv = types.NewVar(token.NoPos, r.currPkg, "", base)
+ }
+ msig := r.signature(recv, nil, nil)
+
+ if method == nil {
+ method = types.NewFunc(mpos, r.currPkg, mname, msig)
+ }
+ methods[i] = method
+ }
+
+ typ := newInterface(methods, embeddeds)
+ r.p.interfaceList = append(r.p.interfaceList, typ)
+ return typ
+
+ case typeParamType:
+ if r.p.version < iexportVersionGenerics {
+ errorf("unexpected type param type")
+ }
+ pkg, name := r.qualifiedIdent()
+ id := ident{pkg, name}
+ if t, ok := r.p.tparamIndex[id]; ok {
+ // We're already in the process of importing this typeparam.
+ return t
+ }
+ // Otherwise, import the definition of the typeparam now.
+ r.p.doDecl(pkg, name)
+ return r.p.tparamIndex[id]
+
+ case instanceType:
+ if r.p.version < iexportVersionGenerics {
+ errorf("unexpected instantiation type")
+ }
+ // pos does not matter for instances: they are positioned on the original
+ // type.
+ _ = r.pos()
+ len := r.uint64()
+ targs := make([]types.Type, len)
+ for i := range targs {
+ targs[i] = r.typ()
+ }
+ baseType := r.typ()
+ // The imported instantiated type doesn't include any methods, so
+ // we must always use the methods of the base (orig) type.
+ // TODO provide a non-nil *Environment
+ t, _ := types.Instantiate(nil, baseType, targs, false)
+
+ // Workaround for golang/go#61561. See the doc for instanceList for details.
+ r.p.instanceList = append(r.p.instanceList, t)
+ return t
+
+ case unionType:
+ if r.p.version < iexportVersionGenerics {
+ errorf("unexpected instantiation type")
+ }
+ terms := make([]*types.Term, r.uint64())
+ for i := range terms {
+ terms[i] = types.NewTerm(r.bool(), r.typ())
+ }
+ return types.NewUnion(terms)
+ }
+}
+
+func (r *importReader) kind() itag {
+ return itag(r.uint64())
+}
+
+// objectPathObject is the inverse of exportWriter.objectPath.
+//
+// In shallow mode, certain fields and methods may need to be looked up in an
+// imported package. See the doc for exportWriter.objectPath for a full
+// explanation.
+func (r *importReader) objectPathObject() types.Object {
+ objPath := objectpath.Path(r.string())
+ if objPath == "" {
+ return nil
+ }
+ pkg := r.pkg()
+ obj, err := objectpath.Object(pkg, objPath)
+ if err != nil {
+ if r.p.reportf != nil {
+ r.p.reportf("failed to find object for objectPath %q: %v", objPath, err)
+ }
+ }
+ return obj
+}
+
+func (r *importReader) signature(recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature {
+ params := r.paramList()
+ results := r.paramList()
+ variadic := params.Len() > 0 && r.bool()
+ return types.NewSignatureType(recv, rparams, tparams, params, results, variadic)
+}
+
+func (r *importReader) tparamList() []*types.TypeParam {
+ n := r.uint64()
+ if n == 0 {
+ return nil
+ }
+ xs := make([]*types.TypeParam, n)
+ for i := range xs {
+ // Note: the standard library importer is tolerant of nil types here,
+ // though would panic in SetTypeParams.
+ xs[i] = aliases.Unalias(r.typ()).(*types.TypeParam)
+ }
+ return xs
+}
+
+func (r *importReader) paramList() *types.Tuple {
+ xs := make([]*types.Var, r.uint64())
+ for i := range xs {
+ xs[i] = r.param()
+ }
+ return types.NewTuple(xs...)
+}
+
+func (r *importReader) param() *types.Var {
+ pos := r.pos()
+ name := r.ident()
+ typ := r.typ()
+ return types.NewParam(pos, r.currPkg, name, typ)
+}
+
+func (r *importReader) bool() bool {
+ return r.uint64() != 0
+}
+
+func (r *importReader) int64() int64 {
+ n, err := binary.ReadVarint(&r.declReader)
+ if err != nil {
+ errorf("readVarint: %v", err)
+ }
+ return n
+}
+
+func (r *importReader) uint64() uint64 {
+ n, err := binary.ReadUvarint(&r.declReader)
+ if err != nil {
+ errorf("readUvarint: %v", err)
+ }
+ return n
+}
+
+func (r *importReader) byte() byte {
+ x, err := r.declReader.ReadByte()
+ if err != nil {
+ errorf("declReader.ReadByte: %v", err)
+ }
+ return x
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go b/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go
new file mode 100644
index 00000000..8b163e3d
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go
@@ -0,0 +1,22 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.11
+// +build !go1.11
+
+package gcimporter
+
+import "go/types"
+
+func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
+ named := make([]*types.Named, len(embeddeds))
+ for i, e := range embeddeds {
+ var ok bool
+ named[i], ok = e.(*types.Named)
+ if !ok {
+ panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11")
+ }
+ }
+ return types.NewInterface(methods, named)
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go b/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go
new file mode 100644
index 00000000..49984f40
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go
@@ -0,0 +1,14 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.11
+// +build go1.11
+
+package gcimporter
+
+import "go/types"
+
+func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
+ return types.NewInterfaceType(methods, embeddeds)
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go b/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go
new file mode 100644
index 00000000..0cd3b91b
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go
@@ -0,0 +1,34 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gcimporter
+
+import "go/types"
+
+const iexportVersion = iexportVersionGenerics
+
+// additionalPredeclared returns additional predeclared types in go.1.18.
+func additionalPredeclared() []types.Type {
+ return []types.Type{
+ // comparable
+ types.Universe.Lookup("comparable").Type(),
+
+ // any
+ types.Universe.Lookup("any").Type(),
+ }
+}
+
+// See cmd/compile/internal/types.SplitVargenSuffix.
+func splitVargenSuffix(name string) (base, suffix string) {
+ i := len(name)
+ for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
+ i--
+ }
+ const dot = "·"
+ if i >= len(dot) && name[i-len(dot):i] == dot {
+ i -= len(dot)
+ return name[:i], name[i:]
+ }
+ return name, ""
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go
new file mode 100644
index 00000000..38b624ca
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !goexperiment.unified
+// +build !goexperiment.unified
+
+package gcimporter
+
+const unifiedIR = false
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go
new file mode 100644
index 00000000..b5118d0b
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.unified
+// +build goexperiment.unified
+
+package gcimporter
+
+const unifiedIR = true
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
new file mode 100644
index 00000000..2c077068
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
@@ -0,0 +1,728 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Derived from go/internal/gcimporter/ureader.go
+
+package gcimporter
+
+import (
+ "fmt"
+ "go/token"
+ "go/types"
+ "sort"
+ "strings"
+
+ "golang.org/x/tools/internal/aliases"
+ "golang.org/x/tools/internal/pkgbits"
+)
+
+// A pkgReader holds the shared state for reading a unified IR package
+// description.
+type pkgReader struct {
+ pkgbits.PkgDecoder
+
+ fake fakeFileSet
+
+ ctxt *types.Context
+ imports map[string]*types.Package // previously imported packages, indexed by path
+ aliases bool // create types.Alias nodes
+
+ // lazily initialized arrays corresponding to the unified IR
+ // PosBase, Pkg, and Type sections, respectively.
+ posBases []string // position bases (i.e., file names)
+ pkgs []*types.Package
+ typs []types.Type
+
+ // laterFns holds functions that need to be invoked at the end of
+ // import reading.
+ laterFns []func()
+ // laterFors is used in case of 'type A B' to ensure that B is processed before A.
+ laterFors map[types.Type]int
+
+ // ifaces holds a list of constructed Interfaces, which need to have
+ // Complete called after importing is done.
+ ifaces []*types.Interface
+}
+
+// later adds a function to be invoked at the end of import reading.
+func (pr *pkgReader) later(fn func()) {
+ pr.laterFns = append(pr.laterFns, fn)
+}
+
+// See cmd/compile/internal/noder.derivedInfo.
+type derivedInfo struct {
+ idx pkgbits.Index
+ needed bool
+}
+
+// See cmd/compile/internal/noder.typeInfo.
+type typeInfo struct {
+ idx pkgbits.Index
+ derived bool
+}
+
+func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
+ if !debug {
+ defer func() {
+ if x := recover(); x != nil {
+ err = fmt.Errorf("internal error in importing %q (%v); please report an issue", path, x)
+ }
+ }()
+ }
+
+ s := string(data)
+ s = s[:strings.LastIndex(s, "\n$$\n")]
+ input := pkgbits.NewPkgDecoder(path, s)
+ pkg = readUnifiedPackage(fset, nil, imports, input)
+ return
+}
+
+// laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing.
+func (pr *pkgReader) laterFor(t types.Type, fn func()) {
+ if pr.laterFors == nil {
+ pr.laterFors = make(map[types.Type]int)
+ }
+ pr.laterFors[t] = len(pr.laterFns)
+ pr.laterFns = append(pr.laterFns, fn)
+}
+
+// readUnifiedPackage reads a package description from the given
+// unified IR export data decoder.
+func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package {
+ pr := pkgReader{
+ PkgDecoder: input,
+
+ fake: fakeFileSet{
+ fset: fset,
+ files: make(map[string]*fileInfo),
+ },
+
+ ctxt: ctxt,
+ imports: imports,
+ aliases: aliases.Enabled(),
+
+ posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)),
+ pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)),
+ typs: make([]types.Type, input.NumElems(pkgbits.RelocType)),
+ }
+ defer pr.fake.setLines()
+
+ r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
+ pkg := r.pkg()
+ r.Bool() // has init
+
+ for i, n := 0, r.Len(); i < n; i++ {
+ // As if r.obj(), but avoiding the Scope.Lookup call,
+ // to avoid eager loading of imports.
+ r.Sync(pkgbits.SyncObject)
+ assert(!r.Bool())
+ r.p.objIdx(r.Reloc(pkgbits.RelocObj))
+ assert(r.Len() == 0)
+ }
+
+ r.Sync(pkgbits.SyncEOF)
+
+ for _, fn := range pr.laterFns {
+ fn()
+ }
+
+ for _, iface := range pr.ifaces {
+ iface.Complete()
+ }
+
+ // Imports() of pkg are all of the transitive packages that were loaded.
+ var imps []*types.Package
+ for _, imp := range pr.pkgs {
+ if imp != nil && imp != pkg {
+ imps = append(imps, imp)
+ }
+ }
+ sort.Sort(byPath(imps))
+ pkg.SetImports(imps)
+
+ pkg.MarkComplete()
+ return pkg
+}
+
+// A reader holds the state for reading a single unified IR element
+// within a package.
+type reader struct {
+ pkgbits.Decoder
+
+ p *pkgReader
+
+ dict *readerDict
+}
+
+// A readerDict holds the state for type parameters that parameterize
+// the current unified IR element.
+type readerDict struct {
+ // bounds is a slice of typeInfos corresponding to the underlying
+ // bounds of the element's type parameters.
+ bounds []typeInfo
+
+ // tparams is a slice of the constructed TypeParams for the element.
+ tparams []*types.TypeParam
+
+ // devived is a slice of types derived from tparams, which may be
+ // instantiated while reading the current element.
+ derived []derivedInfo
+ derivedTypes []types.Type // lazily instantiated from derived
+}
+
+func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
+ return &reader{
+ Decoder: pr.NewDecoder(k, idx, marker),
+ p: pr,
+ }
+}
+
+func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
+ return &reader{
+ Decoder: pr.TempDecoder(k, idx, marker),
+ p: pr,
+ }
+}
+
+func (pr *pkgReader) retireReader(r *reader) {
+ pr.RetireDecoder(&r.Decoder)
+}
+
+// @@@ Positions
+
+func (r *reader) pos() token.Pos {
+ r.Sync(pkgbits.SyncPos)
+ if !r.Bool() {
+ return token.NoPos
+ }
+
+ // TODO(mdempsky): Delta encoding.
+ posBase := r.posBase()
+ line := r.Uint()
+ col := r.Uint()
+ return r.p.fake.pos(posBase, int(line), int(col))
+}
+
+func (r *reader) posBase() string {
+ return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase))
+}
+
+func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
+ if b := pr.posBases[idx]; b != "" {
+ return b
+ }
+
+ var filename string
+ {
+ r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
+
+ // Within types2, position bases have a lot more details (e.g.,
+ // keeping track of where //line directives appeared exactly).
+ //
+ // For go/types, we just track the file name.
+
+ filename = r.String()
+
+ if r.Bool() { // file base
+ // Was: "b = token.NewTrimmedFileBase(filename, true)"
+ } else { // line base
+ pos := r.pos()
+ line := r.Uint()
+ col := r.Uint()
+
+ // Was: "b = token.NewLineBase(pos, filename, true, line, col)"
+ _, _, _ = pos, line, col
+ }
+ pr.retireReader(r)
+ }
+ b := filename
+ pr.posBases[idx] = b
+ return b
+}
+
+// @@@ Packages
+
+func (r *reader) pkg() *types.Package {
+ r.Sync(pkgbits.SyncPkg)
+ return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
+}
+
+func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package {
+ // TODO(mdempsky): Consider using some non-nil pointer to indicate
+ // the universe scope, so we don't need to keep re-reading it.
+ if pkg := pr.pkgs[idx]; pkg != nil {
+ return pkg
+ }
+
+ pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg()
+ pr.pkgs[idx] = pkg
+ return pkg
+}
+
+func (r *reader) doPkg() *types.Package {
+ path := r.String()
+ switch path {
+ case "":
+ path = r.p.PkgPath()
+ case "builtin":
+ return nil // universe
+ case "unsafe":
+ return types.Unsafe
+ }
+
+ if pkg := r.p.imports[path]; pkg != nil {
+ return pkg
+ }
+
+ name := r.String()
+
+ pkg := types.NewPackage(path, name)
+ r.p.imports[path] = pkg
+
+ return pkg
+}
+
+// @@@ Types
+
+func (r *reader) typ() types.Type {
+ return r.p.typIdx(r.typInfo(), r.dict)
+}
+
+func (r *reader) typInfo() typeInfo {
+ r.Sync(pkgbits.SyncType)
+ if r.Bool() {
+ return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
+ }
+ return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
+}
+
+func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type {
+ idx := info.idx
+ var where *types.Type
+ if info.derived {
+ where = &dict.derivedTypes[idx]
+ idx = dict.derived[idx].idx
+ } else {
+ where = &pr.typs[idx]
+ }
+
+ if typ := *where; typ != nil {
+ return typ
+ }
+
+ var typ types.Type
+ {
+ r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
+ r.dict = dict
+
+ typ = r.doTyp()
+ assert(typ != nil)
+ pr.retireReader(r)
+ }
+ // See comment in pkgReader.typIdx explaining how this happens.
+ if prev := *where; prev != nil {
+ return prev
+ }
+
+ *where = typ
+ return typ
+}
+
+func (r *reader) doTyp() (res types.Type) {
+ switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
+ default:
+ errorf("unhandled type tag: %v", tag)
+ panic("unreachable")
+
+ case pkgbits.TypeBasic:
+ return types.Typ[r.Len()]
+
+ case pkgbits.TypeNamed:
+ obj, targs := r.obj()
+ name := obj.(*types.TypeName)
+ if len(targs) != 0 {
+ t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false)
+ return t
+ }
+ return name.Type()
+
+ case pkgbits.TypeTypeParam:
+ return r.dict.tparams[r.Len()]
+
+ case pkgbits.TypeArray:
+ len := int64(r.Uint64())
+ return types.NewArray(r.typ(), len)
+ case pkgbits.TypeChan:
+ dir := types.ChanDir(r.Len())
+ return types.NewChan(dir, r.typ())
+ case pkgbits.TypeMap:
+ return types.NewMap(r.typ(), r.typ())
+ case pkgbits.TypePointer:
+ return types.NewPointer(r.typ())
+ case pkgbits.TypeSignature:
+ return r.signature(nil, nil, nil)
+ case pkgbits.TypeSlice:
+ return types.NewSlice(r.typ())
+ case pkgbits.TypeStruct:
+ return r.structType()
+ case pkgbits.TypeInterface:
+ return r.interfaceType()
+ case pkgbits.TypeUnion:
+ return r.unionType()
+ }
+}
+
+func (r *reader) structType() *types.Struct {
+ fields := make([]*types.Var, r.Len())
+ var tags []string
+ for i := range fields {
+ pos := r.pos()
+ pkg, name := r.selector()
+ ftyp := r.typ()
+ tag := r.String()
+ embedded := r.Bool()
+
+ fields[i] = types.NewField(pos, pkg, name, ftyp, embedded)
+ if tag != "" {
+ for len(tags) < i {
+ tags = append(tags, "")
+ }
+ tags = append(tags, tag)
+ }
+ }
+ return types.NewStruct(fields, tags)
+}
+
+func (r *reader) unionType() *types.Union {
+ terms := make([]*types.Term, r.Len())
+ for i := range terms {
+ terms[i] = types.NewTerm(r.Bool(), r.typ())
+ }
+ return types.NewUnion(terms)
+}
+
+func (r *reader) interfaceType() *types.Interface {
+ methods := make([]*types.Func, r.Len())
+ embeddeds := make([]types.Type, r.Len())
+ implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
+
+ for i := range methods {
+ pos := r.pos()
+ pkg, name := r.selector()
+ mtyp := r.signature(nil, nil, nil)
+ methods[i] = types.NewFunc(pos, pkg, name, mtyp)
+ }
+
+ for i := range embeddeds {
+ embeddeds[i] = r.typ()
+ }
+
+ iface := types.NewInterfaceType(methods, embeddeds)
+ if implicit {
+ iface.MarkImplicit()
+ }
+
+ // We need to call iface.Complete(), but if there are any embedded
+ // defined types, then we may not have set their underlying
+ // interface type yet. So we need to defer calling Complete until
+ // after we've called SetUnderlying everywhere.
+ //
+ // TODO(mdempsky): After CL 424876 lands, it should be safe to call
+ // iface.Complete() immediately.
+ r.p.ifaces = append(r.p.ifaces, iface)
+
+ return iface
+}
+
+func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature {
+ r.Sync(pkgbits.SyncSignature)
+
+ params := r.params()
+ results := r.params()
+ variadic := r.Bool()
+
+ return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
+}
+
+func (r *reader) params() *types.Tuple {
+ r.Sync(pkgbits.SyncParams)
+
+ params := make([]*types.Var, r.Len())
+ for i := range params {
+ params[i] = r.param()
+ }
+
+ return types.NewTuple(params...)
+}
+
+func (r *reader) param() *types.Var {
+ r.Sync(pkgbits.SyncParam)
+
+ pos := r.pos()
+ pkg, name := r.localIdent()
+ typ := r.typ()
+
+ return types.NewParam(pos, pkg, name, typ)
+}
+
+// @@@ Objects
+
+func (r *reader) obj() (types.Object, []types.Type) {
+ r.Sync(pkgbits.SyncObject)
+
+ assert(!r.Bool())
+
+ pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj))
+ obj := pkgScope(pkg).Lookup(name)
+
+ targs := make([]types.Type, r.Len())
+ for i := range targs {
+ targs[i] = r.typ()
+ }
+
+ return obj, targs
+}
+
+func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
+
+ var objPkg *types.Package
+ var objName string
+ var tag pkgbits.CodeObj
+ {
+ rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
+
+ objPkg, objName = rname.qualifiedIdent()
+ assert(objName != "")
+
+ tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
+ pr.retireReader(rname)
+ }
+
+ if tag == pkgbits.ObjStub {
+ assert(objPkg == nil || objPkg == types.Unsafe)
+ return objPkg, objName
+ }
+
+ // Ignore local types promoted to global scope (#55110).
+ if _, suffix := splitVargenSuffix(objName); suffix != "" {
+ return objPkg, objName
+ }
+
+ if objPkg.Scope().Lookup(objName) == nil {
+ dict := pr.objDictIdx(idx)
+
+ r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
+ r.dict = dict
+
+ declare := func(obj types.Object) {
+ objPkg.Scope().Insert(obj)
+ }
+
+ switch tag {
+ default:
+ panic("weird")
+
+ case pkgbits.ObjAlias:
+ pos := r.pos()
+ typ := r.typ()
+ declare(aliases.NewAlias(r.p.aliases, pos, objPkg, objName, typ))
+
+ case pkgbits.ObjConst:
+ pos := r.pos()
+ typ := r.typ()
+ val := r.Value()
+ declare(types.NewConst(pos, objPkg, objName, typ, val))
+
+ case pkgbits.ObjFunc:
+ pos := r.pos()
+ tparams := r.typeParamNames()
+ sig := r.signature(nil, nil, tparams)
+ declare(types.NewFunc(pos, objPkg, objName, sig))
+
+ case pkgbits.ObjType:
+ pos := r.pos()
+
+ obj := types.NewTypeName(pos, objPkg, objName, nil)
+ named := types.NewNamed(obj, nil, nil)
+ declare(obj)
+
+ named.SetTypeParams(r.typeParamNames())
+
+ setUnderlying := func(underlying types.Type) {
+ // If the underlying type is an interface, we need to
+ // duplicate its methods so we can replace the receiver
+ // parameter's type (#49906).
+ if iface, ok := aliases.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
+ methods := make([]*types.Func, iface.NumExplicitMethods())
+ for i := range methods {
+ fn := iface.ExplicitMethod(i)
+ sig := fn.Type().(*types.Signature)
+
+ recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
+ methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic()))
+ }
+
+ embeds := make([]types.Type, iface.NumEmbeddeds())
+ for i := range embeds {
+ embeds[i] = iface.EmbeddedType(i)
+ }
+
+ newIface := types.NewInterfaceType(methods, embeds)
+ r.p.ifaces = append(r.p.ifaces, newIface)
+ underlying = newIface
+ }
+
+ named.SetUnderlying(underlying)
+ }
+
+ // Since go.dev/cl/455279, we can assume rhs.Underlying() will
+ // always be non-nil. However, to temporarily support users of
+ // older snapshot releases, we continue to fallback to the old
+ // behavior for now.
+ //
+ // TODO(mdempsky): Remove fallback code and simplify after
+ // allowing time for snapshot users to upgrade.
+ rhs := r.typ()
+ if underlying := rhs.Underlying(); underlying != nil {
+ setUnderlying(underlying)
+ } else {
+ pk := r.p
+ pk.laterFor(named, func() {
+ // First be sure that the rhs is initialized, if it needs to be initialized.
+ delete(pk.laterFors, named) // prevent cycles
+ if i, ok := pk.laterFors[rhs]; ok {
+ f := pk.laterFns[i]
+ pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op
+ f() // initialize RHS
+ }
+ setUnderlying(rhs.Underlying())
+ })
+ }
+
+ for i, n := 0, r.Len(); i < n; i++ {
+ named.AddMethod(r.method())
+ }
+
+ case pkgbits.ObjVar:
+ pos := r.pos()
+ typ := r.typ()
+ declare(types.NewVar(pos, objPkg, objName, typ))
+ }
+ }
+
+ return objPkg, objName
+}
+
+func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
+
+ var dict readerDict
+
+ {
+ r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
+ if implicits := r.Len(); implicits != 0 {
+ errorf("unexpected object with %v implicit type parameter(s)", implicits)
+ }
+
+ dict.bounds = make([]typeInfo, r.Len())
+ for i := range dict.bounds {
+ dict.bounds[i] = r.typInfo()
+ }
+
+ dict.derived = make([]derivedInfo, r.Len())
+ dict.derivedTypes = make([]types.Type, len(dict.derived))
+ for i := range dict.derived {
+ dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
+ }
+
+ pr.retireReader(r)
+ }
+ // function references follow, but reader doesn't need those
+
+ return &dict
+}
+
+func (r *reader) typeParamNames() []*types.TypeParam {
+ r.Sync(pkgbits.SyncTypeParamNames)
+
+ // Note: This code assumes it only processes objects without
+ // implement type parameters. This is currently fine, because
+ // reader is only used to read in exported declarations, which are
+ // always package scoped.
+
+ if len(r.dict.bounds) == 0 {
+ return nil
+ }
+
+ // Careful: Type parameter lists may have cycles. To allow for this,
+ // we construct the type parameter list in two passes: first we
+ // create all the TypeNames and TypeParams, then we construct and
+ // set the bound type.
+
+ r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds))
+ for i := range r.dict.bounds {
+ pos := r.pos()
+ pkg, name := r.localIdent()
+
+ tname := types.NewTypeName(pos, pkg, name, nil)
+ r.dict.tparams[i] = types.NewTypeParam(tname, nil)
+ }
+
+ typs := make([]types.Type, len(r.dict.bounds))
+ for i, bound := range r.dict.bounds {
+ typs[i] = r.p.typIdx(bound, r.dict)
+ }
+
+ // TODO(mdempsky): This is subtle, elaborate further.
+ //
+ // We have to save tparams outside of the closure, because
+ // typeParamNames() can be called multiple times with the same
+ // dictionary instance.
+ //
+ // Also, this needs to happen later to make sure SetUnderlying has
+ // been called.
+ //
+ // TODO(mdempsky): Is it safe to have a single "later" slice or do
+ // we need to have multiple passes? See comments on CL 386002 and
+ // go.dev/issue/52104.
+ tparams := r.dict.tparams
+ r.p.later(func() {
+ for i, typ := range typs {
+ tparams[i].SetConstraint(typ)
+ }
+ })
+
+ return r.dict.tparams
+}
+
+func (r *reader) method() *types.Func {
+ r.Sync(pkgbits.SyncMethod)
+ pos := r.pos()
+ pkg, name := r.selector()
+
+ rparams := r.typeParamNames()
+ sig := r.signature(r.param(), rparams, nil)
+
+ _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
+ return types.NewFunc(pos, pkg, name, sig)
+}
+
+func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) }
+func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) }
+func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) }
+
+func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) {
+ r.Sync(marker)
+ return r.pkg(), r.String()
+}
+
+// pkgScope returns pkg.Scope().
+// If pkg is nil, it returns types.Universe instead.
+//
+// TODO(mdempsky): Remove after x/tools can depend on Go 1.19.
+func pkgScope(pkg *types.Package) *types.Scope {
+ if pkg != nil {
+ return pkg.Scope()
+ }
+ return types.Universe
+}
diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
new file mode 100644
index 00000000..2e59ff85
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
@@ -0,0 +1,555 @@
+// 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.
+
+// Package gocommand is a helper for calling the go command.
+package gocommand
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "reflect"
+ "regexp"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "golang.org/x/tools/internal/event"
+ "golang.org/x/tools/internal/event/keys"
+ "golang.org/x/tools/internal/event/label"
+)
+
+// An Runner will run go command invocations and serialize
+// them if it sees a concurrency error.
+type Runner struct {
+ // once guards the runner initialization.
+ once sync.Once
+
+ // inFlight tracks available workers.
+ inFlight chan struct{}
+
+ // serialized guards the ability to run a go command serially,
+ // to avoid deadlocks when claiming workers.
+ serialized chan struct{}
+}
+
+const maxInFlight = 10
+
+func (runner *Runner) initialize() {
+ runner.once.Do(func() {
+ runner.inFlight = make(chan struct{}, maxInFlight)
+ runner.serialized = make(chan struct{}, 1)
+ })
+}
+
+// 1.13: go: updates to go.mod needed, but contents have changed
+// 1.14: go: updating go.mod: existing contents have changed since last read
+var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`)
+
+// event keys for go command invocations
+var (
+ verb = keys.NewString("verb", "go command verb")
+ directory = keys.NewString("directory", "")
+)
+
+func invLabels(inv Invocation) []label.Label {
+ return []label.Label{verb.Of(inv.Verb), directory.Of(inv.WorkingDir)}
+}
+
+// Run is a convenience wrapper around RunRaw.
+// It returns only stdout and a "friendly" error.
+func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) {
+ ctx, done := event.Start(ctx, "gocommand.Runner.Run", invLabels(inv)...)
+ defer done()
+
+ stdout, _, friendly, _ := runner.RunRaw(ctx, inv)
+ return stdout, friendly
+}
+
+// RunPiped runs the invocation serially, always waiting for any concurrent
+// invocations to complete first.
+func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) error {
+ ctx, done := event.Start(ctx, "gocommand.Runner.RunPiped", invLabels(inv)...)
+ defer done()
+
+ _, err := runner.runPiped(ctx, inv, stdout, stderr)
+ return err
+}
+
+// RunRaw runs the invocation, serializing requests only if they fight over
+// go.mod changes.
+// Postcondition: both error results have same nilness.
+func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
+ ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...)
+ defer done()
+ // Make sure the runner is always initialized.
+ runner.initialize()
+
+ // First, try to run the go command concurrently.
+ stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv)
+
+ // If we encounter a load concurrency error, we need to retry serially.
+ if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) {
+ event.Error(ctx, "Load concurrency error, will retry serially", err)
+
+ // Run serially by calling runPiped.
+ stdout.Reset()
+ stderr.Reset()
+ friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
+ }
+
+ return stdout, stderr, friendlyErr, err
+}
+
+// Postcondition: both error results have same nilness.
+func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
+ // Wait for 1 worker to become available.
+ select {
+ case <-ctx.Done():
+ return nil, nil, ctx.Err(), ctx.Err()
+ case runner.inFlight <- struct{}{}:
+ defer func() { <-runner.inFlight }()
+ }
+
+ stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
+ friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr)
+ return stdout, stderr, friendlyErr, err
+}
+
+// Postcondition: both error results have same nilness.
+func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) {
+ // Make sure the runner is always initialized.
+ runner.initialize()
+
+ // Acquire the serialization lock. This avoids deadlocks between two
+ // runPiped commands.
+ select {
+ case <-ctx.Done():
+ return ctx.Err(), ctx.Err()
+ case runner.serialized <- struct{}{}:
+ defer func() { <-runner.serialized }()
+ }
+
+ // Wait for all in-progress go commands to return before proceeding,
+ // to avoid load concurrency errors.
+ for i := 0; i < maxInFlight; i++ {
+ select {
+ case <-ctx.Done():
+ return ctx.Err(), ctx.Err()
+ case runner.inFlight <- struct{}{}:
+ // Make sure we always "return" any workers we took.
+ defer func() { <-runner.inFlight }()
+ }
+ }
+
+ return inv.runWithFriendlyError(ctx, stdout, stderr)
+}
+
+// An Invocation represents a call to the go command.
+type Invocation struct {
+ Verb string
+ Args []string
+ BuildFlags []string
+
+ // If ModFlag is set, the go command is invoked with -mod=ModFlag.
+ // TODO(rfindley): remove, in favor of Args.
+ ModFlag string
+
+ // If ModFile is set, the go command is invoked with -modfile=ModFile.
+ // TODO(rfindley): remove, in favor of Args.
+ ModFile string
+
+ // Overlay is the name of the JSON overlay file that describes
+ // unsaved editor buffers; see [WriteOverlays].
+ // If set, the go command is invoked with -overlay=Overlay.
+ // TODO(rfindley): remove, in favor of Args.
+ Overlay string
+
+ // If CleanEnv is set, the invocation will run only with the environment
+ // in Env, not starting with os.Environ.
+ CleanEnv bool
+ Env []string
+ WorkingDir string
+ Logf func(format string, args ...interface{})
+}
+
+// Postcondition: both error results have same nilness.
+func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) {
+ rawError = i.run(ctx, stdout, stderr)
+ if rawError != nil {
+ friendlyError = rawError
+ // Check for 'go' executable not being found.
+ if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
+ friendlyError = fmt.Errorf("go command required, not found: %v", ee)
+ }
+ if ctx.Err() != nil {
+ friendlyError = ctx.Err()
+ }
+ friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr)
+ }
+ return
+}
+
+// logf logs if i.Logf is non-nil.
+func (i *Invocation) logf(format string, args ...any) {
+ if i.Logf != nil {
+ i.Logf(format, args...)
+ }
+}
+
+func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
+ goArgs := []string{i.Verb}
+
+ appendModFile := func() {
+ if i.ModFile != "" {
+ goArgs = append(goArgs, "-modfile="+i.ModFile)
+ }
+ }
+ appendModFlag := func() {
+ if i.ModFlag != "" {
+ goArgs = append(goArgs, "-mod="+i.ModFlag)
+ }
+ }
+ appendOverlayFlag := func() {
+ if i.Overlay != "" {
+ goArgs = append(goArgs, "-overlay="+i.Overlay)
+ }
+ }
+
+ switch i.Verb {
+ case "env", "version":
+ goArgs = append(goArgs, i.Args...)
+ case "mod":
+ // mod needs the sub-verb before flags.
+ goArgs = append(goArgs, i.Args[0])
+ appendModFile()
+ goArgs = append(goArgs, i.Args[1:]...)
+ case "get":
+ goArgs = append(goArgs, i.BuildFlags...)
+ appendModFile()
+ goArgs = append(goArgs, i.Args...)
+
+ default: // notably list and build.
+ goArgs = append(goArgs, i.BuildFlags...)
+ appendModFile()
+ appendModFlag()
+ appendOverlayFlag()
+ goArgs = append(goArgs, i.Args...)
+ }
+ cmd := exec.Command("go", goArgs...)
+ cmd.Stdout = stdout
+ cmd.Stderr = stderr
+
+ // cmd.WaitDelay was added only in go1.20 (see #50436).
+ if waitDelay := reflect.ValueOf(cmd).Elem().FieldByName("WaitDelay"); waitDelay.IsValid() {
+ // https://go.dev/issue/59541: don't wait forever copying stderr
+ // after the command has exited.
+ // After CL 484741 we copy stdout manually, so we we'll stop reading that as
+ // soon as ctx is done. However, we also don't want to wait around forever
+ // for stderr. Give a much-longer-than-reasonable delay and then assume that
+ // something has wedged in the kernel or runtime.
+ waitDelay.Set(reflect.ValueOf(30 * time.Second))
+ }
+
+ // The cwd gets resolved to the real path. On Darwin, where
+ // /tmp is a symlink, this breaks anything that expects the
+ // working directory to keep the original path, including the
+ // go command when dealing with modules.
+ //
+ // os.Getwd has a special feature where if the cwd and the PWD
+ // are the same node then it trusts the PWD, so by setting it
+ // in the env for the child process we fix up all the paths
+ // returned by the go command.
+ if !i.CleanEnv {
+ cmd.Env = os.Environ()
+ }
+ cmd.Env = append(cmd.Env, i.Env...)
+ if i.WorkingDir != "" {
+ cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir)
+ cmd.Dir = i.WorkingDir
+ }
+
+ debugStr := cmdDebugStr(cmd)
+ i.logf("starting %v", debugStr)
+ start := time.Now()
+ defer func() {
+ i.logf("%s for %v", time.Since(start), debugStr)
+ }()
+
+ return runCmdContext(ctx, cmd)
+}
+
+// DebugHangingGoCommands may be set by tests to enable additional
+// instrumentation (including panics) for debugging hanging Go commands.
+//
+// See golang/go#54461 for details.
+var DebugHangingGoCommands = false
+
+// runCmdContext is like exec.CommandContext except it sends os.Interrupt
+// before os.Kill.
+func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
+ // If cmd.Stdout is not an *os.File, the exec package will create a pipe and
+ // copy it to the Writer in a goroutine until the process has finished and
+ // either the pipe reaches EOF or command's WaitDelay expires.
+ //
+ // However, the output from 'go list' can be quite large, and we don't want to
+ // keep reading (and allocating buffers) if we've already decided we don't
+ // care about the output. We don't want to wait for the process to finish, and
+ // we don't wait to wait for the WaitDelay to expire either.
+ //
+ // Instead, if cmd.Stdout requires a copying goroutine we explicitly replace
+ // it with a pipe (which is an *os.File), which we can close in order to stop
+ // copying output as soon as we realize we don't care about it.
+ var stdoutW *os.File
+ if cmd.Stdout != nil {
+ if _, ok := cmd.Stdout.(*os.File); !ok {
+ var stdoutR *os.File
+ stdoutR, stdoutW, err = os.Pipe()
+ if err != nil {
+ return err
+ }
+ prevStdout := cmd.Stdout
+ cmd.Stdout = stdoutW
+
+ stdoutErr := make(chan error, 1)
+ go func() {
+ _, err := io.Copy(prevStdout, stdoutR)
+ if err != nil {
+ err = fmt.Errorf("copying stdout: %w", err)
+ }
+ stdoutErr <- err
+ }()
+ defer func() {
+ // We started a goroutine to copy a stdout pipe.
+ // Wait for it to finish, or terminate it if need be.
+ var err2 error
+ select {
+ case err2 = <-stdoutErr:
+ stdoutR.Close()
+ case <-ctx.Done():
+ stdoutR.Close()
+ // Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close
+ // should cause the Read call in io.Copy to unblock and return
+ // immediately, but we still need to receive from stdoutErr to confirm
+ // that it has happened.
+ <-stdoutErr
+ err2 = ctx.Err()
+ }
+ if err == nil {
+ err = err2
+ }
+ }()
+
+ // Per https://pkg.go.dev/os/exec#Cmd, “If Stdout and Stderr are the
+ // same writer, and have a type that can be compared with ==, at most
+ // one goroutine at a time will call Write.”
+ //
+ // Since we're starting a goroutine that writes to cmd.Stdout, we must
+ // also update cmd.Stderr so that it still holds.
+ func() {
+ defer func() { recover() }()
+ if cmd.Stderr == prevStdout {
+ cmd.Stderr = cmd.Stdout
+ }
+ }()
+ }
+ }
+
+ startTime := time.Now()
+ err = cmd.Start()
+ if stdoutW != nil {
+ // The child process has inherited the pipe file,
+ // so close the copy held in this process.
+ stdoutW.Close()
+ stdoutW = nil
+ }
+ if err != nil {
+ return err
+ }
+
+ resChan := make(chan error, 1)
+ go func() {
+ resChan <- cmd.Wait()
+ }()
+
+ // If we're interested in debugging hanging Go commands, stop waiting after a
+ // minute and panic with interesting information.
+ debug := DebugHangingGoCommands
+ if debug {
+ timer := time.NewTimer(1 * time.Minute)
+ defer timer.Stop()
+ select {
+ case err := <-resChan:
+ return err
+ case <-timer.C:
+ HandleHangingGoCommand(startTime, cmd)
+ case <-ctx.Done():
+ }
+ } else {
+ select {
+ case err := <-resChan:
+ return err
+ case <-ctx.Done():
+ }
+ }
+
+ // Cancelled. Interrupt and see if it ends voluntarily.
+ if err := cmd.Process.Signal(os.Interrupt); err == nil {
+ // (We used to wait only 1s but this proved
+ // fragile on loaded builder machines.)
+ timer := time.NewTimer(5 * time.Second)
+ defer timer.Stop()
+ select {
+ case err := <-resChan:
+ return err
+ case <-timer.C:
+ }
+ }
+
+ // Didn't shut down in response to interrupt. Kill it hard.
+ // TODO(rfindley): per advice from bcmills@, it may be better to send SIGQUIT
+ // on certain platforms, such as unix.
+ if err := cmd.Process.Kill(); err != nil && !errors.Is(err, os.ErrProcessDone) && debug {
+ log.Printf("error killing the Go command: %v", err)
+ }
+
+ return <-resChan
+}
+
+func HandleHangingGoCommand(start time.Time, cmd *exec.Cmd) {
+ switch runtime.GOOS {
+ case "linux", "darwin", "freebsd", "netbsd":
+ fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND
+
+The gopls test runner has detected a hanging go command. In order to debug
+this, the output of ps and lsof/fstat is printed below.
+
+See golang/go#54461 for more details.`)
+
+ fmt.Fprintln(os.Stderr, "\nps axo ppid,pid,command:")
+ fmt.Fprintln(os.Stderr, "-------------------------")
+ psCmd := exec.Command("ps", "axo", "ppid,pid,command")
+ psCmd.Stdout = os.Stderr
+ psCmd.Stderr = os.Stderr
+ if err := psCmd.Run(); err != nil {
+ panic(fmt.Sprintf("running ps: %v", err))
+ }
+
+ listFiles := "lsof"
+ if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" {
+ listFiles = "fstat"
+ }
+
+ fmt.Fprintln(os.Stderr, "\n"+listFiles+":")
+ fmt.Fprintln(os.Stderr, "-----")
+ listFilesCmd := exec.Command(listFiles)
+ listFilesCmd.Stdout = os.Stderr
+ listFilesCmd.Stderr = os.Stderr
+ if err := listFilesCmd.Run(); err != nil {
+ panic(fmt.Sprintf("running %s: %v", listFiles, err))
+ }
+ }
+ panic(fmt.Sprintf("detected hanging go command (golang/go#54461); waited %s\n\tcommand:%s\n\tpid:%d", time.Since(start), cmd, cmd.Process.Pid))
+}
+
+func cmdDebugStr(cmd *exec.Cmd) string {
+ env := make(map[string]string)
+ for _, kv := range cmd.Env {
+ split := strings.SplitN(kv, "=", 2)
+ if len(split) == 2 {
+ k, v := split[0], split[1]
+ env[k] = v
+ }
+ }
+
+ var args []string
+ for _, arg := range cmd.Args {
+ quoted := strconv.Quote(arg)
+ if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") {
+ args = append(args, quoted)
+ } else {
+ args = append(args, arg)
+ }
+ }
+ return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " "))
+}
+
+// WriteOverlays writes each value in the overlay (see the Overlay
+// field of go/packages.Config) to a temporary file and returns the name
+// of a JSON file describing the mapping that is suitable for the "go
+// list -overlay" flag.
+//
+// On success, the caller must call the cleanup function exactly once
+// when the files are no longer needed.
+func WriteOverlays(overlay map[string][]byte) (filename string, cleanup func(), err error) {
+ // Do nothing if there are no overlays in the config.
+ if len(overlay) == 0 {
+ return "", func() {}, nil
+ }
+
+ dir, err := os.MkdirTemp("", "gocommand-*")
+ if err != nil {
+ return "", nil, err
+ }
+
+ // The caller must clean up this directory,
+ // unless this function returns an error.
+ // (The cleanup operand of each return
+ // statement below is ignored.)
+ defer func() {
+ cleanup = func() {
+ os.RemoveAll(dir)
+ }
+ if err != nil {
+ cleanup()
+ cleanup = nil
+ }
+ }()
+
+ // Write each map entry to a temporary file.
+ overlays := make(map[string]string)
+ for k, v := range overlay {
+ // Use a unique basename for each file (001-foo.go),
+ // to avoid creating nested directories.
+ base := fmt.Sprintf("%d-%s", 1+len(overlays), filepath.Base(k))
+ filename := filepath.Join(dir, base)
+ err := os.WriteFile(filename, v, 0666)
+ if err != nil {
+ return "", nil, err
+ }
+ overlays[k] = filename
+ }
+
+ // Write the JSON overlay file that maps logical file names to temp files.
+ //
+ // OverlayJSON is the format overlay files are expected to be in.
+ // The Replace map maps from overlaid paths to replacement paths:
+ // the Go command will forward all reads trying to open
+ // each overlaid path to its replacement path, or consider the overlaid
+ // path not to exist if the replacement path is empty.
+ //
+ // From golang/go#39958.
+ type OverlayJSON struct {
+ Replace map[string]string `json:"replace,omitempty"`
+ }
+ b, err := json.Marshal(OverlayJSON{Replace: overlays})
+ if err != nil {
+ return "", nil, err
+ }
+ filename = filepath.Join(dir, "overlay.json")
+ if err := os.WriteFile(filename, b, 0666); err != nil {
+ return "", nil, err
+ }
+
+ return filename, nil, nil
+}
diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go
new file mode 100644
index 00000000..e38d1fb4
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gocommand/vendor.go
@@ -0,0 +1,163 @@
+// 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.
+
+package gocommand
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+ "time"
+
+ "golang.org/x/mod/semver"
+)
+
+// ModuleJSON holds information about a module.
+type ModuleJSON struct {
+ Path string // module path
+ Version string // module version
+ Versions []string // available module versions (with -versions)
+ Replace *ModuleJSON // replaced by this module
+ Time *time.Time // time version was created
+ Update *ModuleJSON // available update, if any (with -u)
+ Main bool // is this the main module?
+ Indirect bool // is this module only an indirect dependency of main module?
+ Dir string // directory holding files for this module, if any
+ GoMod string // path to go.mod file used when loading this module, if any
+ GoVersion string // go version used in module
+}
+
+var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`)
+
+// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands
+// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields,
+// of which only Verb and Args are modified to run the appropriate Go command.
+// Inspired by setDefaultBuildMod in modload/init.go
+func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) {
+ mainMod, go114, err := getMainModuleAnd114(ctx, inv, r)
+ if err != nil {
+ return false, nil, err
+ }
+
+ // We check the GOFLAGS to see if there is anything overridden or not.
+ inv.Verb = "env"
+ inv.Args = []string{"GOFLAGS"}
+ stdout, err := r.Run(ctx, inv)
+ if err != nil {
+ return false, nil, err
+ }
+ goflags := string(bytes.TrimSpace(stdout.Bytes()))
+ matches := modFlagRegexp.FindStringSubmatch(goflags)
+ var modFlag string
+ if len(matches) != 0 {
+ modFlag = matches[1]
+ }
+ // Don't override an explicit '-mod=' argument.
+ if modFlag == "vendor" {
+ return true, mainMod, nil
+ } else if modFlag != "" {
+ return false, nil, nil
+ }
+ if mainMod == nil || !go114 {
+ return false, nil, nil
+ }
+ // Check 1.14's automatic vendor mode.
+ if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() {
+ if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 {
+ // The Go version is at least 1.14, and a vendor directory exists.
+ // Set -mod=vendor by default.
+ return true, mainMod, nil
+ }
+ }
+ return false, nil, nil
+}
+
+// getMainModuleAnd114 gets one of the main modules' information and whether the
+// go command in use is 1.14+. This is the information needed to figure out
+// if vendoring should be enabled.
+func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) {
+ const format = `{{.Path}}
+{{.Dir}}
+{{.GoMod}}
+{{.GoVersion}}
+{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}}
+`
+ inv.Verb = "list"
+ inv.Args = []string{"-m", "-f", format}
+ stdout, err := r.Run(ctx, inv)
+ if err != nil {
+ return nil, false, err
+ }
+
+ lines := strings.Split(stdout.String(), "\n")
+ if len(lines) < 5 {
+ return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String())
+ }
+ mod := &ModuleJSON{
+ Path: lines[0],
+ Dir: lines[1],
+ GoMod: lines[2],
+ GoVersion: lines[3],
+ Main: true,
+ }
+ return mod, lines[4] == "go1.14", nil
+}
+
+// WorkspaceVendorEnabled reports whether workspace vendoring is enabled. It takes a *Runner to execute Go commands
+// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields,
+// of which only Verb and Args are modified to run the appropriate Go command.
+// Inspired by setDefaultBuildMod in modload/init.go
+func WorkspaceVendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, []*ModuleJSON, error) {
+ inv.Verb = "env"
+ inv.Args = []string{"GOWORK"}
+ stdout, err := r.Run(ctx, inv)
+ if err != nil {
+ return false, nil, err
+ }
+ goWork := string(bytes.TrimSpace(stdout.Bytes()))
+ if fi, err := os.Stat(filepath.Join(filepath.Dir(goWork), "vendor")); err == nil && fi.IsDir() {
+ mainMods, err := getWorkspaceMainModules(ctx, inv, r)
+ if err != nil {
+ return false, nil, err
+ }
+ return true, mainMods, nil
+ }
+ return false, nil, nil
+}
+
+// getWorkspaceMainModules gets the main modules' information.
+// This is the information needed to figure out if vendoring should be enabled.
+func getWorkspaceMainModules(ctx context.Context, inv Invocation, r *Runner) ([]*ModuleJSON, error) {
+ const format = `{{.Path}}
+{{.Dir}}
+{{.GoMod}}
+{{.GoVersion}}
+`
+ inv.Verb = "list"
+ inv.Args = []string{"-m", "-f", format}
+ stdout, err := r.Run(ctx, inv)
+ if err != nil {
+ return nil, err
+ }
+
+ lines := strings.Split(strings.TrimSuffix(stdout.String(), "\n"), "\n")
+ if len(lines) < 4 {
+ return nil, fmt.Errorf("unexpected stdout: %q", stdout.String())
+ }
+ mods := make([]*ModuleJSON, 0, len(lines)/4)
+ for i := 0; i < len(lines); i += 4 {
+ mods = append(mods, &ModuleJSON{
+ Path: lines[i],
+ Dir: lines[i+1],
+ GoMod: lines[i+2],
+ GoVersion: lines[i+3],
+ Main: true,
+ })
+ }
+ return mods, nil
+}
diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go
new file mode 100644
index 00000000..446c5846
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gocommand/version.go
@@ -0,0 +1,71 @@
+// 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.
+
+package gocommand
+
+import (
+ "context"
+ "fmt"
+ "regexp"
+ "strings"
+)
+
+// GoVersion reports the minor version number of the highest release
+// tag built into the go command on the PATH.
+//
+// Note that this may be higher than the version of the go tool used
+// to build this application, and thus the versions of the standard
+// go/{scanner,parser,ast,types} packages that are linked into it.
+// In that case, callers should either downgrade to the version of
+// go used to build the application, or report an error that the
+// application is too old to use the go command on the PATH.
+func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) {
+ inv.Verb = "list"
+ inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`}
+ inv.BuildFlags = nil // This is not a build command.
+ inv.ModFlag = ""
+ inv.ModFile = ""
+ inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off")
+
+ stdoutBytes, err := r.Run(ctx, inv)
+ if err != nil {
+ return 0, err
+ }
+ stdout := stdoutBytes.String()
+ if len(stdout) < 3 {
+ return 0, fmt.Errorf("bad ReleaseTags output: %q", stdout)
+ }
+ // Split up "[go1.1 go1.15]" and return highest go1.X value.
+ tags := strings.Fields(stdout[1 : len(stdout)-2])
+ for i := len(tags) - 1; i >= 0; i-- {
+ var version int
+ if _, err := fmt.Sscanf(tags[i], "go1.%d", &version); err != nil {
+ continue
+ }
+ return version, nil
+ }
+ return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags)
+}
+
+// GoVersionOutput returns the complete output of the go version command.
+func GoVersionOutput(ctx context.Context, inv Invocation, r *Runner) (string, error) {
+ inv.Verb = "version"
+ goVersion, err := r.Run(ctx, inv)
+ if err != nil {
+ return "", err
+ }
+ return goVersion.String(), nil
+}
+
+// ParseGoVersionOutput extracts the Go version string
+// from the output of the "go version" command.
+// Given an unrecognized form, it returns an empty string.
+func ParseGoVersionOutput(data string) string {
+ re := regexp.MustCompile(`^go version (go\S+|devel \S+)`)
+ m := re.FindStringSubmatch(data)
+ if len(m) != 2 {
+ return "" // unrecognized version
+ }
+ return m[1]
+}
diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
new file mode 100644
index 00000000..44719de1
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
@@ -0,0 +1,22 @@
+// 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.
+
+// Package packagesinternal exposes internal-only fields from go/packages.
+package packagesinternal
+
+var GetForTest = func(p interface{}) string { return "" }
+var GetDepsErrors = func(p interface{}) []*PackageError { return nil }
+
+type PackageError struct {
+ ImportStack []string // shortest path from package named on command line to this one
+ Pos string // position of error (if present, file:line:col)
+ Err string // the error itself
+}
+
+var TypecheckCgo int
+var DepsErrors int // must be set as a LoadMode to call GetDepsErrors
+var ForTest int // must be set as a LoadMode to call GetForTest
+
+var SetModFlag = func(config interface{}, value string) {}
+var SetModFile = func(config interface{}, value string) {}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/codes.go b/vendor/golang.org/x/tools/internal/pkgbits/codes.go
new file mode 100644
index 00000000..f0cabde9
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/codes.go
@@ -0,0 +1,77 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+// A Code is an enum value that can be encoded into bitstreams.
+//
+// Code types are preferable for enum types, because they allow
+// Decoder to detect desyncs.
+type Code interface {
+ // Marker returns the SyncMarker for the Code's dynamic type.
+ Marker() SyncMarker
+
+ // Value returns the Code's ordinal value.
+ Value() int
+}
+
+// A CodeVal distinguishes among go/constant.Value encodings.
+type CodeVal int
+
+func (c CodeVal) Marker() SyncMarker { return SyncVal }
+func (c CodeVal) Value() int { return int(c) }
+
+// Note: These values are public and cannot be changed without
+// updating the go/types importers.
+
+const (
+ ValBool CodeVal = iota
+ ValString
+ ValInt64
+ ValBigInt
+ ValBigRat
+ ValBigFloat
+)
+
+// A CodeType distinguishes among go/types.Type encodings.
+type CodeType int
+
+func (c CodeType) Marker() SyncMarker { return SyncType }
+func (c CodeType) Value() int { return int(c) }
+
+// Note: These values are public and cannot be changed without
+// updating the go/types importers.
+
+const (
+ TypeBasic CodeType = iota
+ TypeNamed
+ TypePointer
+ TypeSlice
+ TypeArray
+ TypeChan
+ TypeMap
+ TypeSignature
+ TypeStruct
+ TypeInterface
+ TypeUnion
+ TypeTypeParam
+)
+
+// A CodeObj distinguishes among go/types.Object encodings.
+type CodeObj int
+
+func (c CodeObj) Marker() SyncMarker { return SyncCodeObj }
+func (c CodeObj) Value() int { return int(c) }
+
+// Note: These values are public and cannot be changed without
+// updating the go/types importers.
+
+const (
+ ObjAlias CodeObj = iota
+ ObjConst
+ ObjType
+ ObjFunc
+ ObjVar
+ ObjStub
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go
new file mode 100644
index 00000000..2acd8585
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go
@@ -0,0 +1,521 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "go/constant"
+ "go/token"
+ "io"
+ "math/big"
+ "os"
+ "runtime"
+ "strings"
+)
+
+// A PkgDecoder provides methods for decoding a package's Unified IR
+// export data.
+type PkgDecoder struct {
+ // version is the file format version.
+ version uint32
+
+ // aliases determines whether types.Aliases should be created
+ aliases bool
+
+ // sync indicates whether the file uses sync markers.
+ sync bool
+
+ // pkgPath is the package path for the package to be decoded.
+ //
+ // TODO(mdempsky): Remove; unneeded since CL 391014.
+ pkgPath string
+
+ // elemData is the full data payload of the encoded package.
+ // Elements are densely and contiguously packed together.
+ //
+ // The last 8 bytes of elemData are the package fingerprint.
+ elemData string
+
+ // elemEnds stores the byte-offset end positions of element
+ // bitstreams within elemData.
+ //
+ // For example, element I's bitstream data starts at elemEnds[I-1]
+ // (or 0, if I==0) and ends at elemEnds[I].
+ //
+ // Note: elemEnds is indexed by absolute indices, not
+ // section-relative indices.
+ elemEnds []uint32
+
+ // elemEndsEnds stores the index-offset end positions of relocation
+ // sections within elemEnds.
+ //
+ // For example, section K's end positions start at elemEndsEnds[K-1]
+ // (or 0, if K==0) and end at elemEndsEnds[K].
+ elemEndsEnds [numRelocs]uint32
+
+ scratchRelocEnt []RelocEnt
+}
+
+// PkgPath returns the package path for the package
+//
+// TODO(mdempsky): Remove; unneeded since CL 391014.
+func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath }
+
+// SyncMarkers reports whether pr uses sync markers.
+func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync }
+
+// NewPkgDecoder returns a PkgDecoder initialized to read the Unified
+// IR export data from input. pkgPath is the package path for the
+// compilation unit that produced the export data.
+//
+// TODO(mdempsky): Remove pkgPath parameter; unneeded since CL 391014.
+func NewPkgDecoder(pkgPath, input string) PkgDecoder {
+ pr := PkgDecoder{
+ pkgPath: pkgPath,
+ //aliases: aliases.Enabled(),
+ }
+
+ // TODO(mdempsky): Implement direct indexing of input string to
+ // avoid copying the position information.
+
+ r := strings.NewReader(input)
+
+ assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil)
+
+ switch pr.version {
+ default:
+ panic(fmt.Errorf("unsupported version: %v", pr.version))
+ case 0:
+ // no flags
+ case 1:
+ var flags uint32
+ assert(binary.Read(r, binary.LittleEndian, &flags) == nil)
+ pr.sync = flags&flagSyncMarkers != 0
+ }
+
+ assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil)
+
+ pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1])
+ assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil)
+
+ pos, err := r.Seek(0, io.SeekCurrent)
+ assert(err == nil)
+
+ pr.elemData = input[pos:]
+ assert(len(pr.elemData)-8 == int(pr.elemEnds[len(pr.elemEnds)-1]))
+
+ return pr
+}
+
+// NumElems returns the number of elements in section k.
+func (pr *PkgDecoder) NumElems(k RelocKind) int {
+ count := int(pr.elemEndsEnds[k])
+ if k > 0 {
+ count -= int(pr.elemEndsEnds[k-1])
+ }
+ return count
+}
+
+// TotalElems returns the total number of elements across all sections.
+func (pr *PkgDecoder) TotalElems() int {
+ return len(pr.elemEnds)
+}
+
+// Fingerprint returns the package fingerprint.
+func (pr *PkgDecoder) Fingerprint() [8]byte {
+ var fp [8]byte
+ copy(fp[:], pr.elemData[len(pr.elemData)-8:])
+ return fp
+}
+
+// AbsIdx returns the absolute index for the given (section, index)
+// pair.
+func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int {
+ absIdx := int(idx)
+ if k > 0 {
+ absIdx += int(pr.elemEndsEnds[k-1])
+ }
+ if absIdx >= int(pr.elemEndsEnds[k]) {
+ errorf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds)
+ }
+ return absIdx
+}
+
+// DataIdx returns the raw element bitstream for the given (section,
+// index) pair.
+func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string {
+ absIdx := pr.AbsIdx(k, idx)
+
+ var start uint32
+ if absIdx > 0 {
+ start = pr.elemEnds[absIdx-1]
+ }
+ end := pr.elemEnds[absIdx]
+
+ return pr.elemData[start:end]
+}
+
+// StringIdx returns the string value for the given string index.
+func (pr *PkgDecoder) StringIdx(idx Index) string {
+ return pr.DataIdx(RelocString, idx)
+}
+
+// NewDecoder returns a Decoder for the given (section, index) pair,
+// and decodes the given SyncMarker from the element bitstream.
+func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder {
+ r := pr.NewDecoderRaw(k, idx)
+ r.Sync(marker)
+ return r
+}
+
+// TempDecoder returns a Decoder for the given (section, index) pair,
+// and decodes the given SyncMarker from the element bitstream.
+// If possible the Decoder should be RetireDecoder'd when it is no longer
+// needed, this will avoid heap allocations.
+func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder {
+ r := pr.TempDecoderRaw(k, idx)
+ r.Sync(marker)
+ return r
+}
+
+func (pr *PkgDecoder) RetireDecoder(d *Decoder) {
+ pr.scratchRelocEnt = d.Relocs
+ d.Relocs = nil
+}
+
+// NewDecoderRaw returns a Decoder for the given (section, index) pair.
+//
+// Most callers should use NewDecoder instead.
+func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder {
+ r := Decoder{
+ common: pr,
+ k: k,
+ Idx: idx,
+ }
+
+ // TODO(mdempsky) r.data.Reset(...) after #44505 is resolved.
+ r.Data = *strings.NewReader(pr.DataIdx(k, idx))
+
+ r.Sync(SyncRelocs)
+ r.Relocs = make([]RelocEnt, r.Len())
+ for i := range r.Relocs {
+ r.Sync(SyncReloc)
+ r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())}
+ }
+
+ return r
+}
+
+func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder {
+ r := Decoder{
+ common: pr,
+ k: k,
+ Idx: idx,
+ }
+
+ r.Data.Reset(pr.DataIdx(k, idx))
+ r.Sync(SyncRelocs)
+ l := r.Len()
+ if cap(pr.scratchRelocEnt) >= l {
+ r.Relocs = pr.scratchRelocEnt[:l]
+ pr.scratchRelocEnt = nil
+ } else {
+ r.Relocs = make([]RelocEnt, l)
+ }
+ for i := range r.Relocs {
+ r.Sync(SyncReloc)
+ r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())}
+ }
+
+ return r
+}
+
+// A Decoder provides methods for decoding an individual element's
+// bitstream data.
+type Decoder struct {
+ common *PkgDecoder
+
+ Relocs []RelocEnt
+ Data strings.Reader
+
+ k RelocKind
+ Idx Index
+}
+
+func (r *Decoder) checkErr(err error) {
+ if err != nil {
+ errorf("unexpected decoding error: %w", err)
+ }
+}
+
+func (r *Decoder) rawUvarint() uint64 {
+ x, err := readUvarint(&r.Data)
+ r.checkErr(err)
+ return x
+}
+
+// readUvarint is a type-specialized copy of encoding/binary.ReadUvarint.
+// This avoids the interface conversion and thus has better escape properties,
+// which flows up the stack.
+func readUvarint(r *strings.Reader) (uint64, error) {
+ var x uint64
+ var s uint
+ for i := 0; i < binary.MaxVarintLen64; i++ {
+ b, err := r.ReadByte()
+ if err != nil {
+ if i > 0 && err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return x, err
+ }
+ if b < 0x80 {
+ if i == binary.MaxVarintLen64-1 && b > 1 {
+ return x, overflow
+ }
+ return x | uint64(b)<> 1)
+ if ux&1 != 0 {
+ x = ^x
+ }
+ return x
+}
+
+func (r *Decoder) rawReloc(k RelocKind, idx int) Index {
+ e := r.Relocs[idx]
+ assert(e.Kind == k)
+ return e.Idx
+}
+
+// Sync decodes a sync marker from the element bitstream and asserts
+// that it matches the expected marker.
+//
+// If r.common.sync is false, then Sync is a no-op.
+func (r *Decoder) Sync(mWant SyncMarker) {
+ if !r.common.sync {
+ return
+ }
+
+ pos, _ := r.Data.Seek(0, io.SeekCurrent)
+ mHave := SyncMarker(r.rawUvarint())
+ writerPCs := make([]int, r.rawUvarint())
+ for i := range writerPCs {
+ writerPCs[i] = int(r.rawUvarint())
+ }
+
+ if mHave == mWant {
+ return
+ }
+
+ // There's some tension here between printing:
+ //
+ // (1) full file paths that tools can recognize (e.g., so emacs
+ // hyperlinks the "file:line" text for easy navigation), or
+ //
+ // (2) short file paths that are easier for humans to read (e.g., by
+ // omitting redundant or irrelevant details, so it's easier to
+ // focus on the useful bits that remain).
+ //
+ // The current formatting favors the former, as it seems more
+ // helpful in practice. But perhaps the formatting could be improved
+ // to better address both concerns. For example, use relative file
+ // paths if they would be shorter, or rewrite file paths to contain
+ // "$GOROOT" (like objabi.AbsFile does) if tools can be taught how
+ // to reliably expand that again.
+
+ fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos)
+
+ fmt.Printf("\nfound %v, written at:\n", mHave)
+ if len(writerPCs) == 0 {
+ fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath)
+ }
+ for _, pc := range writerPCs {
+ fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc)))
+ }
+
+ fmt.Printf("\nexpected %v, reading at:\n", mWant)
+ var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size?
+ n := runtime.Callers(2, readerPCs[:])
+ for _, pc := range fmtFrames(readerPCs[:n]...) {
+ fmt.Printf("\t%s\n", pc)
+ }
+
+ // We already printed a stack trace for the reader, so now we can
+ // simply exit. Printing a second one with panic or base.Fatalf
+ // would just be noise.
+ os.Exit(1)
+}
+
+// Bool decodes and returns a bool value from the element bitstream.
+func (r *Decoder) Bool() bool {
+ r.Sync(SyncBool)
+ x, err := r.Data.ReadByte()
+ r.checkErr(err)
+ assert(x < 2)
+ return x != 0
+}
+
+// Int64 decodes and returns an int64 value from the element bitstream.
+func (r *Decoder) Int64() int64 {
+ r.Sync(SyncInt64)
+ return r.rawVarint()
+}
+
+// Uint64 decodes and returns a uint64 value from the element bitstream.
+func (r *Decoder) Uint64() uint64 {
+ r.Sync(SyncUint64)
+ return r.rawUvarint()
+}
+
+// Len decodes and returns a non-negative int value from the element bitstream.
+func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v }
+
+// Int decodes and returns an int value from the element bitstream.
+func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v }
+
+// Uint decodes and returns a uint value from the element bitstream.
+func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v }
+
+// Code decodes a Code value from the element bitstream and returns
+// its ordinal value. It's the caller's responsibility to convert the
+// result to an appropriate Code type.
+//
+// TODO(mdempsky): Ideally this method would have signature "Code[T
+// Code] T" instead, but we don't allow generic methods and the
+// compiler can't depend on generics yet anyway.
+func (r *Decoder) Code(mark SyncMarker) int {
+ r.Sync(mark)
+ return r.Len()
+}
+
+// Reloc decodes a relocation of expected section k from the element
+// bitstream and returns an index to the referenced element.
+func (r *Decoder) Reloc(k RelocKind) Index {
+ r.Sync(SyncUseReloc)
+ return r.rawReloc(k, r.Len())
+}
+
+// String decodes and returns a string value from the element
+// bitstream.
+func (r *Decoder) String() string {
+ r.Sync(SyncString)
+ return r.common.StringIdx(r.Reloc(RelocString))
+}
+
+// Strings decodes and returns a variable-length slice of strings from
+// the element bitstream.
+func (r *Decoder) Strings() []string {
+ res := make([]string, r.Len())
+ for i := range res {
+ res[i] = r.String()
+ }
+ return res
+}
+
+// Value decodes and returns a constant.Value from the element
+// bitstream.
+func (r *Decoder) Value() constant.Value {
+ r.Sync(SyncValue)
+ isComplex := r.Bool()
+ val := r.scalar()
+ if isComplex {
+ val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar()))
+ }
+ return val
+}
+
+func (r *Decoder) scalar() constant.Value {
+ switch tag := CodeVal(r.Code(SyncVal)); tag {
+ default:
+ panic(fmt.Errorf("unexpected scalar tag: %v", tag))
+
+ case ValBool:
+ return constant.MakeBool(r.Bool())
+ case ValString:
+ return constant.MakeString(r.String())
+ case ValInt64:
+ return constant.MakeInt64(r.Int64())
+ case ValBigInt:
+ return constant.Make(r.bigInt())
+ case ValBigRat:
+ num := r.bigInt()
+ denom := r.bigInt()
+ return constant.Make(new(big.Rat).SetFrac(num, denom))
+ case ValBigFloat:
+ return constant.Make(r.bigFloat())
+ }
+}
+
+func (r *Decoder) bigInt() *big.Int {
+ v := new(big.Int).SetBytes([]byte(r.String()))
+ if r.Bool() {
+ v.Neg(v)
+ }
+ return v
+}
+
+func (r *Decoder) bigFloat() *big.Float {
+ v := new(big.Float).SetPrec(512)
+ assert(v.UnmarshalText([]byte(r.String())) == nil)
+ return v
+}
+
+// @@@ Helpers
+
+// TODO(mdempsky): These should probably be removed. I think they're a
+// smell that the export data format is not yet quite right.
+
+// PeekPkgPath returns the package path for the specified package
+// index.
+func (pr *PkgDecoder) PeekPkgPath(idx Index) string {
+ var path string
+ {
+ r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef)
+ path = r.String()
+ pr.RetireDecoder(&r)
+ }
+ if path == "" {
+ path = pr.pkgPath
+ }
+ return path
+}
+
+// PeekObj returns the package path, object name, and CodeObj for the
+// specified object index.
+func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) {
+ var ridx Index
+ var name string
+ var rcode int
+ {
+ r := pr.TempDecoder(RelocName, idx, SyncObject1)
+ r.Sync(SyncSym)
+ r.Sync(SyncPkg)
+ ridx = r.Reloc(RelocPkg)
+ name = r.String()
+ rcode = r.Code(SyncCodeObj)
+ pr.RetireDecoder(&r)
+ }
+
+ path := pr.PeekPkgPath(ridx)
+ assert(name != "")
+
+ tag := CodeObj(rcode)
+
+ return path, name, tag
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/doc.go b/vendor/golang.org/x/tools/internal/pkgbits/doc.go
new file mode 100644
index 00000000..c8a2796b
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/doc.go
@@ -0,0 +1,32 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package pkgbits implements low-level coding abstractions for
+// Unified IR's export data format.
+//
+// At a low-level, a package is a collection of bitstream elements.
+// Each element has a "kind" and a dense, non-negative index.
+// Elements can be randomly accessed given their kind and index.
+//
+// Individual elements are sequences of variable-length values (e.g.,
+// integers, booleans, strings, go/constant values, cross-references
+// to other elements). Package pkgbits provides APIs for encoding and
+// decoding these low-level values, but the details of mapping
+// higher-level Go constructs into elements is left to higher-level
+// abstractions.
+//
+// Elements may cross-reference each other with "relocations." For
+// example, an element representing a pointer type has a relocation
+// referring to the element type.
+//
+// Go constructs may be composed as a constellation of multiple
+// elements. For example, a declared function may have one element to
+// describe the object (e.g., its name, type, position), and a
+// separate element to describe its function body. This allows readers
+// some flexibility in efficiently seeking or re-reading data (e.g.,
+// inlining requires re-reading the function body for each inlined
+// call, without needing to re-read the object-level details).
+//
+// This is a copy of internal/pkgbits in the Go implementation.
+package pkgbits
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go
new file mode 100644
index 00000000..6482617a
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go
@@ -0,0 +1,383 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import (
+ "bytes"
+ "crypto/md5"
+ "encoding/binary"
+ "go/constant"
+ "io"
+ "math/big"
+ "runtime"
+)
+
+// currentVersion is the current version number.
+//
+// - v0: initial prototype
+//
+// - v1: adds the flags uint32 word
+const currentVersion uint32 = 1
+
+// A PkgEncoder provides methods for encoding a package's Unified IR
+// export data.
+type PkgEncoder struct {
+ // elems holds the bitstream for previously encoded elements.
+ elems [numRelocs][]string
+
+ // stringsIdx maps previously encoded strings to their index within
+ // the RelocString section, to allow deduplication. That is,
+ // elems[RelocString][stringsIdx[s]] == s (if present).
+ stringsIdx map[string]Index
+
+ // syncFrames is the number of frames to write at each sync
+ // marker. A negative value means sync markers are omitted.
+ syncFrames int
+}
+
+// SyncMarkers reports whether pw uses sync markers.
+func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 }
+
+// NewPkgEncoder returns an initialized PkgEncoder.
+//
+// syncFrames is the number of caller frames that should be serialized
+// at Sync points. Serializing additional frames results in larger
+// export data files, but can help diagnosing desync errors in
+// higher-level Unified IR reader/writer code. If syncFrames is
+// negative, then sync markers are omitted entirely.
+func NewPkgEncoder(syncFrames int) PkgEncoder {
+ return PkgEncoder{
+ stringsIdx: make(map[string]Index),
+ syncFrames: syncFrames,
+ }
+}
+
+// DumpTo writes the package's encoded data to out0 and returns the
+// package fingerprint.
+func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) {
+ h := md5.New()
+ out := io.MultiWriter(out0, h)
+
+ writeUint32 := func(x uint32) {
+ assert(binary.Write(out, binary.LittleEndian, x) == nil)
+ }
+
+ writeUint32(currentVersion)
+
+ var flags uint32
+ if pw.SyncMarkers() {
+ flags |= flagSyncMarkers
+ }
+ writeUint32(flags)
+
+ // Write elemEndsEnds.
+ var sum uint32
+ for _, elems := range &pw.elems {
+ sum += uint32(len(elems))
+ writeUint32(sum)
+ }
+
+ // Write elemEnds.
+ sum = 0
+ for _, elems := range &pw.elems {
+ for _, elem := range elems {
+ sum += uint32(len(elem))
+ writeUint32(sum)
+ }
+ }
+
+ // Write elemData.
+ for _, elems := range &pw.elems {
+ for _, elem := range elems {
+ _, err := io.WriteString(out, elem)
+ assert(err == nil)
+ }
+ }
+
+ // Write fingerprint.
+ copy(fingerprint[:], h.Sum(nil))
+ _, err := out0.Write(fingerprint[:])
+ assert(err == nil)
+
+ return
+}
+
+// StringIdx adds a string value to the strings section, if not
+// already present, and returns its index.
+func (pw *PkgEncoder) StringIdx(s string) Index {
+ if idx, ok := pw.stringsIdx[s]; ok {
+ assert(pw.elems[RelocString][idx] == s)
+ return idx
+ }
+
+ idx := Index(len(pw.elems[RelocString]))
+ pw.elems[RelocString] = append(pw.elems[RelocString], s)
+ pw.stringsIdx[s] = idx
+ return idx
+}
+
+// NewEncoder returns an Encoder for a new element within the given
+// section, and encodes the given SyncMarker as the start of the
+// element bitstream.
+func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder {
+ e := pw.NewEncoderRaw(k)
+ e.Sync(marker)
+ return e
+}
+
+// NewEncoderRaw returns an Encoder for a new element within the given
+// section.
+//
+// Most callers should use NewEncoder instead.
+func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder {
+ idx := Index(len(pw.elems[k]))
+ pw.elems[k] = append(pw.elems[k], "") // placeholder
+
+ return Encoder{
+ p: pw,
+ k: k,
+ Idx: idx,
+ }
+}
+
+// An Encoder provides methods for encoding an individual element's
+// bitstream data.
+type Encoder struct {
+ p *PkgEncoder
+
+ Relocs []RelocEnt
+ RelocMap map[RelocEnt]uint32
+ Data bytes.Buffer // accumulated element bitstream data
+
+ encodingRelocHeader bool
+
+ k RelocKind
+ Idx Index // index within relocation section
+}
+
+// Flush finalizes the element's bitstream and returns its Index.
+func (w *Encoder) Flush() Index {
+ var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved
+
+ // Backup the data so we write the relocations at the front.
+ var tmp bytes.Buffer
+ io.Copy(&tmp, &w.Data)
+
+ // TODO(mdempsky): Consider writing these out separately so they're
+ // easier to strip, along with function bodies, so that we can prune
+ // down to just the data that's relevant to go/types.
+ if w.encodingRelocHeader {
+ panic("encodingRelocHeader already true; recursive flush?")
+ }
+ w.encodingRelocHeader = true
+ w.Sync(SyncRelocs)
+ w.Len(len(w.Relocs))
+ for _, rEnt := range w.Relocs {
+ w.Sync(SyncReloc)
+ w.Len(int(rEnt.Kind))
+ w.Len(int(rEnt.Idx))
+ }
+
+ io.Copy(&sb, &w.Data)
+ io.Copy(&sb, &tmp)
+ w.p.elems[w.k][w.Idx] = sb.String()
+
+ return w.Idx
+}
+
+func (w *Encoder) checkErr(err error) {
+ if err != nil {
+ errorf("unexpected encoding error: %v", err)
+ }
+}
+
+func (w *Encoder) rawUvarint(x uint64) {
+ var buf [binary.MaxVarintLen64]byte
+ n := binary.PutUvarint(buf[:], x)
+ _, err := w.Data.Write(buf[:n])
+ w.checkErr(err)
+}
+
+func (w *Encoder) rawVarint(x int64) {
+ // Zig-zag encode.
+ ux := uint64(x) << 1
+ if x < 0 {
+ ux = ^ux
+ }
+
+ w.rawUvarint(ux)
+}
+
+func (w *Encoder) rawReloc(r RelocKind, idx Index) int {
+ e := RelocEnt{r, idx}
+ if w.RelocMap != nil {
+ if i, ok := w.RelocMap[e]; ok {
+ return int(i)
+ }
+ } else {
+ w.RelocMap = make(map[RelocEnt]uint32)
+ }
+
+ i := len(w.Relocs)
+ w.RelocMap[e] = uint32(i)
+ w.Relocs = append(w.Relocs, e)
+ return i
+}
+
+func (w *Encoder) Sync(m SyncMarker) {
+ if !w.p.SyncMarkers() {
+ return
+ }
+
+ // Writing out stack frame string references requires working
+ // relocations, but writing out the relocations themselves involves
+ // sync markers. To prevent infinite recursion, we simply trim the
+ // stack frame for sync markers within the relocation header.
+ var frames []string
+ if !w.encodingRelocHeader && w.p.syncFrames > 0 {
+ pcs := make([]uintptr, w.p.syncFrames)
+ n := runtime.Callers(2, pcs)
+ frames = fmtFrames(pcs[:n]...)
+ }
+
+ // TODO(mdempsky): Save space by writing out stack frames as a
+ // linked list so we can share common stack frames.
+ w.rawUvarint(uint64(m))
+ w.rawUvarint(uint64(len(frames)))
+ for _, frame := range frames {
+ w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame))))
+ }
+}
+
+// Bool encodes and writes a bool value into the element bitstream,
+// and then returns the bool value.
+//
+// For simple, 2-alternative encodings, the idiomatic way to call Bool
+// is something like:
+//
+// if w.Bool(x != 0) {
+// // alternative #1
+// } else {
+// // alternative #2
+// }
+//
+// For multi-alternative encodings, use Code instead.
+func (w *Encoder) Bool(b bool) bool {
+ w.Sync(SyncBool)
+ var x byte
+ if b {
+ x = 1
+ }
+ err := w.Data.WriteByte(x)
+ w.checkErr(err)
+ return b
+}
+
+// Int64 encodes and writes an int64 value into the element bitstream.
+func (w *Encoder) Int64(x int64) {
+ w.Sync(SyncInt64)
+ w.rawVarint(x)
+}
+
+// Uint64 encodes and writes a uint64 value into the element bitstream.
+func (w *Encoder) Uint64(x uint64) {
+ w.Sync(SyncUint64)
+ w.rawUvarint(x)
+}
+
+// Len encodes and writes a non-negative int value into the element bitstream.
+func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) }
+
+// Int encodes and writes an int value into the element bitstream.
+func (w *Encoder) Int(x int) { w.Int64(int64(x)) }
+
+// Uint encodes and writes a uint value into the element bitstream.
+func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) }
+
+// Reloc encodes and writes a relocation for the given (section,
+// index) pair into the element bitstream.
+//
+// Note: Only the index is formally written into the element
+// bitstream, so bitstream decoders must know from context which
+// section an encoded relocation refers to.
+func (w *Encoder) Reloc(r RelocKind, idx Index) {
+ w.Sync(SyncUseReloc)
+ w.Len(w.rawReloc(r, idx))
+}
+
+// Code encodes and writes a Code value into the element bitstream.
+func (w *Encoder) Code(c Code) {
+ w.Sync(c.Marker())
+ w.Len(c.Value())
+}
+
+// String encodes and writes a string value into the element
+// bitstream.
+//
+// Internally, strings are deduplicated by adding them to the strings
+// section (if not already present), and then writing a relocation
+// into the element bitstream.
+func (w *Encoder) String(s string) {
+ w.Sync(SyncString)
+ w.Reloc(RelocString, w.p.StringIdx(s))
+}
+
+// Strings encodes and writes a variable-length slice of strings into
+// the element bitstream.
+func (w *Encoder) Strings(ss []string) {
+ w.Len(len(ss))
+ for _, s := range ss {
+ w.String(s)
+ }
+}
+
+// Value encodes and writes a constant.Value into the element
+// bitstream.
+func (w *Encoder) Value(val constant.Value) {
+ w.Sync(SyncValue)
+ if w.Bool(val.Kind() == constant.Complex) {
+ w.scalar(constant.Real(val))
+ w.scalar(constant.Imag(val))
+ } else {
+ w.scalar(val)
+ }
+}
+
+func (w *Encoder) scalar(val constant.Value) {
+ switch v := constant.Val(val).(type) {
+ default:
+ errorf("unhandled %v (%v)", val, val.Kind())
+ case bool:
+ w.Code(ValBool)
+ w.Bool(v)
+ case string:
+ w.Code(ValString)
+ w.String(v)
+ case int64:
+ w.Code(ValInt64)
+ w.Int64(v)
+ case *big.Int:
+ w.Code(ValBigInt)
+ w.bigInt(v)
+ case *big.Rat:
+ w.Code(ValBigRat)
+ w.bigInt(v.Num())
+ w.bigInt(v.Denom())
+ case *big.Float:
+ w.Code(ValBigFloat)
+ w.bigFloat(v)
+ }
+}
+
+func (w *Encoder) bigInt(v *big.Int) {
+ b := v.Bytes()
+ w.String(string(b)) // TODO: More efficient encoding.
+ w.Bool(v.Sign() < 0)
+}
+
+func (w *Encoder) bigFloat(v *big.Float) {
+ b := v.Append(nil, 'p', -1)
+ w.String(string(b)) // TODO: More efficient encoding.
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/flags.go b/vendor/golang.org/x/tools/internal/pkgbits/flags.go
new file mode 100644
index 00000000..65422274
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/flags.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+const (
+ flagSyncMarkers = 1 << iota // file format contains sync markers
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go
new file mode 100644
index 00000000..5294f6a6
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go
@@ -0,0 +1,21 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.7
+// +build !go1.7
+
+// TODO(mdempsky): Remove after #44505 is resolved
+
+package pkgbits
+
+import "runtime"
+
+func walkFrames(pcs []uintptr, visit frameVisitor) {
+ for _, pc := range pcs {
+ fn := runtime.FuncForPC(pc)
+ file, line := fn.FileLine(pc)
+
+ visit(file, line, fn.Name(), pc-fn.Entry())
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go
new file mode 100644
index 00000000..2324ae7a
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go
@@ -0,0 +1,28 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.7
+// +build go1.7
+
+package pkgbits
+
+import "runtime"
+
+// walkFrames calls visit for each call frame represented by pcs.
+//
+// pcs should be a slice of PCs, as returned by runtime.Callers.
+func walkFrames(pcs []uintptr, visit frameVisitor) {
+ if len(pcs) == 0 {
+ return
+ }
+
+ frames := runtime.CallersFrames(pcs)
+ for {
+ frame, more := frames.Next()
+ visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry)
+ if !more {
+ return
+ }
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go
new file mode 100644
index 00000000..fcdfb97c
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go
@@ -0,0 +1,42 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+// A RelocKind indicates a particular section within a unified IR export.
+type RelocKind int32
+
+// An Index represents a bitstream element index within a particular
+// section.
+type Index int32
+
+// A relocEnt (relocation entry) is an entry in an element's local
+// reference table.
+//
+// TODO(mdempsky): Rename this too.
+type RelocEnt struct {
+ Kind RelocKind
+ Idx Index
+}
+
+// Reserved indices within the meta relocation section.
+const (
+ PublicRootIdx Index = 0
+ PrivateRootIdx Index = 1
+)
+
+const (
+ RelocString RelocKind = iota
+ RelocMeta
+ RelocPosBase
+ RelocPkg
+ RelocName
+ RelocType
+ RelocObj
+ RelocObjExt
+ RelocObjDict
+ RelocBody
+
+ numRelocs = iota
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/support.go b/vendor/golang.org/x/tools/internal/pkgbits/support.go
new file mode 100644
index 00000000..ad26d3b2
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/support.go
@@ -0,0 +1,17 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import "fmt"
+
+func assert(b bool) {
+ if !b {
+ panic("assertion failed")
+ }
+}
+
+func errorf(format string, args ...interface{}) {
+ panic(fmt.Errorf(format, args...))
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/internal/pkgbits/sync.go
new file mode 100644
index 00000000..5bd51ef7
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/sync.go
@@ -0,0 +1,113 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import (
+ "fmt"
+ "strings"
+)
+
+// fmtFrames formats a backtrace for reporting reader/writer desyncs.
+func fmtFrames(pcs ...uintptr) []string {
+ res := make([]string, 0, len(pcs))
+ walkFrames(pcs, func(file string, line int, name string, offset uintptr) {
+ // Trim package from function name. It's just redundant noise.
+ name = strings.TrimPrefix(name, "cmd/compile/internal/noder.")
+
+ res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset))
+ })
+ return res
+}
+
+type frameVisitor func(file string, line int, name string, offset uintptr)
+
+// SyncMarker is an enum type that represents markers that may be
+// written to export data to ensure the reader and writer stay
+// synchronized.
+type SyncMarker int
+
+//go:generate stringer -type=SyncMarker -trimprefix=Sync
+
+const (
+ _ SyncMarker = iota
+
+ // Public markers (known to go/types importers).
+
+ // Low-level coding markers.
+ SyncEOF
+ SyncBool
+ SyncInt64
+ SyncUint64
+ SyncString
+ SyncValue
+ SyncVal
+ SyncRelocs
+ SyncReloc
+ SyncUseReloc
+
+ // Higher-level object and type markers.
+ SyncPublic
+ SyncPos
+ SyncPosBase
+ SyncObject
+ SyncObject1
+ SyncPkg
+ SyncPkgDef
+ SyncMethod
+ SyncType
+ SyncTypeIdx
+ SyncTypeParamNames
+ SyncSignature
+ SyncParams
+ SyncParam
+ SyncCodeObj
+ SyncSym
+ SyncLocalIdent
+ SyncSelector
+
+ // Private markers (only known to cmd/compile).
+ SyncPrivate
+
+ SyncFuncExt
+ SyncVarExt
+ SyncTypeExt
+ SyncPragma
+
+ SyncExprList
+ SyncExprs
+ SyncExpr
+ SyncExprType
+ SyncAssign
+ SyncOp
+ SyncFuncLit
+ SyncCompLit
+
+ SyncDecl
+ SyncFuncBody
+ SyncOpenScope
+ SyncCloseScope
+ SyncCloseAnotherScope
+ SyncDeclNames
+ SyncDeclName
+
+ SyncStmts
+ SyncBlockStmt
+ SyncIfStmt
+ SyncForStmt
+ SyncSwitchStmt
+ SyncRangeStmt
+ SyncCaseClause
+ SyncCommClause
+ SyncSelectStmt
+ SyncDecls
+ SyncLabeledStmt
+ SyncUseObjLocal
+ SyncAddLocal
+ SyncLinkname
+ SyncStmt1
+ SyncStmtsEnd
+ SyncLabel
+ SyncOptLabel
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go
new file mode 100644
index 00000000..4a5b0ca5
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go
@@ -0,0 +1,89 @@
+// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT.
+
+package pkgbits
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[SyncEOF-1]
+ _ = x[SyncBool-2]
+ _ = x[SyncInt64-3]
+ _ = x[SyncUint64-4]
+ _ = x[SyncString-5]
+ _ = x[SyncValue-6]
+ _ = x[SyncVal-7]
+ _ = x[SyncRelocs-8]
+ _ = x[SyncReloc-9]
+ _ = x[SyncUseReloc-10]
+ _ = x[SyncPublic-11]
+ _ = x[SyncPos-12]
+ _ = x[SyncPosBase-13]
+ _ = x[SyncObject-14]
+ _ = x[SyncObject1-15]
+ _ = x[SyncPkg-16]
+ _ = x[SyncPkgDef-17]
+ _ = x[SyncMethod-18]
+ _ = x[SyncType-19]
+ _ = x[SyncTypeIdx-20]
+ _ = x[SyncTypeParamNames-21]
+ _ = x[SyncSignature-22]
+ _ = x[SyncParams-23]
+ _ = x[SyncParam-24]
+ _ = x[SyncCodeObj-25]
+ _ = x[SyncSym-26]
+ _ = x[SyncLocalIdent-27]
+ _ = x[SyncSelector-28]
+ _ = x[SyncPrivate-29]
+ _ = x[SyncFuncExt-30]
+ _ = x[SyncVarExt-31]
+ _ = x[SyncTypeExt-32]
+ _ = x[SyncPragma-33]
+ _ = x[SyncExprList-34]
+ _ = x[SyncExprs-35]
+ _ = x[SyncExpr-36]
+ _ = x[SyncExprType-37]
+ _ = x[SyncAssign-38]
+ _ = x[SyncOp-39]
+ _ = x[SyncFuncLit-40]
+ _ = x[SyncCompLit-41]
+ _ = x[SyncDecl-42]
+ _ = x[SyncFuncBody-43]
+ _ = x[SyncOpenScope-44]
+ _ = x[SyncCloseScope-45]
+ _ = x[SyncCloseAnotherScope-46]
+ _ = x[SyncDeclNames-47]
+ _ = x[SyncDeclName-48]
+ _ = x[SyncStmts-49]
+ _ = x[SyncBlockStmt-50]
+ _ = x[SyncIfStmt-51]
+ _ = x[SyncForStmt-52]
+ _ = x[SyncSwitchStmt-53]
+ _ = x[SyncRangeStmt-54]
+ _ = x[SyncCaseClause-55]
+ _ = x[SyncCommClause-56]
+ _ = x[SyncSelectStmt-57]
+ _ = x[SyncDecls-58]
+ _ = x[SyncLabeledStmt-59]
+ _ = x[SyncUseObjLocal-60]
+ _ = x[SyncAddLocal-61]
+ _ = x[SyncLinkname-62]
+ _ = x[SyncStmt1-63]
+ _ = x[SyncStmtsEnd-64]
+ _ = x[SyncLabel-65]
+ _ = x[SyncOptLabel-66]
+}
+
+const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel"
+
+var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458}
+
+func (i SyncMarker) String() string {
+ i -= 1
+ if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) {
+ return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")"
+ }
+ return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]]
+}
diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go
new file mode 100644
index 00000000..a928acf2
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/stdlib/manifest.go
@@ -0,0 +1,17431 @@
+// 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.
+
+// Code generated by generate.go. DO NOT EDIT.
+
+package stdlib
+
+var PackageSymbols = map[string][]Symbol{
+ "archive/tar": {
+ {"(*Header).FileInfo", Method, 1},
+ {"(*Reader).Next", Method, 0},
+ {"(*Reader).Read", Method, 0},
+ {"(*Writer).AddFS", Method, 22},
+ {"(*Writer).Close", Method, 0},
+ {"(*Writer).Flush", Method, 0},
+ {"(*Writer).Write", Method, 0},
+ {"(*Writer).WriteHeader", Method, 0},
+ {"(Format).String", Method, 10},
+ {"ErrFieldTooLong", Var, 0},
+ {"ErrHeader", Var, 0},
+ {"ErrInsecurePath", Var, 20},
+ {"ErrWriteAfterClose", Var, 0},
+ {"ErrWriteTooLong", Var, 0},
+ {"FileInfoHeader", Func, 1},
+ {"FileInfoNames", Type, 23},
+ {"Format", Type, 10},
+ {"FormatGNU", Const, 10},
+ {"FormatPAX", Const, 10},
+ {"FormatUSTAR", Const, 10},
+ {"FormatUnknown", Const, 10},
+ {"Header", Type, 0},
+ {"Header.AccessTime", Field, 0},
+ {"Header.ChangeTime", Field, 0},
+ {"Header.Devmajor", Field, 0},
+ {"Header.Devminor", Field, 0},
+ {"Header.Format", Field, 10},
+ {"Header.Gid", Field, 0},
+ {"Header.Gname", Field, 0},
+ {"Header.Linkname", Field, 0},
+ {"Header.ModTime", Field, 0},
+ {"Header.Mode", Field, 0},
+ {"Header.Name", Field, 0},
+ {"Header.PAXRecords", Field, 10},
+ {"Header.Size", Field, 0},
+ {"Header.Typeflag", Field, 0},
+ {"Header.Uid", Field, 0},
+ {"Header.Uname", Field, 0},
+ {"Header.Xattrs", Field, 3},
+ {"NewReader", Func, 0},
+ {"NewWriter", Func, 0},
+ {"Reader", Type, 0},
+ {"TypeBlock", Const, 0},
+ {"TypeChar", Const, 0},
+ {"TypeCont", Const, 0},
+ {"TypeDir", Const, 0},
+ {"TypeFifo", Const, 0},
+ {"TypeGNULongLink", Const, 1},
+ {"TypeGNULongName", Const, 1},
+ {"TypeGNUSparse", Const, 3},
+ {"TypeLink", Const, 0},
+ {"TypeReg", Const, 0},
+ {"TypeRegA", Const, 0},
+ {"TypeSymlink", Const, 0},
+ {"TypeXGlobalHeader", Const, 0},
+ {"TypeXHeader", Const, 0},
+ {"Writer", Type, 0},
+ },
+ "archive/zip": {
+ {"(*File).DataOffset", Method, 2},
+ {"(*File).FileInfo", Method, 0},
+ {"(*File).ModTime", Method, 0},
+ {"(*File).Mode", Method, 0},
+ {"(*File).Open", Method, 0},
+ {"(*File).OpenRaw", Method, 17},
+ {"(*File).SetModTime", Method, 0},
+ {"(*File).SetMode", Method, 0},
+ {"(*FileHeader).FileInfo", Method, 0},
+ {"(*FileHeader).ModTime", Method, 0},
+ {"(*FileHeader).Mode", Method, 0},
+ {"(*FileHeader).SetModTime", Method, 0},
+ {"(*FileHeader).SetMode", Method, 0},
+ {"(*ReadCloser).Close", Method, 0},
+ {"(*ReadCloser).Open", Method, 16},
+ {"(*ReadCloser).RegisterDecompressor", Method, 6},
+ {"(*Reader).Open", Method, 16},
+ {"(*Reader).RegisterDecompressor", Method, 6},
+ {"(*Writer).AddFS", Method, 22},
+ {"(*Writer).Close", Method, 0},
+ {"(*Writer).Copy", Method, 17},
+ {"(*Writer).Create", Method, 0},
+ {"(*Writer).CreateHeader", Method, 0},
+ {"(*Writer).CreateRaw", Method, 17},
+ {"(*Writer).Flush", Method, 4},
+ {"(*Writer).RegisterCompressor", Method, 6},
+ {"(*Writer).SetComment", Method, 10},
+ {"(*Writer).SetOffset", Method, 5},
+ {"Compressor", Type, 2},
+ {"Decompressor", Type, 2},
+ {"Deflate", Const, 0},
+ {"ErrAlgorithm", Var, 0},
+ {"ErrChecksum", Var, 0},
+ {"ErrFormat", Var, 0},
+ {"ErrInsecurePath", Var, 20},
+ {"File", Type, 0},
+ {"File.FileHeader", Field, 0},
+ {"FileHeader", Type, 0},
+ {"FileHeader.CRC32", Field, 0},
+ {"FileHeader.Comment", Field, 0},
+ {"FileHeader.CompressedSize", Field, 0},
+ {"FileHeader.CompressedSize64", Field, 1},
+ {"FileHeader.CreatorVersion", Field, 0},
+ {"FileHeader.ExternalAttrs", Field, 0},
+ {"FileHeader.Extra", Field, 0},
+ {"FileHeader.Flags", Field, 0},
+ {"FileHeader.Method", Field, 0},
+ {"FileHeader.Modified", Field, 10},
+ {"FileHeader.ModifiedDate", Field, 0},
+ {"FileHeader.ModifiedTime", Field, 0},
+ {"FileHeader.Name", Field, 0},
+ {"FileHeader.NonUTF8", Field, 10},
+ {"FileHeader.ReaderVersion", Field, 0},
+ {"FileHeader.UncompressedSize", Field, 0},
+ {"FileHeader.UncompressedSize64", Field, 1},
+ {"FileInfoHeader", Func, 0},
+ {"NewReader", Func, 0},
+ {"NewWriter", Func, 0},
+ {"OpenReader", Func, 0},
+ {"ReadCloser", Type, 0},
+ {"ReadCloser.Reader", Field, 0},
+ {"Reader", Type, 0},
+ {"Reader.Comment", Field, 0},
+ {"Reader.File", Field, 0},
+ {"RegisterCompressor", Func, 2},
+ {"RegisterDecompressor", Func, 2},
+ {"Store", Const, 0},
+ {"Writer", Type, 0},
+ },
+ "bufio": {
+ {"(*Reader).Buffered", Method, 0},
+ {"(*Reader).Discard", Method, 5},
+ {"(*Reader).Peek", Method, 0},
+ {"(*Reader).Read", Method, 0},
+ {"(*Reader).ReadByte", Method, 0},
+ {"(*Reader).ReadBytes", Method, 0},
+ {"(*Reader).ReadLine", Method, 0},
+ {"(*Reader).ReadRune", Method, 0},
+ {"(*Reader).ReadSlice", Method, 0},
+ {"(*Reader).ReadString", Method, 0},
+ {"(*Reader).Reset", Method, 2},
+ {"(*Reader).Size", Method, 10},
+ {"(*Reader).UnreadByte", Method, 0},
+ {"(*Reader).UnreadRune", Method, 0},
+ {"(*Reader).WriteTo", Method, 1},
+ {"(*Scanner).Buffer", Method, 6},
+ {"(*Scanner).Bytes", Method, 1},
+ {"(*Scanner).Err", Method, 1},
+ {"(*Scanner).Scan", Method, 1},
+ {"(*Scanner).Split", Method, 1},
+ {"(*Scanner).Text", Method, 1},
+ {"(*Writer).Available", Method, 0},
+ {"(*Writer).AvailableBuffer", Method, 18},
+ {"(*Writer).Buffered", Method, 0},
+ {"(*Writer).Flush", Method, 0},
+ {"(*Writer).ReadFrom", Method, 1},
+ {"(*Writer).Reset", Method, 2},
+ {"(*Writer).Size", Method, 10},
+ {"(*Writer).Write", Method, 0},
+ {"(*Writer).WriteByte", Method, 0},
+ {"(*Writer).WriteRune", Method, 0},
+ {"(*Writer).WriteString", Method, 0},
+ {"(ReadWriter).Available", Method, 0},
+ {"(ReadWriter).AvailableBuffer", Method, 18},
+ {"(ReadWriter).Discard", Method, 5},
+ {"(ReadWriter).Flush", Method, 0},
+ {"(ReadWriter).Peek", Method, 0},
+ {"(ReadWriter).Read", Method, 0},
+ {"(ReadWriter).ReadByte", Method, 0},
+ {"(ReadWriter).ReadBytes", Method, 0},
+ {"(ReadWriter).ReadFrom", Method, 1},
+ {"(ReadWriter).ReadLine", Method, 0},
+ {"(ReadWriter).ReadRune", Method, 0},
+ {"(ReadWriter).ReadSlice", Method, 0},
+ {"(ReadWriter).ReadString", Method, 0},
+ {"(ReadWriter).UnreadByte", Method, 0},
+ {"(ReadWriter).UnreadRune", Method, 0},
+ {"(ReadWriter).Write", Method, 0},
+ {"(ReadWriter).WriteByte", Method, 0},
+ {"(ReadWriter).WriteRune", Method, 0},
+ {"(ReadWriter).WriteString", Method, 0},
+ {"(ReadWriter).WriteTo", Method, 1},
+ {"ErrAdvanceTooFar", Var, 1},
+ {"ErrBadReadCount", Var, 15},
+ {"ErrBufferFull", Var, 0},
+ {"ErrFinalToken", Var, 6},
+ {"ErrInvalidUnreadByte", Var, 0},
+ {"ErrInvalidUnreadRune", Var, 0},
+ {"ErrNegativeAdvance", Var, 1},
+ {"ErrNegativeCount", Var, 0},
+ {"ErrTooLong", Var, 1},
+ {"MaxScanTokenSize", Const, 1},
+ {"NewReadWriter", Func, 0},
+ {"NewReader", Func, 0},
+ {"NewReaderSize", Func, 0},
+ {"NewScanner", Func, 1},
+ {"NewWriter", Func, 0},
+ {"NewWriterSize", Func, 0},
+ {"ReadWriter", Type, 0},
+ {"ReadWriter.Reader", Field, 0},
+ {"ReadWriter.Writer", Field, 0},
+ {"Reader", Type, 0},
+ {"ScanBytes", Func, 1},
+ {"ScanLines", Func, 1},
+ {"ScanRunes", Func, 1},
+ {"ScanWords", Func, 1},
+ {"Scanner", Type, 1},
+ {"SplitFunc", Type, 1},
+ {"Writer", Type, 0},
+ },
+ "bytes": {
+ {"(*Buffer).Available", Method, 21},
+ {"(*Buffer).AvailableBuffer", Method, 21},
+ {"(*Buffer).Bytes", Method, 0},
+ {"(*Buffer).Cap", Method, 5},
+ {"(*Buffer).Grow", Method, 1},
+ {"(*Buffer).Len", Method, 0},
+ {"(*Buffer).Next", Method, 0},
+ {"(*Buffer).Read", Method, 0},
+ {"(*Buffer).ReadByte", Method, 0},
+ {"(*Buffer).ReadBytes", Method, 0},
+ {"(*Buffer).ReadFrom", Method, 0},
+ {"(*Buffer).ReadRune", Method, 0},
+ {"(*Buffer).ReadString", Method, 0},
+ {"(*Buffer).Reset", Method, 0},
+ {"(*Buffer).String", Method, 0},
+ {"(*Buffer).Truncate", Method, 0},
+ {"(*Buffer).UnreadByte", Method, 0},
+ {"(*Buffer).UnreadRune", Method, 0},
+ {"(*Buffer).Write", Method, 0},
+ {"(*Buffer).WriteByte", Method, 0},
+ {"(*Buffer).WriteRune", Method, 0},
+ {"(*Buffer).WriteString", Method, 0},
+ {"(*Buffer).WriteTo", Method, 0},
+ {"(*Reader).Len", Method, 0},
+ {"(*Reader).Read", Method, 0},
+ {"(*Reader).ReadAt", Method, 0},
+ {"(*Reader).ReadByte", Method, 0},
+ {"(*Reader).ReadRune", Method, 0},
+ {"(*Reader).Reset", Method, 7},
+ {"(*Reader).Seek", Method, 0},
+ {"(*Reader).Size", Method, 5},
+ {"(*Reader).UnreadByte", Method, 0},
+ {"(*Reader).UnreadRune", Method, 0},
+ {"(*Reader).WriteTo", Method, 1},
+ {"Buffer", Type, 0},
+ {"Clone", Func, 20},
+ {"Compare", Func, 0},
+ {"Contains", Func, 0},
+ {"ContainsAny", Func, 7},
+ {"ContainsFunc", Func, 21},
+ {"ContainsRune", Func, 7},
+ {"Count", Func, 0},
+ {"Cut", Func, 18},
+ {"CutPrefix", Func, 20},
+ {"CutSuffix", Func, 20},
+ {"Equal", Func, 0},
+ {"EqualFold", Func, 0},
+ {"ErrTooLarge", Var, 0},
+ {"Fields", Func, 0},
+ {"FieldsFunc", Func, 0},
+ {"HasPrefix", Func, 0},
+ {"HasSuffix", Func, 0},
+ {"Index", Func, 0},
+ {"IndexAny", Func, 0},
+ {"IndexByte", Func, 0},
+ {"IndexFunc", Func, 0},
+ {"IndexRune", Func, 0},
+ {"Join", Func, 0},
+ {"LastIndex", Func, 0},
+ {"LastIndexAny", Func, 0},
+ {"LastIndexByte", Func, 5},
+ {"LastIndexFunc", Func, 0},
+ {"Map", Func, 0},
+ {"MinRead", Const, 0},
+ {"NewBuffer", Func, 0},
+ {"NewBufferString", Func, 0},
+ {"NewReader", Func, 0},
+ {"Reader", Type, 0},
+ {"Repeat", Func, 0},
+ {"Replace", Func, 0},
+ {"ReplaceAll", Func, 12},
+ {"Runes", Func, 0},
+ {"Split", Func, 0},
+ {"SplitAfter", Func, 0},
+ {"SplitAfterN", Func, 0},
+ {"SplitN", Func, 0},
+ {"Title", Func, 0},
+ {"ToLower", Func, 0},
+ {"ToLowerSpecial", Func, 0},
+ {"ToTitle", Func, 0},
+ {"ToTitleSpecial", Func, 0},
+ {"ToUpper", Func, 0},
+ {"ToUpperSpecial", Func, 0},
+ {"ToValidUTF8", Func, 13},
+ {"Trim", Func, 0},
+ {"TrimFunc", Func, 0},
+ {"TrimLeft", Func, 0},
+ {"TrimLeftFunc", Func, 0},
+ {"TrimPrefix", Func, 1},
+ {"TrimRight", Func, 0},
+ {"TrimRightFunc", Func, 0},
+ {"TrimSpace", Func, 0},
+ {"TrimSuffix", Func, 1},
+ },
+ "cmp": {
+ {"Compare", Func, 21},
+ {"Less", Func, 21},
+ {"Or", Func, 22},
+ {"Ordered", Type, 21},
+ },
+ "compress/bzip2": {
+ {"(StructuralError).Error", Method, 0},
+ {"NewReader", Func, 0},
+ {"StructuralError", Type, 0},
+ },
+ "compress/flate": {
+ {"(*ReadError).Error", Method, 0},
+ {"(*WriteError).Error", Method, 0},
+ {"(*Writer).Close", Method, 0},
+ {"(*Writer).Flush", Method, 0},
+ {"(*Writer).Reset", Method, 2},
+ {"(*Writer).Write", Method, 0},
+ {"(CorruptInputError).Error", Method, 0},
+ {"(InternalError).Error", Method, 0},
+ {"BestCompression", Const, 0},
+ {"BestSpeed", Const, 0},
+ {"CorruptInputError", Type, 0},
+ {"DefaultCompression", Const, 0},
+ {"HuffmanOnly", Const, 7},
+ {"InternalError", Type, 0},
+ {"NewReader", Func, 0},
+ {"NewReaderDict", Func, 0},
+ {"NewWriter", Func, 0},
+ {"NewWriterDict", Func, 0},
+ {"NoCompression", Const, 0},
+ {"ReadError", Type, 0},
+ {"ReadError.Err", Field, 0},
+ {"ReadError.Offset", Field, 0},
+ {"Reader", Type, 0},
+ {"Resetter", Type, 4},
+ {"WriteError", Type, 0},
+ {"WriteError.Err", Field, 0},
+ {"WriteError.Offset", Field, 0},
+ {"Writer", Type, 0},
+ },
+ "compress/gzip": {
+ {"(*Reader).Close", Method, 0},
+ {"(*Reader).Multistream", Method, 4},
+ {"(*Reader).Read", Method, 0},
+ {"(*Reader).Reset", Method, 3},
+ {"(*Writer).Close", Method, 0},
+ {"(*Writer).Flush", Method, 1},
+ {"(*Writer).Reset", Method, 2},
+ {"(*Writer).Write", Method, 0},
+ {"BestCompression", Const, 0},
+ {"BestSpeed", Const, 0},
+ {"DefaultCompression", Const, 0},
+ {"ErrChecksum", Var, 0},
+ {"ErrHeader", Var, 0},
+ {"Header", Type, 0},
+ {"Header.Comment", Field, 0},
+ {"Header.Extra", Field, 0},
+ {"Header.ModTime", Field, 0},
+ {"Header.Name", Field, 0},
+ {"Header.OS", Field, 0},
+ {"HuffmanOnly", Const, 8},
+ {"NewReader", Func, 0},
+ {"NewWriter", Func, 0},
+ {"NewWriterLevel", Func, 0},
+ {"NoCompression", Const, 0},
+ {"Reader", Type, 0},
+ {"Reader.Header", Field, 0},
+ {"Writer", Type, 0},
+ {"Writer.Header", Field, 0},
+ },
+ "compress/lzw": {
+ {"(*Reader).Close", Method, 17},
+ {"(*Reader).Read", Method, 17},
+ {"(*Reader).Reset", Method, 17},
+ {"(*Writer).Close", Method, 17},
+ {"(*Writer).Reset", Method, 17},
+ {"(*Writer).Write", Method, 17},
+ {"LSB", Const, 0},
+ {"MSB", Const, 0},
+ {"NewReader", Func, 0},
+ {"NewWriter", Func, 0},
+ {"Order", Type, 0},
+ {"Reader", Type, 17},
+ {"Writer", Type, 17},
+ },
+ "compress/zlib": {
+ {"(*Writer).Close", Method, 0},
+ {"(*Writer).Flush", Method, 0},
+ {"(*Writer).Reset", Method, 2},
+ {"(*Writer).Write", Method, 0},
+ {"BestCompression", Const, 0},
+ {"BestSpeed", Const, 0},
+ {"DefaultCompression", Const, 0},
+ {"ErrChecksum", Var, 0},
+ {"ErrDictionary", Var, 0},
+ {"ErrHeader", Var, 0},
+ {"HuffmanOnly", Const, 8},
+ {"NewReader", Func, 0},
+ {"NewReaderDict", Func, 0},
+ {"NewWriter", Func, 0},
+ {"NewWriterLevel", Func, 0},
+ {"NewWriterLevelDict", Func, 0},
+ {"NoCompression", Const, 0},
+ {"Resetter", Type, 4},
+ {"Writer", Type, 0},
+ },
+ "container/heap": {
+ {"Fix", Func, 2},
+ {"Init", Func, 0},
+ {"Interface", Type, 0},
+ {"Pop", Func, 0},
+ {"Push", Func, 0},
+ {"Remove", Func, 0},
+ },
+ "container/list": {
+ {"(*Element).Next", Method, 0},
+ {"(*Element).Prev", Method, 0},
+ {"(*List).Back", Method, 0},
+ {"(*List).Front", Method, 0},
+ {"(*List).Init", Method, 0},
+ {"(*List).InsertAfter", Method, 0},
+ {"(*List).InsertBefore", Method, 0},
+ {"(*List).Len", Method, 0},
+ {"(*List).MoveAfter", Method, 2},
+ {"(*List).MoveBefore", Method, 2},
+ {"(*List).MoveToBack", Method, 0},
+ {"(*List).MoveToFront", Method, 0},
+ {"(*List).PushBack", Method, 0},
+ {"(*List).PushBackList", Method, 0},
+ {"(*List).PushFront", Method, 0},
+ {"(*List).PushFrontList", Method, 0},
+ {"(*List).Remove", Method, 0},
+ {"Element", Type, 0},
+ {"Element.Value", Field, 0},
+ {"List", Type, 0},
+ {"New", Func, 0},
+ },
+ "container/ring": {
+ {"(*Ring).Do", Method, 0},
+ {"(*Ring).Len", Method, 0},
+ {"(*Ring).Link", Method, 0},
+ {"(*Ring).Move", Method, 0},
+ {"(*Ring).Next", Method, 0},
+ {"(*Ring).Prev", Method, 0},
+ {"(*Ring).Unlink", Method, 0},
+ {"New", Func, 0},
+ {"Ring", Type, 0},
+ {"Ring.Value", Field, 0},
+ },
+ "context": {
+ {"AfterFunc", Func, 21},
+ {"Background", Func, 7},
+ {"CancelCauseFunc", Type, 20},
+ {"CancelFunc", Type, 7},
+ {"Canceled", Var, 7},
+ {"Cause", Func, 20},
+ {"Context", Type, 7},
+ {"DeadlineExceeded", Var, 7},
+ {"TODO", Func, 7},
+ {"WithCancel", Func, 7},
+ {"WithCancelCause", Func, 20},
+ {"WithDeadline", Func, 7},
+ {"WithDeadlineCause", Func, 21},
+ {"WithTimeout", Func, 7},
+ {"WithTimeoutCause", Func, 21},
+ {"WithValue", Func, 7},
+ {"WithoutCancel", Func, 21},
+ },
+ "crypto": {
+ {"(Hash).Available", Method, 0},
+ {"(Hash).HashFunc", Method, 4},
+ {"(Hash).New", Method, 0},
+ {"(Hash).Size", Method, 0},
+ {"(Hash).String", Method, 15},
+ {"BLAKE2b_256", Const, 9},
+ {"BLAKE2b_384", Const, 9},
+ {"BLAKE2b_512", Const, 9},
+ {"BLAKE2s_256", Const, 9},
+ {"Decrypter", Type, 5},
+ {"DecrypterOpts", Type, 5},
+ {"Hash", Type, 0},
+ {"MD4", Const, 0},
+ {"MD5", Const, 0},
+ {"MD5SHA1", Const, 0},
+ {"PrivateKey", Type, 0},
+ {"PublicKey", Type, 2},
+ {"RIPEMD160", Const, 0},
+ {"RegisterHash", Func, 0},
+ {"SHA1", Const, 0},
+ {"SHA224", Const, 0},
+ {"SHA256", Const, 0},
+ {"SHA384", Const, 0},
+ {"SHA3_224", Const, 4},
+ {"SHA3_256", Const, 4},
+ {"SHA3_384", Const, 4},
+ {"SHA3_512", Const, 4},
+ {"SHA512", Const, 0},
+ {"SHA512_224", Const, 5},
+ {"SHA512_256", Const, 5},
+ {"Signer", Type, 4},
+ {"SignerOpts", Type, 4},
+ },
+ "crypto/aes": {
+ {"(KeySizeError).Error", Method, 0},
+ {"BlockSize", Const, 0},
+ {"KeySizeError", Type, 0},
+ {"NewCipher", Func, 0},
+ },
+ "crypto/cipher": {
+ {"(StreamReader).Read", Method, 0},
+ {"(StreamWriter).Close", Method, 0},
+ {"(StreamWriter).Write", Method, 0},
+ {"AEAD", Type, 2},
+ {"Block", Type, 0},
+ {"BlockMode", Type, 0},
+ {"NewCBCDecrypter", Func, 0},
+ {"NewCBCEncrypter", Func, 0},
+ {"NewCFBDecrypter", Func, 0},
+ {"NewCFBEncrypter", Func, 0},
+ {"NewCTR", Func, 0},
+ {"NewGCM", Func, 2},
+ {"NewGCMWithNonceSize", Func, 5},
+ {"NewGCMWithTagSize", Func, 11},
+ {"NewOFB", Func, 0},
+ {"Stream", Type, 0},
+ {"StreamReader", Type, 0},
+ {"StreamReader.R", Field, 0},
+ {"StreamReader.S", Field, 0},
+ {"StreamWriter", Type, 0},
+ {"StreamWriter.Err", Field, 0},
+ {"StreamWriter.S", Field, 0},
+ {"StreamWriter.W", Field, 0},
+ },
+ "crypto/des": {
+ {"(KeySizeError).Error", Method, 0},
+ {"BlockSize", Const, 0},
+ {"KeySizeError", Type, 0},
+ {"NewCipher", Func, 0},
+ {"NewTripleDESCipher", Func, 0},
+ },
+ "crypto/dsa": {
+ {"ErrInvalidPublicKey", Var, 0},
+ {"GenerateKey", Func, 0},
+ {"GenerateParameters", Func, 0},
+ {"L1024N160", Const, 0},
+ {"L2048N224", Const, 0},
+ {"L2048N256", Const, 0},
+ {"L3072N256", Const, 0},
+ {"ParameterSizes", Type, 0},
+ {"Parameters", Type, 0},
+ {"Parameters.G", Field, 0},
+ {"Parameters.P", Field, 0},
+ {"Parameters.Q", Field, 0},
+ {"PrivateKey", Type, 0},
+ {"PrivateKey.PublicKey", Field, 0},
+ {"PrivateKey.X", Field, 0},
+ {"PublicKey", Type, 0},
+ {"PublicKey.Parameters", Field, 0},
+ {"PublicKey.Y", Field, 0},
+ {"Sign", Func, 0},
+ {"Verify", Func, 0},
+ },
+ "crypto/ecdh": {
+ {"(*PrivateKey).Bytes", Method, 20},
+ {"(*PrivateKey).Curve", Method, 20},
+ {"(*PrivateKey).ECDH", Method, 20},
+ {"(*PrivateKey).Equal", Method, 20},
+ {"(*PrivateKey).Public", Method, 20},
+ {"(*PrivateKey).PublicKey", Method, 20},
+ {"(*PublicKey).Bytes", Method, 20},
+ {"(*PublicKey).Curve", Method, 20},
+ {"(*PublicKey).Equal", Method, 20},
+ {"Curve", Type, 20},
+ {"P256", Func, 20},
+ {"P384", Func, 20},
+ {"P521", Func, 20},
+ {"PrivateKey", Type, 20},
+ {"PublicKey", Type, 20},
+ {"X25519", Func, 20},
+ },
+ "crypto/ecdsa": {
+ {"(*PrivateKey).ECDH", Method, 20},
+ {"(*PrivateKey).Equal", Method, 15},
+ {"(*PrivateKey).Public", Method, 4},
+ {"(*PrivateKey).Sign", Method, 4},
+ {"(*PublicKey).ECDH", Method, 20},
+ {"(*PublicKey).Equal", Method, 15},
+ {"(PrivateKey).Add", Method, 0},
+ {"(PrivateKey).Double", Method, 0},
+ {"(PrivateKey).IsOnCurve", Method, 0},
+ {"(PrivateKey).Params", Method, 0},
+ {"(PrivateKey).ScalarBaseMult", Method, 0},
+ {"(PrivateKey).ScalarMult", Method, 0},
+ {"(PublicKey).Add", Method, 0},
+ {"(PublicKey).Double", Method, 0},
+ {"(PublicKey).IsOnCurve", Method, 0},
+ {"(PublicKey).Params", Method, 0},
+ {"(PublicKey).ScalarBaseMult", Method, 0},
+ {"(PublicKey).ScalarMult", Method, 0},
+ {"GenerateKey", Func, 0},
+ {"PrivateKey", Type, 0},
+ {"PrivateKey.D", Field, 0},
+ {"PrivateKey.PublicKey", Field, 0},
+ {"PublicKey", Type, 0},
+ {"PublicKey.Curve", Field, 0},
+ {"PublicKey.X", Field, 0},
+ {"PublicKey.Y", Field, 0},
+ {"Sign", Func, 0},
+ {"SignASN1", Func, 15},
+ {"Verify", Func, 0},
+ {"VerifyASN1", Func, 15},
+ },
+ "crypto/ed25519": {
+ {"(*Options).HashFunc", Method, 20},
+ {"(PrivateKey).Equal", Method, 15},
+ {"(PrivateKey).Public", Method, 13},
+ {"(PrivateKey).Seed", Method, 13},
+ {"(PrivateKey).Sign", Method, 13},
+ {"(PublicKey).Equal", Method, 15},
+ {"GenerateKey", Func, 13},
+ {"NewKeyFromSeed", Func, 13},
+ {"Options", Type, 20},
+ {"Options.Context", Field, 20},
+ {"Options.Hash", Field, 20},
+ {"PrivateKey", Type, 13},
+ {"PrivateKeySize", Const, 13},
+ {"PublicKey", Type, 13},
+ {"PublicKeySize", Const, 13},
+ {"SeedSize", Const, 13},
+ {"Sign", Func, 13},
+ {"SignatureSize", Const, 13},
+ {"Verify", Func, 13},
+ {"VerifyWithOptions", Func, 20},
+ },
+ "crypto/elliptic": {
+ {"(*CurveParams).Add", Method, 0},
+ {"(*CurveParams).Double", Method, 0},
+ {"(*CurveParams).IsOnCurve", Method, 0},
+ {"(*CurveParams).Params", Method, 0},
+ {"(*CurveParams).ScalarBaseMult", Method, 0},
+ {"(*CurveParams).ScalarMult", Method, 0},
+ {"Curve", Type, 0},
+ {"CurveParams", Type, 0},
+ {"CurveParams.B", Field, 0},
+ {"CurveParams.BitSize", Field, 0},
+ {"CurveParams.Gx", Field, 0},
+ {"CurveParams.Gy", Field, 0},
+ {"CurveParams.N", Field, 0},
+ {"CurveParams.Name", Field, 5},
+ {"CurveParams.P", Field, 0},
+ {"GenerateKey", Func, 0},
+ {"Marshal", Func, 0},
+ {"MarshalCompressed", Func, 15},
+ {"P224", Func, 0},
+ {"P256", Func, 0},
+ {"P384", Func, 0},
+ {"P521", Func, 0},
+ {"Unmarshal", Func, 0},
+ {"UnmarshalCompressed", Func, 15},
+ },
+ "crypto/hmac": {
+ {"Equal", Func, 1},
+ {"New", Func, 0},
+ },
+ "crypto/md5": {
+ {"BlockSize", Const, 0},
+ {"New", Func, 0},
+ {"Size", Const, 0},
+ {"Sum", Func, 2},
+ },
+ "crypto/rand": {
+ {"Int", Func, 0},
+ {"Prime", Func, 0},
+ {"Read", Func, 0},
+ {"Reader", Var, 0},
+ },
+ "crypto/rc4": {
+ {"(*Cipher).Reset", Method, 0},
+ {"(*Cipher).XORKeyStream", Method, 0},
+ {"(KeySizeError).Error", Method, 0},
+ {"Cipher", Type, 0},
+ {"KeySizeError", Type, 0},
+ {"NewCipher", Func, 0},
+ },
+ "crypto/rsa": {
+ {"(*PSSOptions).HashFunc", Method, 4},
+ {"(*PrivateKey).Decrypt", Method, 5},
+ {"(*PrivateKey).Equal", Method, 15},
+ {"(*PrivateKey).Precompute", Method, 0},
+ {"(*PrivateKey).Public", Method, 4},
+ {"(*PrivateKey).Sign", Method, 4},
+ {"(*PrivateKey).Size", Method, 11},
+ {"(*PrivateKey).Validate", Method, 0},
+ {"(*PublicKey).Equal", Method, 15},
+ {"(*PublicKey).Size", Method, 11},
+ {"CRTValue", Type, 0},
+ {"CRTValue.Coeff", Field, 0},
+ {"CRTValue.Exp", Field, 0},
+ {"CRTValue.R", Field, 0},
+ {"DecryptOAEP", Func, 0},
+ {"DecryptPKCS1v15", Func, 0},
+ {"DecryptPKCS1v15SessionKey", Func, 0},
+ {"EncryptOAEP", Func, 0},
+ {"EncryptPKCS1v15", Func, 0},
+ {"ErrDecryption", Var, 0},
+ {"ErrMessageTooLong", Var, 0},
+ {"ErrVerification", Var, 0},
+ {"GenerateKey", Func, 0},
+ {"GenerateMultiPrimeKey", Func, 0},
+ {"OAEPOptions", Type, 5},
+ {"OAEPOptions.Hash", Field, 5},
+ {"OAEPOptions.Label", Field, 5},
+ {"OAEPOptions.MGFHash", Field, 20},
+ {"PKCS1v15DecryptOptions", Type, 5},
+ {"PKCS1v15DecryptOptions.SessionKeyLen", Field, 5},
+ {"PSSOptions", Type, 2},
+ {"PSSOptions.Hash", Field, 4},
+ {"PSSOptions.SaltLength", Field, 2},
+ {"PSSSaltLengthAuto", Const, 2},
+ {"PSSSaltLengthEqualsHash", Const, 2},
+ {"PrecomputedValues", Type, 0},
+ {"PrecomputedValues.CRTValues", Field, 0},
+ {"PrecomputedValues.Dp", Field, 0},
+ {"PrecomputedValues.Dq", Field, 0},
+ {"PrecomputedValues.Qinv", Field, 0},
+ {"PrivateKey", Type, 0},
+ {"PrivateKey.D", Field, 0},
+ {"PrivateKey.Precomputed", Field, 0},
+ {"PrivateKey.Primes", Field, 0},
+ {"PrivateKey.PublicKey", Field, 0},
+ {"PublicKey", Type, 0},
+ {"PublicKey.E", Field, 0},
+ {"PublicKey.N", Field, 0},
+ {"SignPKCS1v15", Func, 0},
+ {"SignPSS", Func, 2},
+ {"VerifyPKCS1v15", Func, 0},
+ {"VerifyPSS", Func, 2},
+ },
+ "crypto/sha1": {
+ {"BlockSize", Const, 0},
+ {"New", Func, 0},
+ {"Size", Const, 0},
+ {"Sum", Func, 2},
+ },
+ "crypto/sha256": {
+ {"BlockSize", Const, 0},
+ {"New", Func, 0},
+ {"New224", Func, 0},
+ {"Size", Const, 0},
+ {"Size224", Const, 0},
+ {"Sum224", Func, 2},
+ {"Sum256", Func, 2},
+ },
+ "crypto/sha512": {
+ {"BlockSize", Const, 0},
+ {"New", Func, 0},
+ {"New384", Func, 0},
+ {"New512_224", Func, 5},
+ {"New512_256", Func, 5},
+ {"Size", Const, 0},
+ {"Size224", Const, 5},
+ {"Size256", Const, 5},
+ {"Size384", Const, 0},
+ {"Sum384", Func, 2},
+ {"Sum512", Func, 2},
+ {"Sum512_224", Func, 5},
+ {"Sum512_256", Func, 5},
+ },
+ "crypto/subtle": {
+ {"ConstantTimeByteEq", Func, 0},
+ {"ConstantTimeCompare", Func, 0},
+ {"ConstantTimeCopy", Func, 0},
+ {"ConstantTimeEq", Func, 0},
+ {"ConstantTimeLessOrEq", Func, 2},
+ {"ConstantTimeSelect", Func, 0},
+ {"XORBytes", Func, 20},
+ },
+ "crypto/tls": {
+ {"(*CertificateRequestInfo).Context", Method, 17},
+ {"(*CertificateRequestInfo).SupportsCertificate", Method, 14},
+ {"(*CertificateVerificationError).Error", Method, 20},
+ {"(*CertificateVerificationError).Unwrap", Method, 20},
+ {"(*ClientHelloInfo).Context", Method, 17},
+ {"(*ClientHelloInfo).SupportsCertificate", Method, 14},
+ {"(*ClientSessionState).ResumptionState", Method, 21},
+ {"(*Config).BuildNameToCertificate", Method, 0},
+ {"(*Config).Clone", Method, 8},
+ {"(*Config).DecryptTicket", Method, 21},
+ {"(*Config).EncryptTicket", Method, 21},
+ {"(*Config).SetSessionTicketKeys", Method, 5},
+ {"(*Conn).Close", Method, 0},
+ {"(*Conn).CloseWrite", Method, 8},
+ {"(*Conn).ConnectionState", Method, 0},
+ {"(*Conn).Handshake", Method, 0},
+ {"(*Conn).HandshakeContext", Method, 17},
+ {"(*Conn).LocalAddr", Method, 0},
+ {"(*Conn).NetConn", Method, 18},
+ {"(*Conn).OCSPResponse", Method, 0},
+ {"(*Conn).Read", Method, 0},
+ {"(*Conn).RemoteAddr", Method, 0},
+ {"(*Conn).SetDeadline", Method, 0},
+ {"(*Conn).SetReadDeadline", Method, 0},
+ {"(*Conn).SetWriteDeadline", Method, 0},
+ {"(*Conn).VerifyHostname", Method, 0},
+ {"(*Conn).Write", Method, 0},
+ {"(*ConnectionState).ExportKeyingMaterial", Method, 11},
+ {"(*Dialer).Dial", Method, 15},
+ {"(*Dialer).DialContext", Method, 15},
+ {"(*ECHRejectionError).Error", Method, 23},
+ {"(*QUICConn).Close", Method, 21},
+ {"(*QUICConn).ConnectionState", Method, 21},
+ {"(*QUICConn).HandleData", Method, 21},
+ {"(*QUICConn).NextEvent", Method, 21},
+ {"(*QUICConn).SendSessionTicket", Method, 21},
+ {"(*QUICConn).SetTransportParameters", Method, 21},
+ {"(*QUICConn).Start", Method, 21},
+ {"(*QUICConn).StoreSession", Method, 23},
+ {"(*SessionState).Bytes", Method, 21},
+ {"(AlertError).Error", Method, 21},
+ {"(ClientAuthType).String", Method, 15},
+ {"(CurveID).String", Method, 15},
+ {"(QUICEncryptionLevel).String", Method, 21},
+ {"(RecordHeaderError).Error", Method, 6},
+ {"(SignatureScheme).String", Method, 15},
+ {"AlertError", Type, 21},
+ {"Certificate", Type, 0},
+ {"Certificate.Certificate", Field, 0},
+ {"Certificate.Leaf", Field, 0},
+ {"Certificate.OCSPStaple", Field, 0},
+ {"Certificate.PrivateKey", Field, 0},
+ {"Certificate.SignedCertificateTimestamps", Field, 5},
+ {"Certificate.SupportedSignatureAlgorithms", Field, 14},
+ {"CertificateRequestInfo", Type, 8},
+ {"CertificateRequestInfo.AcceptableCAs", Field, 8},
+ {"CertificateRequestInfo.SignatureSchemes", Field, 8},
+ {"CertificateRequestInfo.Version", Field, 14},
+ {"CertificateVerificationError", Type, 20},
+ {"CertificateVerificationError.Err", Field, 20},
+ {"CertificateVerificationError.UnverifiedCertificates", Field, 20},
+ {"CipherSuite", Type, 14},
+ {"CipherSuite.ID", Field, 14},
+ {"CipherSuite.Insecure", Field, 14},
+ {"CipherSuite.Name", Field, 14},
+ {"CipherSuite.SupportedVersions", Field, 14},
+ {"CipherSuiteName", Func, 14},
+ {"CipherSuites", Func, 14},
+ {"Client", Func, 0},
+ {"ClientAuthType", Type, 0},
+ {"ClientHelloInfo", Type, 4},
+ {"ClientHelloInfo.CipherSuites", Field, 4},
+ {"ClientHelloInfo.Conn", Field, 8},
+ {"ClientHelloInfo.ServerName", Field, 4},
+ {"ClientHelloInfo.SignatureSchemes", Field, 8},
+ {"ClientHelloInfo.SupportedCurves", Field, 4},
+ {"ClientHelloInfo.SupportedPoints", Field, 4},
+ {"ClientHelloInfo.SupportedProtos", Field, 8},
+ {"ClientHelloInfo.SupportedVersions", Field, 8},
+ {"ClientSessionCache", Type, 3},
+ {"ClientSessionState", Type, 3},
+ {"Config", Type, 0},
+ {"Config.Certificates", Field, 0},
+ {"Config.CipherSuites", Field, 0},
+ {"Config.ClientAuth", Field, 0},
+ {"Config.ClientCAs", Field, 0},
+ {"Config.ClientSessionCache", Field, 3},
+ {"Config.CurvePreferences", Field, 3},
+ {"Config.DynamicRecordSizingDisabled", Field, 7},
+ {"Config.EncryptedClientHelloConfigList", Field, 23},
+ {"Config.EncryptedClientHelloRejectionVerify", Field, 23},
+ {"Config.GetCertificate", Field, 4},
+ {"Config.GetClientCertificate", Field, 8},
+ {"Config.GetConfigForClient", Field, 8},
+ {"Config.InsecureSkipVerify", Field, 0},
+ {"Config.KeyLogWriter", Field, 8},
+ {"Config.MaxVersion", Field, 2},
+ {"Config.MinVersion", Field, 2},
+ {"Config.NameToCertificate", Field, 0},
+ {"Config.NextProtos", Field, 0},
+ {"Config.PreferServerCipherSuites", Field, 1},
+ {"Config.Rand", Field, 0},
+ {"Config.Renegotiation", Field, 7},
+ {"Config.RootCAs", Field, 0},
+ {"Config.ServerName", Field, 0},
+ {"Config.SessionTicketKey", Field, 1},
+ {"Config.SessionTicketsDisabled", Field, 1},
+ {"Config.Time", Field, 0},
+ {"Config.UnwrapSession", Field, 21},
+ {"Config.VerifyConnection", Field, 15},
+ {"Config.VerifyPeerCertificate", Field, 8},
+ {"Config.WrapSession", Field, 21},
+ {"Conn", Type, 0},
+ {"ConnectionState", Type, 0},
+ {"ConnectionState.CipherSuite", Field, 0},
+ {"ConnectionState.DidResume", Field, 1},
+ {"ConnectionState.ECHAccepted", Field, 23},
+ {"ConnectionState.HandshakeComplete", Field, 0},
+ {"ConnectionState.NegotiatedProtocol", Field, 0},
+ {"ConnectionState.NegotiatedProtocolIsMutual", Field, 0},
+ {"ConnectionState.OCSPResponse", Field, 5},
+ {"ConnectionState.PeerCertificates", Field, 0},
+ {"ConnectionState.ServerName", Field, 0},
+ {"ConnectionState.SignedCertificateTimestamps", Field, 5},
+ {"ConnectionState.TLSUnique", Field, 4},
+ {"ConnectionState.VerifiedChains", Field, 0},
+ {"ConnectionState.Version", Field, 3},
+ {"CurveID", Type, 3},
+ {"CurveP256", Const, 3},
+ {"CurveP384", Const, 3},
+ {"CurveP521", Const, 3},
+ {"Dial", Func, 0},
+ {"DialWithDialer", Func, 3},
+ {"Dialer", Type, 15},
+ {"Dialer.Config", Field, 15},
+ {"Dialer.NetDialer", Field, 15},
+ {"ECDSAWithP256AndSHA256", Const, 8},
+ {"ECDSAWithP384AndSHA384", Const, 8},
+ {"ECDSAWithP521AndSHA512", Const, 8},
+ {"ECDSAWithSHA1", Const, 10},
+ {"ECHRejectionError", Type, 23},
+ {"ECHRejectionError.RetryConfigList", Field, 23},
+ {"Ed25519", Const, 13},
+ {"InsecureCipherSuites", Func, 14},
+ {"Listen", Func, 0},
+ {"LoadX509KeyPair", Func, 0},
+ {"NewLRUClientSessionCache", Func, 3},
+ {"NewListener", Func, 0},
+ {"NewResumptionState", Func, 21},
+ {"NoClientCert", Const, 0},
+ {"PKCS1WithSHA1", Const, 8},
+ {"PKCS1WithSHA256", Const, 8},
+ {"PKCS1WithSHA384", Const, 8},
+ {"PKCS1WithSHA512", Const, 8},
+ {"PSSWithSHA256", Const, 8},
+ {"PSSWithSHA384", Const, 8},
+ {"PSSWithSHA512", Const, 8},
+ {"ParseSessionState", Func, 21},
+ {"QUICClient", Func, 21},
+ {"QUICConfig", Type, 21},
+ {"QUICConfig.EnableStoreSessionEvent", Field, 23},
+ {"QUICConfig.TLSConfig", Field, 21},
+ {"QUICConn", Type, 21},
+ {"QUICEncryptionLevel", Type, 21},
+ {"QUICEncryptionLevelApplication", Const, 21},
+ {"QUICEncryptionLevelEarly", Const, 21},
+ {"QUICEncryptionLevelHandshake", Const, 21},
+ {"QUICEncryptionLevelInitial", Const, 21},
+ {"QUICEvent", Type, 21},
+ {"QUICEvent.Data", Field, 21},
+ {"QUICEvent.Kind", Field, 21},
+ {"QUICEvent.Level", Field, 21},
+ {"QUICEvent.SessionState", Field, 23},
+ {"QUICEvent.Suite", Field, 21},
+ {"QUICEventKind", Type, 21},
+ {"QUICHandshakeDone", Const, 21},
+ {"QUICNoEvent", Const, 21},
+ {"QUICRejectedEarlyData", Const, 21},
+ {"QUICResumeSession", Const, 23},
+ {"QUICServer", Func, 21},
+ {"QUICSessionTicketOptions", Type, 21},
+ {"QUICSessionTicketOptions.EarlyData", Field, 21},
+ {"QUICSessionTicketOptions.Extra", Field, 23},
+ {"QUICSetReadSecret", Const, 21},
+ {"QUICSetWriteSecret", Const, 21},
+ {"QUICStoreSession", Const, 23},
+ {"QUICTransportParameters", Const, 21},
+ {"QUICTransportParametersRequired", Const, 21},
+ {"QUICWriteData", Const, 21},
+ {"RecordHeaderError", Type, 6},
+ {"RecordHeaderError.Conn", Field, 12},
+ {"RecordHeaderError.Msg", Field, 6},
+ {"RecordHeaderError.RecordHeader", Field, 6},
+ {"RenegotiateFreelyAsClient", Const, 7},
+ {"RenegotiateNever", Const, 7},
+ {"RenegotiateOnceAsClient", Const, 7},
+ {"RenegotiationSupport", Type, 7},
+ {"RequestClientCert", Const, 0},
+ {"RequireAndVerifyClientCert", Const, 0},
+ {"RequireAnyClientCert", Const, 0},
+ {"Server", Func, 0},
+ {"SessionState", Type, 21},
+ {"SessionState.EarlyData", Field, 21},
+ {"SessionState.Extra", Field, 21},
+ {"SignatureScheme", Type, 8},
+ {"TLS_AES_128_GCM_SHA256", Const, 12},
+ {"TLS_AES_256_GCM_SHA384", Const, 12},
+ {"TLS_CHACHA20_POLY1305_SHA256", Const, 12},
+ {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", Const, 2},
+ {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", Const, 8},
+ {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", Const, 2},
+ {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", Const, 2},
+ {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", Const, 5},
+ {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", Const, 8},
+ {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14},
+ {"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", Const, 2},
+ {"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0},
+ {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", Const, 0},
+ {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", Const, 8},
+ {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", Const, 2},
+ {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", Const, 1},
+ {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", Const, 5},
+ {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", Const, 8},
+ {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14},
+ {"TLS_ECDHE_RSA_WITH_RC4_128_SHA", Const, 0},
+ {"TLS_FALLBACK_SCSV", Const, 4},
+ {"TLS_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0},
+ {"TLS_RSA_WITH_AES_128_CBC_SHA", Const, 0},
+ {"TLS_RSA_WITH_AES_128_CBC_SHA256", Const, 8},
+ {"TLS_RSA_WITH_AES_128_GCM_SHA256", Const, 6},
+ {"TLS_RSA_WITH_AES_256_CBC_SHA", Const, 1},
+ {"TLS_RSA_WITH_AES_256_GCM_SHA384", Const, 6},
+ {"TLS_RSA_WITH_RC4_128_SHA", Const, 0},
+ {"VerifyClientCertIfGiven", Const, 0},
+ {"VersionName", Func, 21},
+ {"VersionSSL30", Const, 2},
+ {"VersionTLS10", Const, 2},
+ {"VersionTLS11", Const, 2},
+ {"VersionTLS12", Const, 2},
+ {"VersionTLS13", Const, 12},
+ {"X25519", Const, 8},
+ {"X509KeyPair", Func, 0},
+ },
+ "crypto/x509": {
+ {"(*CertPool).AddCert", Method, 0},
+ {"(*CertPool).AddCertWithConstraint", Method, 22},
+ {"(*CertPool).AppendCertsFromPEM", Method, 0},
+ {"(*CertPool).Clone", Method, 19},
+ {"(*CertPool).Equal", Method, 19},
+ {"(*CertPool).Subjects", Method, 0},
+ {"(*Certificate).CheckCRLSignature", Method, 0},
+ {"(*Certificate).CheckSignature", Method, 0},
+ {"(*Certificate).CheckSignatureFrom", Method, 0},
+ {"(*Certificate).CreateCRL", Method, 0},
+ {"(*Certificate).Equal", Method, 0},
+ {"(*Certificate).Verify", Method, 0},
+ {"(*Certificate).VerifyHostname", Method, 0},
+ {"(*CertificateRequest).CheckSignature", Method, 5},
+ {"(*OID).UnmarshalBinary", Method, 23},
+ {"(*OID).UnmarshalText", Method, 23},
+ {"(*RevocationList).CheckSignatureFrom", Method, 19},
+ {"(CertificateInvalidError).Error", Method, 0},
+ {"(ConstraintViolationError).Error", Method, 0},
+ {"(HostnameError).Error", Method, 0},
+ {"(InsecureAlgorithmError).Error", Method, 6},
+ {"(OID).Equal", Method, 22},
+ {"(OID).EqualASN1OID", Method, 22},
+ {"(OID).MarshalBinary", Method, 23},
+ {"(OID).MarshalText", Method, 23},
+ {"(OID).String", Method, 22},
+ {"(PublicKeyAlgorithm).String", Method, 10},
+ {"(SignatureAlgorithm).String", Method, 6},
+ {"(SystemRootsError).Error", Method, 1},
+ {"(SystemRootsError).Unwrap", Method, 16},
+ {"(UnhandledCriticalExtension).Error", Method, 0},
+ {"(UnknownAuthorityError).Error", Method, 0},
+ {"CANotAuthorizedForExtKeyUsage", Const, 10},
+ {"CANotAuthorizedForThisName", Const, 0},
+ {"CertPool", Type, 0},
+ {"Certificate", Type, 0},
+ {"Certificate.AuthorityKeyId", Field, 0},
+ {"Certificate.BasicConstraintsValid", Field, 0},
+ {"Certificate.CRLDistributionPoints", Field, 2},
+ {"Certificate.DNSNames", Field, 0},
+ {"Certificate.EmailAddresses", Field, 0},
+ {"Certificate.ExcludedDNSDomains", Field, 9},
+ {"Certificate.ExcludedEmailAddresses", Field, 10},
+ {"Certificate.ExcludedIPRanges", Field, 10},
+ {"Certificate.ExcludedURIDomains", Field, 10},
+ {"Certificate.ExtKeyUsage", Field, 0},
+ {"Certificate.Extensions", Field, 2},
+ {"Certificate.ExtraExtensions", Field, 2},
+ {"Certificate.IPAddresses", Field, 1},
+ {"Certificate.IsCA", Field, 0},
+ {"Certificate.Issuer", Field, 0},
+ {"Certificate.IssuingCertificateURL", Field, 2},
+ {"Certificate.KeyUsage", Field, 0},
+ {"Certificate.MaxPathLen", Field, 0},
+ {"Certificate.MaxPathLenZero", Field, 4},
+ {"Certificate.NotAfter", Field, 0},
+ {"Certificate.NotBefore", Field, 0},
+ {"Certificate.OCSPServer", Field, 2},
+ {"Certificate.PermittedDNSDomains", Field, 0},
+ {"Certificate.PermittedDNSDomainsCritical", Field, 0},
+ {"Certificate.PermittedEmailAddresses", Field, 10},
+ {"Certificate.PermittedIPRanges", Field, 10},
+ {"Certificate.PermittedURIDomains", Field, 10},
+ {"Certificate.Policies", Field, 22},
+ {"Certificate.PolicyIdentifiers", Field, 0},
+ {"Certificate.PublicKey", Field, 0},
+ {"Certificate.PublicKeyAlgorithm", Field, 0},
+ {"Certificate.Raw", Field, 0},
+ {"Certificate.RawIssuer", Field, 0},
+ {"Certificate.RawSubject", Field, 0},
+ {"Certificate.RawSubjectPublicKeyInfo", Field, 0},
+ {"Certificate.RawTBSCertificate", Field, 0},
+ {"Certificate.SerialNumber", Field, 0},
+ {"Certificate.Signature", Field, 0},
+ {"Certificate.SignatureAlgorithm", Field, 0},
+ {"Certificate.Subject", Field, 0},
+ {"Certificate.SubjectKeyId", Field, 0},
+ {"Certificate.URIs", Field, 10},
+ {"Certificate.UnhandledCriticalExtensions", Field, 5},
+ {"Certificate.UnknownExtKeyUsage", Field, 0},
+ {"Certificate.Version", Field, 0},
+ {"CertificateInvalidError", Type, 0},
+ {"CertificateInvalidError.Cert", Field, 0},
+ {"CertificateInvalidError.Detail", Field, 10},
+ {"CertificateInvalidError.Reason", Field, 0},
+ {"CertificateRequest", Type, 3},
+ {"CertificateRequest.Attributes", Field, 3},
+ {"CertificateRequest.DNSNames", Field, 3},
+ {"CertificateRequest.EmailAddresses", Field, 3},
+ {"CertificateRequest.Extensions", Field, 3},
+ {"CertificateRequest.ExtraExtensions", Field, 3},
+ {"CertificateRequest.IPAddresses", Field, 3},
+ {"CertificateRequest.PublicKey", Field, 3},
+ {"CertificateRequest.PublicKeyAlgorithm", Field, 3},
+ {"CertificateRequest.Raw", Field, 3},
+ {"CertificateRequest.RawSubject", Field, 3},
+ {"CertificateRequest.RawSubjectPublicKeyInfo", Field, 3},
+ {"CertificateRequest.RawTBSCertificateRequest", Field, 3},
+ {"CertificateRequest.Signature", Field, 3},
+ {"CertificateRequest.SignatureAlgorithm", Field, 3},
+ {"CertificateRequest.Subject", Field, 3},
+ {"CertificateRequest.URIs", Field, 10},
+ {"CertificateRequest.Version", Field, 3},
+ {"ConstraintViolationError", Type, 0},
+ {"CreateCertificate", Func, 0},
+ {"CreateCertificateRequest", Func, 3},
+ {"CreateRevocationList", Func, 15},
+ {"DSA", Const, 0},
+ {"DSAWithSHA1", Const, 0},
+ {"DSAWithSHA256", Const, 0},
+ {"DecryptPEMBlock", Func, 1},
+ {"ECDSA", Const, 1},
+ {"ECDSAWithSHA1", Const, 1},
+ {"ECDSAWithSHA256", Const, 1},
+ {"ECDSAWithSHA384", Const, 1},
+ {"ECDSAWithSHA512", Const, 1},
+ {"Ed25519", Const, 13},
+ {"EncryptPEMBlock", Func, 1},
+ {"ErrUnsupportedAlgorithm", Var, 0},
+ {"Expired", Const, 0},
+ {"ExtKeyUsage", Type, 0},
+ {"ExtKeyUsageAny", Const, 0},
+ {"ExtKeyUsageClientAuth", Const, 0},
+ {"ExtKeyUsageCodeSigning", Const, 0},
+ {"ExtKeyUsageEmailProtection", Const, 0},
+ {"ExtKeyUsageIPSECEndSystem", Const, 1},
+ {"ExtKeyUsageIPSECTunnel", Const, 1},
+ {"ExtKeyUsageIPSECUser", Const, 1},
+ {"ExtKeyUsageMicrosoftCommercialCodeSigning", Const, 10},
+ {"ExtKeyUsageMicrosoftKernelCodeSigning", Const, 10},
+ {"ExtKeyUsageMicrosoftServerGatedCrypto", Const, 1},
+ {"ExtKeyUsageNetscapeServerGatedCrypto", Const, 1},
+ {"ExtKeyUsageOCSPSigning", Const, 0},
+ {"ExtKeyUsageServerAuth", Const, 0},
+ {"ExtKeyUsageTimeStamping", Const, 0},
+ {"HostnameError", Type, 0},
+ {"HostnameError.Certificate", Field, 0},
+ {"HostnameError.Host", Field, 0},
+ {"IncompatibleUsage", Const, 1},
+ {"IncorrectPasswordError", Var, 1},
+ {"InsecureAlgorithmError", Type, 6},
+ {"InvalidReason", Type, 0},
+ {"IsEncryptedPEMBlock", Func, 1},
+ {"KeyUsage", Type, 0},
+ {"KeyUsageCRLSign", Const, 0},
+ {"KeyUsageCertSign", Const, 0},
+ {"KeyUsageContentCommitment", Const, 0},
+ {"KeyUsageDataEncipherment", Const, 0},
+ {"KeyUsageDecipherOnly", Const, 0},
+ {"KeyUsageDigitalSignature", Const, 0},
+ {"KeyUsageEncipherOnly", Const, 0},
+ {"KeyUsageKeyAgreement", Const, 0},
+ {"KeyUsageKeyEncipherment", Const, 0},
+ {"MD2WithRSA", Const, 0},
+ {"MD5WithRSA", Const, 0},
+ {"MarshalECPrivateKey", Func, 2},
+ {"MarshalPKCS1PrivateKey", Func, 0},
+ {"MarshalPKCS1PublicKey", Func, 10},
+ {"MarshalPKCS8PrivateKey", Func, 10},
+ {"MarshalPKIXPublicKey", Func, 0},
+ {"NameConstraintsWithoutSANs", Const, 10},
+ {"NameMismatch", Const, 8},
+ {"NewCertPool", Func, 0},
+ {"NotAuthorizedToSign", Const, 0},
+ {"OID", Type, 22},
+ {"OIDFromInts", Func, 22},
+ {"PEMCipher", Type, 1},
+ {"PEMCipher3DES", Const, 1},
+ {"PEMCipherAES128", Const, 1},
+ {"PEMCipherAES192", Const, 1},
+ {"PEMCipherAES256", Const, 1},
+ {"PEMCipherDES", Const, 1},
+ {"ParseCRL", Func, 0},
+ {"ParseCertificate", Func, 0},
+ {"ParseCertificateRequest", Func, 3},
+ {"ParseCertificates", Func, 0},
+ {"ParseDERCRL", Func, 0},
+ {"ParseECPrivateKey", Func, 1},
+ {"ParseOID", Func, 23},
+ {"ParsePKCS1PrivateKey", Func, 0},
+ {"ParsePKCS1PublicKey", Func, 10},
+ {"ParsePKCS8PrivateKey", Func, 0},
+ {"ParsePKIXPublicKey", Func, 0},
+ {"ParseRevocationList", Func, 19},
+ {"PublicKeyAlgorithm", Type, 0},
+ {"PureEd25519", Const, 13},
+ {"RSA", Const, 0},
+ {"RevocationList", Type, 15},
+ {"RevocationList.AuthorityKeyId", Field, 19},
+ {"RevocationList.Extensions", Field, 19},
+ {"RevocationList.ExtraExtensions", Field, 15},
+ {"RevocationList.Issuer", Field, 19},
+ {"RevocationList.NextUpdate", Field, 15},
+ {"RevocationList.Number", Field, 15},
+ {"RevocationList.Raw", Field, 19},
+ {"RevocationList.RawIssuer", Field, 19},
+ {"RevocationList.RawTBSRevocationList", Field, 19},
+ {"RevocationList.RevokedCertificateEntries", Field, 21},
+ {"RevocationList.RevokedCertificates", Field, 15},
+ {"RevocationList.Signature", Field, 19},
+ {"RevocationList.SignatureAlgorithm", Field, 15},
+ {"RevocationList.ThisUpdate", Field, 15},
+ {"RevocationListEntry", Type, 21},
+ {"RevocationListEntry.Extensions", Field, 21},
+ {"RevocationListEntry.ExtraExtensions", Field, 21},
+ {"RevocationListEntry.Raw", Field, 21},
+ {"RevocationListEntry.ReasonCode", Field, 21},
+ {"RevocationListEntry.RevocationTime", Field, 21},
+ {"RevocationListEntry.SerialNumber", Field, 21},
+ {"SHA1WithRSA", Const, 0},
+ {"SHA256WithRSA", Const, 0},
+ {"SHA256WithRSAPSS", Const, 8},
+ {"SHA384WithRSA", Const, 0},
+ {"SHA384WithRSAPSS", Const, 8},
+ {"SHA512WithRSA", Const, 0},
+ {"SHA512WithRSAPSS", Const, 8},
+ {"SetFallbackRoots", Func, 20},
+ {"SignatureAlgorithm", Type, 0},
+ {"SystemCertPool", Func, 7},
+ {"SystemRootsError", Type, 1},
+ {"SystemRootsError.Err", Field, 7},
+ {"TooManyConstraints", Const, 10},
+ {"TooManyIntermediates", Const, 0},
+ {"UnconstrainedName", Const, 10},
+ {"UnhandledCriticalExtension", Type, 0},
+ {"UnknownAuthorityError", Type, 0},
+ {"UnknownAuthorityError.Cert", Field, 8},
+ {"UnknownPublicKeyAlgorithm", Const, 0},
+ {"UnknownSignatureAlgorithm", Const, 0},
+ {"VerifyOptions", Type, 0},
+ {"VerifyOptions.CurrentTime", Field, 0},
+ {"VerifyOptions.DNSName", Field, 0},
+ {"VerifyOptions.Intermediates", Field, 0},
+ {"VerifyOptions.KeyUsages", Field, 1},
+ {"VerifyOptions.MaxConstraintComparisions", Field, 10},
+ {"VerifyOptions.Roots", Field, 0},
+ },
+ "crypto/x509/pkix": {
+ {"(*CertificateList).HasExpired", Method, 0},
+ {"(*Name).FillFromRDNSequence", Method, 0},
+ {"(Name).String", Method, 10},
+ {"(Name).ToRDNSequence", Method, 0},
+ {"(RDNSequence).String", Method, 10},
+ {"AlgorithmIdentifier", Type, 0},
+ {"AlgorithmIdentifier.Algorithm", Field, 0},
+ {"AlgorithmIdentifier.Parameters", Field, 0},
+ {"AttributeTypeAndValue", Type, 0},
+ {"AttributeTypeAndValue.Type", Field, 0},
+ {"AttributeTypeAndValue.Value", Field, 0},
+ {"AttributeTypeAndValueSET", Type, 3},
+ {"AttributeTypeAndValueSET.Type", Field, 3},
+ {"AttributeTypeAndValueSET.Value", Field, 3},
+ {"CertificateList", Type, 0},
+ {"CertificateList.SignatureAlgorithm", Field, 0},
+ {"CertificateList.SignatureValue", Field, 0},
+ {"CertificateList.TBSCertList", Field, 0},
+ {"Extension", Type, 0},
+ {"Extension.Critical", Field, 0},
+ {"Extension.Id", Field, 0},
+ {"Extension.Value", Field, 0},
+ {"Name", Type, 0},
+ {"Name.CommonName", Field, 0},
+ {"Name.Country", Field, 0},
+ {"Name.ExtraNames", Field, 5},
+ {"Name.Locality", Field, 0},
+ {"Name.Names", Field, 0},
+ {"Name.Organization", Field, 0},
+ {"Name.OrganizationalUnit", Field, 0},
+ {"Name.PostalCode", Field, 0},
+ {"Name.Province", Field, 0},
+ {"Name.SerialNumber", Field, 0},
+ {"Name.StreetAddress", Field, 0},
+ {"RDNSequence", Type, 0},
+ {"RelativeDistinguishedNameSET", Type, 0},
+ {"RevokedCertificate", Type, 0},
+ {"RevokedCertificate.Extensions", Field, 0},
+ {"RevokedCertificate.RevocationTime", Field, 0},
+ {"RevokedCertificate.SerialNumber", Field, 0},
+ {"TBSCertificateList", Type, 0},
+ {"TBSCertificateList.Extensions", Field, 0},
+ {"TBSCertificateList.Issuer", Field, 0},
+ {"TBSCertificateList.NextUpdate", Field, 0},
+ {"TBSCertificateList.Raw", Field, 0},
+ {"TBSCertificateList.RevokedCertificates", Field, 0},
+ {"TBSCertificateList.Signature", Field, 0},
+ {"TBSCertificateList.ThisUpdate", Field, 0},
+ {"TBSCertificateList.Version", Field, 0},
+ },
+ "database/sql": {
+ {"(*ColumnType).DatabaseTypeName", Method, 8},
+ {"(*ColumnType).DecimalSize", Method, 8},
+ {"(*ColumnType).Length", Method, 8},
+ {"(*ColumnType).Name", Method, 8},
+ {"(*ColumnType).Nullable", Method, 8},
+ {"(*ColumnType).ScanType", Method, 8},
+ {"(*Conn).BeginTx", Method, 9},
+ {"(*Conn).Close", Method, 9},
+ {"(*Conn).ExecContext", Method, 9},
+ {"(*Conn).PingContext", Method, 9},
+ {"(*Conn).PrepareContext", Method, 9},
+ {"(*Conn).QueryContext", Method, 9},
+ {"(*Conn).QueryRowContext", Method, 9},
+ {"(*Conn).Raw", Method, 13},
+ {"(*DB).Begin", Method, 0},
+ {"(*DB).BeginTx", Method, 8},
+ {"(*DB).Close", Method, 0},
+ {"(*DB).Conn", Method, 9},
+ {"(*DB).Driver", Method, 0},
+ {"(*DB).Exec", Method, 0},
+ {"(*DB).ExecContext", Method, 8},
+ {"(*DB).Ping", Method, 1},
+ {"(*DB).PingContext", Method, 8},
+ {"(*DB).Prepare", Method, 0},
+ {"(*DB).PrepareContext", Method, 8},
+ {"(*DB).Query", Method, 0},
+ {"(*DB).QueryContext", Method, 8},
+ {"(*DB).QueryRow", Method, 0},
+ {"(*DB).QueryRowContext", Method, 8},
+ {"(*DB).SetConnMaxIdleTime", Method, 15},
+ {"(*DB).SetConnMaxLifetime", Method, 6},
+ {"(*DB).SetMaxIdleConns", Method, 1},
+ {"(*DB).SetMaxOpenConns", Method, 2},
+ {"(*DB).Stats", Method, 5},
+ {"(*Null).Scan", Method, 22},
+ {"(*NullBool).Scan", Method, 0},
+ {"(*NullByte).Scan", Method, 17},
+ {"(*NullFloat64).Scan", Method, 0},
+ {"(*NullInt16).Scan", Method, 17},
+ {"(*NullInt32).Scan", Method, 13},
+ {"(*NullInt64).Scan", Method, 0},
+ {"(*NullString).Scan", Method, 0},
+ {"(*NullTime).Scan", Method, 13},
+ {"(*Row).Err", Method, 15},
+ {"(*Row).Scan", Method, 0},
+ {"(*Rows).Close", Method, 0},
+ {"(*Rows).ColumnTypes", Method, 8},
+ {"(*Rows).Columns", Method, 0},
+ {"(*Rows).Err", Method, 0},
+ {"(*Rows).Next", Method, 0},
+ {"(*Rows).NextResultSet", Method, 8},
+ {"(*Rows).Scan", Method, 0},
+ {"(*Stmt).Close", Method, 0},
+ {"(*Stmt).Exec", Method, 0},
+ {"(*Stmt).ExecContext", Method, 8},
+ {"(*Stmt).Query", Method, 0},
+ {"(*Stmt).QueryContext", Method, 8},
+ {"(*Stmt).QueryRow", Method, 0},
+ {"(*Stmt).QueryRowContext", Method, 8},
+ {"(*Tx).Commit", Method, 0},
+ {"(*Tx).Exec", Method, 0},
+ {"(*Tx).ExecContext", Method, 8},
+ {"(*Tx).Prepare", Method, 0},
+ {"(*Tx).PrepareContext", Method, 8},
+ {"(*Tx).Query", Method, 0},
+ {"(*Tx).QueryContext", Method, 8},
+ {"(*Tx).QueryRow", Method, 0},
+ {"(*Tx).QueryRowContext", Method, 8},
+ {"(*Tx).Rollback", Method, 0},
+ {"(*Tx).Stmt", Method, 0},
+ {"(*Tx).StmtContext", Method, 8},
+ {"(IsolationLevel).String", Method, 11},
+ {"(Null).Value", Method, 22},
+ {"(NullBool).Value", Method, 0},
+ {"(NullByte).Value", Method, 17},
+ {"(NullFloat64).Value", Method, 0},
+ {"(NullInt16).Value", Method, 17},
+ {"(NullInt32).Value", Method, 13},
+ {"(NullInt64).Value", Method, 0},
+ {"(NullString).Value", Method, 0},
+ {"(NullTime).Value", Method, 13},
+ {"ColumnType", Type, 8},
+ {"Conn", Type, 9},
+ {"DB", Type, 0},
+ {"DBStats", Type, 5},
+ {"DBStats.Idle", Field, 11},
+ {"DBStats.InUse", Field, 11},
+ {"DBStats.MaxIdleClosed", Field, 11},
+ {"DBStats.MaxIdleTimeClosed", Field, 15},
+ {"DBStats.MaxLifetimeClosed", Field, 11},
+ {"DBStats.MaxOpenConnections", Field, 11},
+ {"DBStats.OpenConnections", Field, 5},
+ {"DBStats.WaitCount", Field, 11},
+ {"DBStats.WaitDuration", Field, 11},
+ {"Drivers", Func, 4},
+ {"ErrConnDone", Var, 9},
+ {"ErrNoRows", Var, 0},
+ {"ErrTxDone", Var, 0},
+ {"IsolationLevel", Type, 8},
+ {"LevelDefault", Const, 8},
+ {"LevelLinearizable", Const, 8},
+ {"LevelReadCommitted", Const, 8},
+ {"LevelReadUncommitted", Const, 8},
+ {"LevelRepeatableRead", Const, 8},
+ {"LevelSerializable", Const, 8},
+ {"LevelSnapshot", Const, 8},
+ {"LevelWriteCommitted", Const, 8},
+ {"Named", Func, 8},
+ {"NamedArg", Type, 8},
+ {"NamedArg.Name", Field, 8},
+ {"NamedArg.Value", Field, 8},
+ {"Null", Type, 22},
+ {"Null.V", Field, 22},
+ {"Null.Valid", Field, 22},
+ {"NullBool", Type, 0},
+ {"NullBool.Bool", Field, 0},
+ {"NullBool.Valid", Field, 0},
+ {"NullByte", Type, 17},
+ {"NullByte.Byte", Field, 17},
+ {"NullByte.Valid", Field, 17},
+ {"NullFloat64", Type, 0},
+ {"NullFloat64.Float64", Field, 0},
+ {"NullFloat64.Valid", Field, 0},
+ {"NullInt16", Type, 17},
+ {"NullInt16.Int16", Field, 17},
+ {"NullInt16.Valid", Field, 17},
+ {"NullInt32", Type, 13},
+ {"NullInt32.Int32", Field, 13},
+ {"NullInt32.Valid", Field, 13},
+ {"NullInt64", Type, 0},
+ {"NullInt64.Int64", Field, 0},
+ {"NullInt64.Valid", Field, 0},
+ {"NullString", Type, 0},
+ {"NullString.String", Field, 0},
+ {"NullString.Valid", Field, 0},
+ {"NullTime", Type, 13},
+ {"NullTime.Time", Field, 13},
+ {"NullTime.Valid", Field, 13},
+ {"Open", Func, 0},
+ {"OpenDB", Func, 10},
+ {"Out", Type, 9},
+ {"Out.Dest", Field, 9},
+ {"Out.In", Field, 9},
+ {"RawBytes", Type, 0},
+ {"Register", Func, 0},
+ {"Result", Type, 0},
+ {"Row", Type, 0},
+ {"Rows", Type, 0},
+ {"Scanner", Type, 0},
+ {"Stmt", Type, 0},
+ {"Tx", Type, 0},
+ {"TxOptions", Type, 8},
+ {"TxOptions.Isolation", Field, 8},
+ {"TxOptions.ReadOnly", Field, 8},
+ },
+ "database/sql/driver": {
+ {"(NotNull).ConvertValue", Method, 0},
+ {"(Null).ConvertValue", Method, 0},
+ {"(RowsAffected).LastInsertId", Method, 0},
+ {"(RowsAffected).RowsAffected", Method, 0},
+ {"Bool", Var, 0},
+ {"ColumnConverter", Type, 0},
+ {"Conn", Type, 0},
+ {"ConnBeginTx", Type, 8},
+ {"ConnPrepareContext", Type, 8},
+ {"Connector", Type, 10},
+ {"DefaultParameterConverter", Var, 0},
+ {"Driver", Type, 0},
+ {"DriverContext", Type, 10},
+ {"ErrBadConn", Var, 0},
+ {"ErrRemoveArgument", Var, 9},
+ {"ErrSkip", Var, 0},
+ {"Execer", Type, 0},
+ {"ExecerContext", Type, 8},
+ {"Int32", Var, 0},
+ {"IsScanValue", Func, 0},
+ {"IsValue", Func, 0},
+ {"IsolationLevel", Type, 8},
+ {"NamedValue", Type, 8},
+ {"NamedValue.Name", Field, 8},
+ {"NamedValue.Ordinal", Field, 8},
+ {"NamedValue.Value", Field, 8},
+ {"NamedValueChecker", Type, 9},
+ {"NotNull", Type, 0},
+ {"NotNull.Converter", Field, 0},
+ {"Null", Type, 0},
+ {"Null.Converter", Field, 0},
+ {"Pinger", Type, 8},
+ {"Queryer", Type, 1},
+ {"QueryerContext", Type, 8},
+ {"Result", Type, 0},
+ {"ResultNoRows", Var, 0},
+ {"Rows", Type, 0},
+ {"RowsAffected", Type, 0},
+ {"RowsColumnTypeDatabaseTypeName", Type, 8},
+ {"RowsColumnTypeLength", Type, 8},
+ {"RowsColumnTypeNullable", Type, 8},
+ {"RowsColumnTypePrecisionScale", Type, 8},
+ {"RowsColumnTypeScanType", Type, 8},
+ {"RowsNextResultSet", Type, 8},
+ {"SessionResetter", Type, 10},
+ {"Stmt", Type, 0},
+ {"StmtExecContext", Type, 8},
+ {"StmtQueryContext", Type, 8},
+ {"String", Var, 0},
+ {"Tx", Type, 0},
+ {"TxOptions", Type, 8},
+ {"TxOptions.Isolation", Field, 8},
+ {"TxOptions.ReadOnly", Field, 8},
+ {"Validator", Type, 15},
+ {"Value", Type, 0},
+ {"ValueConverter", Type, 0},
+ {"Valuer", Type, 0},
+ },
+ "debug/buildinfo": {
+ {"BuildInfo", Type, 18},
+ {"Read", Func, 18},
+ {"ReadFile", Func, 18},
+ },
+ "debug/dwarf": {
+ {"(*AddrType).Basic", Method, 0},
+ {"(*AddrType).Common", Method, 0},
+ {"(*AddrType).Size", Method, 0},
+ {"(*AddrType).String", Method, 0},
+ {"(*ArrayType).Common", Method, 0},
+ {"(*ArrayType).Size", Method, 0},
+ {"(*ArrayType).String", Method, 0},
+ {"(*BasicType).Basic", Method, 0},
+ {"(*BasicType).Common", Method, 0},
+ {"(*BasicType).Size", Method, 0},
+ {"(*BasicType).String", Method, 0},
+ {"(*BoolType).Basic", Method, 0},
+ {"(*BoolType).Common", Method, 0},
+ {"(*BoolType).Size", Method, 0},
+ {"(*BoolType).String", Method, 0},
+ {"(*CharType).Basic", Method, 0},
+ {"(*CharType).Common", Method, 0},
+ {"(*CharType).Size", Method, 0},
+ {"(*CharType).String", Method, 0},
+ {"(*CommonType).Common", Method, 0},
+ {"(*CommonType).Size", Method, 0},
+ {"(*ComplexType).Basic", Method, 0},
+ {"(*ComplexType).Common", Method, 0},
+ {"(*ComplexType).Size", Method, 0},
+ {"(*ComplexType).String", Method, 0},
+ {"(*Data).AddSection", Method, 14},
+ {"(*Data).AddTypes", Method, 3},
+ {"(*Data).LineReader", Method, 5},
+ {"(*Data).Ranges", Method, 7},
+ {"(*Data).Reader", Method, 0},
+ {"(*Data).Type", Method, 0},
+ {"(*DotDotDotType).Common", Method, 0},
+ {"(*DotDotDotType).Size", Method, 0},
+ {"(*DotDotDotType).String", Method, 0},
+ {"(*Entry).AttrField", Method, 5},
+ {"(*Entry).Val", Method, 0},
+ {"(*EnumType).Common", Method, 0},
+ {"(*EnumType).Size", Method, 0},
+ {"(*EnumType).String", Method, 0},
+ {"(*FloatType).Basic", Method, 0},
+ {"(*FloatType).Common", Method, 0},
+ {"(*FloatType).Size", Method, 0},
+ {"(*FloatType).String", Method, 0},
+ {"(*FuncType).Common", Method, 0},
+ {"(*FuncType).Size", Method, 0},
+ {"(*FuncType).String", Method, 0},
+ {"(*IntType).Basic", Method, 0},
+ {"(*IntType).Common", Method, 0},
+ {"(*IntType).Size", Method, 0},
+ {"(*IntType).String", Method, 0},
+ {"(*LineReader).Files", Method, 14},
+ {"(*LineReader).Next", Method, 5},
+ {"(*LineReader).Reset", Method, 5},
+ {"(*LineReader).Seek", Method, 5},
+ {"(*LineReader).SeekPC", Method, 5},
+ {"(*LineReader).Tell", Method, 5},
+ {"(*PtrType).Common", Method, 0},
+ {"(*PtrType).Size", Method, 0},
+ {"(*PtrType).String", Method, 0},
+ {"(*QualType).Common", Method, 0},
+ {"(*QualType).Size", Method, 0},
+ {"(*QualType).String", Method, 0},
+ {"(*Reader).AddressSize", Method, 5},
+ {"(*Reader).ByteOrder", Method, 14},
+ {"(*Reader).Next", Method, 0},
+ {"(*Reader).Seek", Method, 0},
+ {"(*Reader).SeekPC", Method, 7},
+ {"(*Reader).SkipChildren", Method, 0},
+ {"(*StructType).Common", Method, 0},
+ {"(*StructType).Defn", Method, 0},
+ {"(*StructType).Size", Method, 0},
+ {"(*StructType).String", Method, 0},
+ {"(*TypedefType).Common", Method, 0},
+ {"(*TypedefType).Size", Method, 0},
+ {"(*TypedefType).String", Method, 0},
+ {"(*UcharType).Basic", Method, 0},
+ {"(*UcharType).Common", Method, 0},
+ {"(*UcharType).Size", Method, 0},
+ {"(*UcharType).String", Method, 0},
+ {"(*UintType).Basic", Method, 0},
+ {"(*UintType).Common", Method, 0},
+ {"(*UintType).Size", Method, 0},
+ {"(*UintType).String", Method, 0},
+ {"(*UnspecifiedType).Basic", Method, 4},
+ {"(*UnspecifiedType).Common", Method, 4},
+ {"(*UnspecifiedType).Size", Method, 4},
+ {"(*UnspecifiedType).String", Method, 4},
+ {"(*UnsupportedType).Common", Method, 13},
+ {"(*UnsupportedType).Size", Method, 13},
+ {"(*UnsupportedType).String", Method, 13},
+ {"(*VoidType).Common", Method, 0},
+ {"(*VoidType).Size", Method, 0},
+ {"(*VoidType).String", Method, 0},
+ {"(Attr).GoString", Method, 0},
+ {"(Attr).String", Method, 0},
+ {"(Class).GoString", Method, 5},
+ {"(Class).String", Method, 5},
+ {"(DecodeError).Error", Method, 0},
+ {"(Tag).GoString", Method, 0},
+ {"(Tag).String", Method, 0},
+ {"AddrType", Type, 0},
+ {"AddrType.BasicType", Field, 0},
+ {"ArrayType", Type, 0},
+ {"ArrayType.CommonType", Field, 0},
+ {"ArrayType.Count", Field, 0},
+ {"ArrayType.StrideBitSize", Field, 0},
+ {"ArrayType.Type", Field, 0},
+ {"Attr", Type, 0},
+ {"AttrAbstractOrigin", Const, 0},
+ {"AttrAccessibility", Const, 0},
+ {"AttrAddrBase", Const, 14},
+ {"AttrAddrClass", Const, 0},
+ {"AttrAlignment", Const, 14},
+ {"AttrAllocated", Const, 0},
+ {"AttrArtificial", Const, 0},
+ {"AttrAssociated", Const, 0},
+ {"AttrBaseTypes", Const, 0},
+ {"AttrBinaryScale", Const, 14},
+ {"AttrBitOffset", Const, 0},
+ {"AttrBitSize", Const, 0},
+ {"AttrByteSize", Const, 0},
+ {"AttrCallAllCalls", Const, 14},
+ {"AttrCallAllSourceCalls", Const, 14},
+ {"AttrCallAllTailCalls", Const, 14},
+ {"AttrCallColumn", Const, 0},
+ {"AttrCallDataLocation", Const, 14},
+ {"AttrCallDataValue", Const, 14},
+ {"AttrCallFile", Const, 0},
+ {"AttrCallLine", Const, 0},
+ {"AttrCallOrigin", Const, 14},
+ {"AttrCallPC", Const, 14},
+ {"AttrCallParameter", Const, 14},
+ {"AttrCallReturnPC", Const, 14},
+ {"AttrCallTailCall", Const, 14},
+ {"AttrCallTarget", Const, 14},
+ {"AttrCallTargetClobbered", Const, 14},
+ {"AttrCallValue", Const, 14},
+ {"AttrCalling", Const, 0},
+ {"AttrCommonRef", Const, 0},
+ {"AttrCompDir", Const, 0},
+ {"AttrConstExpr", Const, 14},
+ {"AttrConstValue", Const, 0},
+ {"AttrContainingType", Const, 0},
+ {"AttrCount", Const, 0},
+ {"AttrDataBitOffset", Const, 14},
+ {"AttrDataLocation", Const, 0},
+ {"AttrDataMemberLoc", Const, 0},
+ {"AttrDecimalScale", Const, 14},
+ {"AttrDecimalSign", Const, 14},
+ {"AttrDeclColumn", Const, 0},
+ {"AttrDeclFile", Const, 0},
+ {"AttrDeclLine", Const, 0},
+ {"AttrDeclaration", Const, 0},
+ {"AttrDefaultValue", Const, 0},
+ {"AttrDefaulted", Const, 14},
+ {"AttrDeleted", Const, 14},
+ {"AttrDescription", Const, 0},
+ {"AttrDigitCount", Const, 14},
+ {"AttrDiscr", Const, 0},
+ {"AttrDiscrList", Const, 0},
+ {"AttrDiscrValue", Const, 0},
+ {"AttrDwoName", Const, 14},
+ {"AttrElemental", Const, 14},
+ {"AttrEncoding", Const, 0},
+ {"AttrEndianity", Const, 14},
+ {"AttrEntrypc", Const, 0},
+ {"AttrEnumClass", Const, 14},
+ {"AttrExplicit", Const, 14},
+ {"AttrExportSymbols", Const, 14},
+ {"AttrExtension", Const, 0},
+ {"AttrExternal", Const, 0},
+ {"AttrFrameBase", Const, 0},
+ {"AttrFriend", Const, 0},
+ {"AttrHighpc", Const, 0},
+ {"AttrIdentifierCase", Const, 0},
+ {"AttrImport", Const, 0},
+ {"AttrInline", Const, 0},
+ {"AttrIsOptional", Const, 0},
+ {"AttrLanguage", Const, 0},
+ {"AttrLinkageName", Const, 14},
+ {"AttrLocation", Const, 0},
+ {"AttrLoclistsBase", Const, 14},
+ {"AttrLowerBound", Const, 0},
+ {"AttrLowpc", Const, 0},
+ {"AttrMacroInfo", Const, 0},
+ {"AttrMacros", Const, 14},
+ {"AttrMainSubprogram", Const, 14},
+ {"AttrMutable", Const, 14},
+ {"AttrName", Const, 0},
+ {"AttrNamelistItem", Const, 0},
+ {"AttrNoreturn", Const, 14},
+ {"AttrObjectPointer", Const, 14},
+ {"AttrOrdering", Const, 0},
+ {"AttrPictureString", Const, 14},
+ {"AttrPriority", Const, 0},
+ {"AttrProducer", Const, 0},
+ {"AttrPrototyped", Const, 0},
+ {"AttrPure", Const, 14},
+ {"AttrRanges", Const, 0},
+ {"AttrRank", Const, 14},
+ {"AttrRecursive", Const, 14},
+ {"AttrReference", Const, 14},
+ {"AttrReturnAddr", Const, 0},
+ {"AttrRnglistsBase", Const, 14},
+ {"AttrRvalueReference", Const, 14},
+ {"AttrSegment", Const, 0},
+ {"AttrSibling", Const, 0},
+ {"AttrSignature", Const, 14},
+ {"AttrSmall", Const, 14},
+ {"AttrSpecification", Const, 0},
+ {"AttrStartScope", Const, 0},
+ {"AttrStaticLink", Const, 0},
+ {"AttrStmtList", Const, 0},
+ {"AttrStrOffsetsBase", Const, 14},
+ {"AttrStride", Const, 0},
+ {"AttrStrideSize", Const, 0},
+ {"AttrStringLength", Const, 0},
+ {"AttrStringLengthBitSize", Const, 14},
+ {"AttrStringLengthByteSize", Const, 14},
+ {"AttrThreadsScaled", Const, 14},
+ {"AttrTrampoline", Const, 0},
+ {"AttrType", Const, 0},
+ {"AttrUpperBound", Const, 0},
+ {"AttrUseLocation", Const, 0},
+ {"AttrUseUTF8", Const, 0},
+ {"AttrVarParam", Const, 0},
+ {"AttrVirtuality", Const, 0},
+ {"AttrVisibility", Const, 0},
+ {"AttrVtableElemLoc", Const, 0},
+ {"BasicType", Type, 0},
+ {"BasicType.BitOffset", Field, 0},
+ {"BasicType.BitSize", Field, 0},
+ {"BasicType.CommonType", Field, 0},
+ {"BasicType.DataBitOffset", Field, 18},
+ {"BoolType", Type, 0},
+ {"BoolType.BasicType", Field, 0},
+ {"CharType", Type, 0},
+ {"CharType.BasicType", Field, 0},
+ {"Class", Type, 5},
+ {"ClassAddrPtr", Const, 14},
+ {"ClassAddress", Const, 5},
+ {"ClassBlock", Const, 5},
+ {"ClassConstant", Const, 5},
+ {"ClassExprLoc", Const, 5},
+ {"ClassFlag", Const, 5},
+ {"ClassLinePtr", Const, 5},
+ {"ClassLocList", Const, 14},
+ {"ClassLocListPtr", Const, 5},
+ {"ClassMacPtr", Const, 5},
+ {"ClassRangeListPtr", Const, 5},
+ {"ClassReference", Const, 5},
+ {"ClassReferenceAlt", Const, 5},
+ {"ClassReferenceSig", Const, 5},
+ {"ClassRngList", Const, 14},
+ {"ClassRngListsPtr", Const, 14},
+ {"ClassStrOffsetsPtr", Const, 14},
+ {"ClassString", Const, 5},
+ {"ClassStringAlt", Const, 5},
+ {"ClassUnknown", Const, 6},
+ {"CommonType", Type, 0},
+ {"CommonType.ByteSize", Field, 0},
+ {"CommonType.Name", Field, 0},
+ {"ComplexType", Type, 0},
+ {"ComplexType.BasicType", Field, 0},
+ {"Data", Type, 0},
+ {"DecodeError", Type, 0},
+ {"DecodeError.Err", Field, 0},
+ {"DecodeError.Name", Field, 0},
+ {"DecodeError.Offset", Field, 0},
+ {"DotDotDotType", Type, 0},
+ {"DotDotDotType.CommonType", Field, 0},
+ {"Entry", Type, 0},
+ {"Entry.Children", Field, 0},
+ {"Entry.Field", Field, 0},
+ {"Entry.Offset", Field, 0},
+ {"Entry.Tag", Field, 0},
+ {"EnumType", Type, 0},
+ {"EnumType.CommonType", Field, 0},
+ {"EnumType.EnumName", Field, 0},
+ {"EnumType.Val", Field, 0},
+ {"EnumValue", Type, 0},
+ {"EnumValue.Name", Field, 0},
+ {"EnumValue.Val", Field, 0},
+ {"ErrUnknownPC", Var, 5},
+ {"Field", Type, 0},
+ {"Field.Attr", Field, 0},
+ {"Field.Class", Field, 5},
+ {"Field.Val", Field, 0},
+ {"FloatType", Type, 0},
+ {"FloatType.BasicType", Field, 0},
+ {"FuncType", Type, 0},
+ {"FuncType.CommonType", Field, 0},
+ {"FuncType.ParamType", Field, 0},
+ {"FuncType.ReturnType", Field, 0},
+ {"IntType", Type, 0},
+ {"IntType.BasicType", Field, 0},
+ {"LineEntry", Type, 5},
+ {"LineEntry.Address", Field, 5},
+ {"LineEntry.BasicBlock", Field, 5},
+ {"LineEntry.Column", Field, 5},
+ {"LineEntry.Discriminator", Field, 5},
+ {"LineEntry.EndSequence", Field, 5},
+ {"LineEntry.EpilogueBegin", Field, 5},
+ {"LineEntry.File", Field, 5},
+ {"LineEntry.ISA", Field, 5},
+ {"LineEntry.IsStmt", Field, 5},
+ {"LineEntry.Line", Field, 5},
+ {"LineEntry.OpIndex", Field, 5},
+ {"LineEntry.PrologueEnd", Field, 5},
+ {"LineFile", Type, 5},
+ {"LineFile.Length", Field, 5},
+ {"LineFile.Mtime", Field, 5},
+ {"LineFile.Name", Field, 5},
+ {"LineReader", Type, 5},
+ {"LineReaderPos", Type, 5},
+ {"New", Func, 0},
+ {"Offset", Type, 0},
+ {"PtrType", Type, 0},
+ {"PtrType.CommonType", Field, 0},
+ {"PtrType.Type", Field, 0},
+ {"QualType", Type, 0},
+ {"QualType.CommonType", Field, 0},
+ {"QualType.Qual", Field, 0},
+ {"QualType.Type", Field, 0},
+ {"Reader", Type, 0},
+ {"StructField", Type, 0},
+ {"StructField.BitOffset", Field, 0},
+ {"StructField.BitSize", Field, 0},
+ {"StructField.ByteOffset", Field, 0},
+ {"StructField.ByteSize", Field, 0},
+ {"StructField.DataBitOffset", Field, 18},
+ {"StructField.Name", Field, 0},
+ {"StructField.Type", Field, 0},
+ {"StructType", Type, 0},
+ {"StructType.CommonType", Field, 0},
+ {"StructType.Field", Field, 0},
+ {"StructType.Incomplete", Field, 0},
+ {"StructType.Kind", Field, 0},
+ {"StructType.StructName", Field, 0},
+ {"Tag", Type, 0},
+ {"TagAccessDeclaration", Const, 0},
+ {"TagArrayType", Const, 0},
+ {"TagAtomicType", Const, 14},
+ {"TagBaseType", Const, 0},
+ {"TagCallSite", Const, 14},
+ {"TagCallSiteParameter", Const, 14},
+ {"TagCatchDwarfBlock", Const, 0},
+ {"TagClassType", Const, 0},
+ {"TagCoarrayType", Const, 14},
+ {"TagCommonDwarfBlock", Const, 0},
+ {"TagCommonInclusion", Const, 0},
+ {"TagCompileUnit", Const, 0},
+ {"TagCondition", Const, 3},
+ {"TagConstType", Const, 0},
+ {"TagConstant", Const, 0},
+ {"TagDwarfProcedure", Const, 0},
+ {"TagDynamicType", Const, 14},
+ {"TagEntryPoint", Const, 0},
+ {"TagEnumerationType", Const, 0},
+ {"TagEnumerator", Const, 0},
+ {"TagFileType", Const, 0},
+ {"TagFormalParameter", Const, 0},
+ {"TagFriend", Const, 0},
+ {"TagGenericSubrange", Const, 14},
+ {"TagImmutableType", Const, 14},
+ {"TagImportedDeclaration", Const, 0},
+ {"TagImportedModule", Const, 0},
+ {"TagImportedUnit", Const, 0},
+ {"TagInheritance", Const, 0},
+ {"TagInlinedSubroutine", Const, 0},
+ {"TagInterfaceType", Const, 0},
+ {"TagLabel", Const, 0},
+ {"TagLexDwarfBlock", Const, 0},
+ {"TagMember", Const, 0},
+ {"TagModule", Const, 0},
+ {"TagMutableType", Const, 0},
+ {"TagNamelist", Const, 0},
+ {"TagNamelistItem", Const, 0},
+ {"TagNamespace", Const, 0},
+ {"TagPackedType", Const, 0},
+ {"TagPartialUnit", Const, 0},
+ {"TagPointerType", Const, 0},
+ {"TagPtrToMemberType", Const, 0},
+ {"TagReferenceType", Const, 0},
+ {"TagRestrictType", Const, 0},
+ {"TagRvalueReferenceType", Const, 3},
+ {"TagSetType", Const, 0},
+ {"TagSharedType", Const, 3},
+ {"TagSkeletonUnit", Const, 14},
+ {"TagStringType", Const, 0},
+ {"TagStructType", Const, 0},
+ {"TagSubprogram", Const, 0},
+ {"TagSubrangeType", Const, 0},
+ {"TagSubroutineType", Const, 0},
+ {"TagTemplateAlias", Const, 3},
+ {"TagTemplateTypeParameter", Const, 0},
+ {"TagTemplateValueParameter", Const, 0},
+ {"TagThrownType", Const, 0},
+ {"TagTryDwarfBlock", Const, 0},
+ {"TagTypeUnit", Const, 3},
+ {"TagTypedef", Const, 0},
+ {"TagUnionType", Const, 0},
+ {"TagUnspecifiedParameters", Const, 0},
+ {"TagUnspecifiedType", Const, 0},
+ {"TagVariable", Const, 0},
+ {"TagVariant", Const, 0},
+ {"TagVariantPart", Const, 0},
+ {"TagVolatileType", Const, 0},
+ {"TagWithStmt", Const, 0},
+ {"Type", Type, 0},
+ {"TypedefType", Type, 0},
+ {"TypedefType.CommonType", Field, 0},
+ {"TypedefType.Type", Field, 0},
+ {"UcharType", Type, 0},
+ {"UcharType.BasicType", Field, 0},
+ {"UintType", Type, 0},
+ {"UintType.BasicType", Field, 0},
+ {"UnspecifiedType", Type, 4},
+ {"UnspecifiedType.BasicType", Field, 4},
+ {"UnsupportedType", Type, 13},
+ {"UnsupportedType.CommonType", Field, 13},
+ {"UnsupportedType.Tag", Field, 13},
+ {"VoidType", Type, 0},
+ {"VoidType.CommonType", Field, 0},
+ },
+ "debug/elf": {
+ {"(*File).Close", Method, 0},
+ {"(*File).DWARF", Method, 0},
+ {"(*File).DynString", Method, 1},
+ {"(*File).DynValue", Method, 21},
+ {"(*File).DynamicSymbols", Method, 4},
+ {"(*File).ImportedLibraries", Method, 0},
+ {"(*File).ImportedSymbols", Method, 0},
+ {"(*File).Section", Method, 0},
+ {"(*File).SectionByType", Method, 0},
+ {"(*File).Symbols", Method, 0},
+ {"(*FormatError).Error", Method, 0},
+ {"(*Prog).Open", Method, 0},
+ {"(*Section).Data", Method, 0},
+ {"(*Section).Open", Method, 0},
+ {"(Class).GoString", Method, 0},
+ {"(Class).String", Method, 0},
+ {"(CompressionType).GoString", Method, 6},
+ {"(CompressionType).String", Method, 6},
+ {"(Data).GoString", Method, 0},
+ {"(Data).String", Method, 0},
+ {"(DynFlag).GoString", Method, 0},
+ {"(DynFlag).String", Method, 0},
+ {"(DynFlag1).GoString", Method, 21},
+ {"(DynFlag1).String", Method, 21},
+ {"(DynTag).GoString", Method, 0},
+ {"(DynTag).String", Method, 0},
+ {"(Machine).GoString", Method, 0},
+ {"(Machine).String", Method, 0},
+ {"(NType).GoString", Method, 0},
+ {"(NType).String", Method, 0},
+ {"(OSABI).GoString", Method, 0},
+ {"(OSABI).String", Method, 0},
+ {"(Prog).ReadAt", Method, 0},
+ {"(ProgFlag).GoString", Method, 0},
+ {"(ProgFlag).String", Method, 0},
+ {"(ProgType).GoString", Method, 0},
+ {"(ProgType).String", Method, 0},
+ {"(R_386).GoString", Method, 0},
+ {"(R_386).String", Method, 0},
+ {"(R_390).GoString", Method, 7},
+ {"(R_390).String", Method, 7},
+ {"(R_AARCH64).GoString", Method, 4},
+ {"(R_AARCH64).String", Method, 4},
+ {"(R_ALPHA).GoString", Method, 0},
+ {"(R_ALPHA).String", Method, 0},
+ {"(R_ARM).GoString", Method, 0},
+ {"(R_ARM).String", Method, 0},
+ {"(R_LARCH).GoString", Method, 19},
+ {"(R_LARCH).String", Method, 19},
+ {"(R_MIPS).GoString", Method, 6},
+ {"(R_MIPS).String", Method, 6},
+ {"(R_PPC).GoString", Method, 0},
+ {"(R_PPC).String", Method, 0},
+ {"(R_PPC64).GoString", Method, 5},
+ {"(R_PPC64).String", Method, 5},
+ {"(R_RISCV).GoString", Method, 11},
+ {"(R_RISCV).String", Method, 11},
+ {"(R_SPARC).GoString", Method, 0},
+ {"(R_SPARC).String", Method, 0},
+ {"(R_X86_64).GoString", Method, 0},
+ {"(R_X86_64).String", Method, 0},
+ {"(Section).ReadAt", Method, 0},
+ {"(SectionFlag).GoString", Method, 0},
+ {"(SectionFlag).String", Method, 0},
+ {"(SectionIndex).GoString", Method, 0},
+ {"(SectionIndex).String", Method, 0},
+ {"(SectionType).GoString", Method, 0},
+ {"(SectionType).String", Method, 0},
+ {"(SymBind).GoString", Method, 0},
+ {"(SymBind).String", Method, 0},
+ {"(SymType).GoString", Method, 0},
+ {"(SymType).String", Method, 0},
+ {"(SymVis).GoString", Method, 0},
+ {"(SymVis).String", Method, 0},
+ {"(Type).GoString", Method, 0},
+ {"(Type).String", Method, 0},
+ {"(Version).GoString", Method, 0},
+ {"(Version).String", Method, 0},
+ {"ARM_MAGIC_TRAMP_NUMBER", Const, 0},
+ {"COMPRESS_HIOS", Const, 6},
+ {"COMPRESS_HIPROC", Const, 6},
+ {"COMPRESS_LOOS", Const, 6},
+ {"COMPRESS_LOPROC", Const, 6},
+ {"COMPRESS_ZLIB", Const, 6},
+ {"COMPRESS_ZSTD", Const, 21},
+ {"Chdr32", Type, 6},
+ {"Chdr32.Addralign", Field, 6},
+ {"Chdr32.Size", Field, 6},
+ {"Chdr32.Type", Field, 6},
+ {"Chdr64", Type, 6},
+ {"Chdr64.Addralign", Field, 6},
+ {"Chdr64.Size", Field, 6},
+ {"Chdr64.Type", Field, 6},
+ {"Class", Type, 0},
+ {"CompressionType", Type, 6},
+ {"DF_1_CONFALT", Const, 21},
+ {"DF_1_DIRECT", Const, 21},
+ {"DF_1_DISPRELDNE", Const, 21},
+ {"DF_1_DISPRELPND", Const, 21},
+ {"DF_1_EDITED", Const, 21},
+ {"DF_1_ENDFILTEE", Const, 21},
+ {"DF_1_GLOBAL", Const, 21},
+ {"DF_1_GLOBAUDIT", Const, 21},
+ {"DF_1_GROUP", Const, 21},
+ {"DF_1_IGNMULDEF", Const, 21},
+ {"DF_1_INITFIRST", Const, 21},
+ {"DF_1_INTERPOSE", Const, 21},
+ {"DF_1_KMOD", Const, 21},
+ {"DF_1_LOADFLTR", Const, 21},
+ {"DF_1_NOCOMMON", Const, 21},
+ {"DF_1_NODEFLIB", Const, 21},
+ {"DF_1_NODELETE", Const, 21},
+ {"DF_1_NODIRECT", Const, 21},
+ {"DF_1_NODUMP", Const, 21},
+ {"DF_1_NOHDR", Const, 21},
+ {"DF_1_NOKSYMS", Const, 21},
+ {"DF_1_NOOPEN", Const, 21},
+ {"DF_1_NORELOC", Const, 21},
+ {"DF_1_NOW", Const, 21},
+ {"DF_1_ORIGIN", Const, 21},
+ {"DF_1_PIE", Const, 21},
+ {"DF_1_SINGLETON", Const, 21},
+ {"DF_1_STUB", Const, 21},
+ {"DF_1_SYMINTPOSE", Const, 21},
+ {"DF_1_TRANS", Const, 21},
+ {"DF_1_WEAKFILTER", Const, 21},
+ {"DF_BIND_NOW", Const, 0},
+ {"DF_ORIGIN", Const, 0},
+ {"DF_STATIC_TLS", Const, 0},
+ {"DF_SYMBOLIC", Const, 0},
+ {"DF_TEXTREL", Const, 0},
+ {"DT_ADDRRNGHI", Const, 16},
+ {"DT_ADDRRNGLO", Const, 16},
+ {"DT_AUDIT", Const, 16},
+ {"DT_AUXILIARY", Const, 16},
+ {"DT_BIND_NOW", Const, 0},
+ {"DT_CHECKSUM", Const, 16},
+ {"DT_CONFIG", Const, 16},
+ {"DT_DEBUG", Const, 0},
+ {"DT_DEPAUDIT", Const, 16},
+ {"DT_ENCODING", Const, 0},
+ {"DT_FEATURE", Const, 16},
+ {"DT_FILTER", Const, 16},
+ {"DT_FINI", Const, 0},
+ {"DT_FINI_ARRAY", Const, 0},
+ {"DT_FINI_ARRAYSZ", Const, 0},
+ {"DT_FLAGS", Const, 0},
+ {"DT_FLAGS_1", Const, 16},
+ {"DT_GNU_CONFLICT", Const, 16},
+ {"DT_GNU_CONFLICTSZ", Const, 16},
+ {"DT_GNU_HASH", Const, 16},
+ {"DT_GNU_LIBLIST", Const, 16},
+ {"DT_GNU_LIBLISTSZ", Const, 16},
+ {"DT_GNU_PRELINKED", Const, 16},
+ {"DT_HASH", Const, 0},
+ {"DT_HIOS", Const, 0},
+ {"DT_HIPROC", Const, 0},
+ {"DT_INIT", Const, 0},
+ {"DT_INIT_ARRAY", Const, 0},
+ {"DT_INIT_ARRAYSZ", Const, 0},
+ {"DT_JMPREL", Const, 0},
+ {"DT_LOOS", Const, 0},
+ {"DT_LOPROC", Const, 0},
+ {"DT_MIPS_AUX_DYNAMIC", Const, 16},
+ {"DT_MIPS_BASE_ADDRESS", Const, 16},
+ {"DT_MIPS_COMPACT_SIZE", Const, 16},
+ {"DT_MIPS_CONFLICT", Const, 16},
+ {"DT_MIPS_CONFLICTNO", Const, 16},
+ {"DT_MIPS_CXX_FLAGS", Const, 16},
+ {"DT_MIPS_DELTA_CLASS", Const, 16},
+ {"DT_MIPS_DELTA_CLASSSYM", Const, 16},
+ {"DT_MIPS_DELTA_CLASSSYM_NO", Const, 16},
+ {"DT_MIPS_DELTA_CLASS_NO", Const, 16},
+ {"DT_MIPS_DELTA_INSTANCE", Const, 16},
+ {"DT_MIPS_DELTA_INSTANCE_NO", Const, 16},
+ {"DT_MIPS_DELTA_RELOC", Const, 16},
+ {"DT_MIPS_DELTA_RELOC_NO", Const, 16},
+ {"DT_MIPS_DELTA_SYM", Const, 16},
+ {"DT_MIPS_DELTA_SYM_NO", Const, 16},
+ {"DT_MIPS_DYNSTR_ALIGN", Const, 16},
+ {"DT_MIPS_FLAGS", Const, 16},
+ {"DT_MIPS_GOTSYM", Const, 16},
+ {"DT_MIPS_GP_VALUE", Const, 16},
+ {"DT_MIPS_HIDDEN_GOTIDX", Const, 16},
+ {"DT_MIPS_HIPAGENO", Const, 16},
+ {"DT_MIPS_ICHECKSUM", Const, 16},
+ {"DT_MIPS_INTERFACE", Const, 16},
+ {"DT_MIPS_INTERFACE_SIZE", Const, 16},
+ {"DT_MIPS_IVERSION", Const, 16},
+ {"DT_MIPS_LIBLIST", Const, 16},
+ {"DT_MIPS_LIBLISTNO", Const, 16},
+ {"DT_MIPS_LOCALPAGE_GOTIDX", Const, 16},
+ {"DT_MIPS_LOCAL_GOTIDX", Const, 16},
+ {"DT_MIPS_LOCAL_GOTNO", Const, 16},
+ {"DT_MIPS_MSYM", Const, 16},
+ {"DT_MIPS_OPTIONS", Const, 16},
+ {"DT_MIPS_PERF_SUFFIX", Const, 16},
+ {"DT_MIPS_PIXIE_INIT", Const, 16},
+ {"DT_MIPS_PLTGOT", Const, 16},
+ {"DT_MIPS_PROTECTED_GOTIDX", Const, 16},
+ {"DT_MIPS_RLD_MAP", Const, 16},
+ {"DT_MIPS_RLD_MAP_REL", Const, 16},
+ {"DT_MIPS_RLD_TEXT_RESOLVE_ADDR", Const, 16},
+ {"DT_MIPS_RLD_VERSION", Const, 16},
+ {"DT_MIPS_RWPLT", Const, 16},
+ {"DT_MIPS_SYMBOL_LIB", Const, 16},
+ {"DT_MIPS_SYMTABNO", Const, 16},
+ {"DT_MIPS_TIME_STAMP", Const, 16},
+ {"DT_MIPS_UNREFEXTNO", Const, 16},
+ {"DT_MOVEENT", Const, 16},
+ {"DT_MOVESZ", Const, 16},
+ {"DT_MOVETAB", Const, 16},
+ {"DT_NEEDED", Const, 0},
+ {"DT_NULL", Const, 0},
+ {"DT_PLTGOT", Const, 0},
+ {"DT_PLTPAD", Const, 16},
+ {"DT_PLTPADSZ", Const, 16},
+ {"DT_PLTREL", Const, 0},
+ {"DT_PLTRELSZ", Const, 0},
+ {"DT_POSFLAG_1", Const, 16},
+ {"DT_PPC64_GLINK", Const, 16},
+ {"DT_PPC64_OPD", Const, 16},
+ {"DT_PPC64_OPDSZ", Const, 16},
+ {"DT_PPC64_OPT", Const, 16},
+ {"DT_PPC_GOT", Const, 16},
+ {"DT_PPC_OPT", Const, 16},
+ {"DT_PREINIT_ARRAY", Const, 0},
+ {"DT_PREINIT_ARRAYSZ", Const, 0},
+ {"DT_REL", Const, 0},
+ {"DT_RELA", Const, 0},
+ {"DT_RELACOUNT", Const, 16},
+ {"DT_RELAENT", Const, 0},
+ {"DT_RELASZ", Const, 0},
+ {"DT_RELCOUNT", Const, 16},
+ {"DT_RELENT", Const, 0},
+ {"DT_RELSZ", Const, 0},
+ {"DT_RPATH", Const, 0},
+ {"DT_RUNPATH", Const, 0},
+ {"DT_SONAME", Const, 0},
+ {"DT_SPARC_REGISTER", Const, 16},
+ {"DT_STRSZ", Const, 0},
+ {"DT_STRTAB", Const, 0},
+ {"DT_SYMBOLIC", Const, 0},
+ {"DT_SYMENT", Const, 0},
+ {"DT_SYMINENT", Const, 16},
+ {"DT_SYMINFO", Const, 16},
+ {"DT_SYMINSZ", Const, 16},
+ {"DT_SYMTAB", Const, 0},
+ {"DT_SYMTAB_SHNDX", Const, 16},
+ {"DT_TEXTREL", Const, 0},
+ {"DT_TLSDESC_GOT", Const, 16},
+ {"DT_TLSDESC_PLT", Const, 16},
+ {"DT_USED", Const, 16},
+ {"DT_VALRNGHI", Const, 16},
+ {"DT_VALRNGLO", Const, 16},
+ {"DT_VERDEF", Const, 16},
+ {"DT_VERDEFNUM", Const, 16},
+ {"DT_VERNEED", Const, 0},
+ {"DT_VERNEEDNUM", Const, 0},
+ {"DT_VERSYM", Const, 0},
+ {"Data", Type, 0},
+ {"Dyn32", Type, 0},
+ {"Dyn32.Tag", Field, 0},
+ {"Dyn32.Val", Field, 0},
+ {"Dyn64", Type, 0},
+ {"Dyn64.Tag", Field, 0},
+ {"Dyn64.Val", Field, 0},
+ {"DynFlag", Type, 0},
+ {"DynFlag1", Type, 21},
+ {"DynTag", Type, 0},
+ {"EI_ABIVERSION", Const, 0},
+ {"EI_CLASS", Const, 0},
+ {"EI_DATA", Const, 0},
+ {"EI_NIDENT", Const, 0},
+ {"EI_OSABI", Const, 0},
+ {"EI_PAD", Const, 0},
+ {"EI_VERSION", Const, 0},
+ {"ELFCLASS32", Const, 0},
+ {"ELFCLASS64", Const, 0},
+ {"ELFCLASSNONE", Const, 0},
+ {"ELFDATA2LSB", Const, 0},
+ {"ELFDATA2MSB", Const, 0},
+ {"ELFDATANONE", Const, 0},
+ {"ELFMAG", Const, 0},
+ {"ELFOSABI_86OPEN", Const, 0},
+ {"ELFOSABI_AIX", Const, 0},
+ {"ELFOSABI_ARM", Const, 0},
+ {"ELFOSABI_AROS", Const, 11},
+ {"ELFOSABI_CLOUDABI", Const, 11},
+ {"ELFOSABI_FENIXOS", Const, 11},
+ {"ELFOSABI_FREEBSD", Const, 0},
+ {"ELFOSABI_HPUX", Const, 0},
+ {"ELFOSABI_HURD", Const, 0},
+ {"ELFOSABI_IRIX", Const, 0},
+ {"ELFOSABI_LINUX", Const, 0},
+ {"ELFOSABI_MODESTO", Const, 0},
+ {"ELFOSABI_NETBSD", Const, 0},
+ {"ELFOSABI_NONE", Const, 0},
+ {"ELFOSABI_NSK", Const, 0},
+ {"ELFOSABI_OPENBSD", Const, 0},
+ {"ELFOSABI_OPENVMS", Const, 0},
+ {"ELFOSABI_SOLARIS", Const, 0},
+ {"ELFOSABI_STANDALONE", Const, 0},
+ {"ELFOSABI_TRU64", Const, 0},
+ {"EM_386", Const, 0},
+ {"EM_486", Const, 0},
+ {"EM_56800EX", Const, 11},
+ {"EM_68HC05", Const, 11},
+ {"EM_68HC08", Const, 11},
+ {"EM_68HC11", Const, 11},
+ {"EM_68HC12", Const, 0},
+ {"EM_68HC16", Const, 11},
+ {"EM_68K", Const, 0},
+ {"EM_78KOR", Const, 11},
+ {"EM_8051", Const, 11},
+ {"EM_860", Const, 0},
+ {"EM_88K", Const, 0},
+ {"EM_960", Const, 0},
+ {"EM_AARCH64", Const, 4},
+ {"EM_ALPHA", Const, 0},
+ {"EM_ALPHA_STD", Const, 0},
+ {"EM_ALTERA_NIOS2", Const, 11},
+ {"EM_AMDGPU", Const, 11},
+ {"EM_ARC", Const, 0},
+ {"EM_ARCA", Const, 11},
+ {"EM_ARC_COMPACT", Const, 11},
+ {"EM_ARC_COMPACT2", Const, 11},
+ {"EM_ARM", Const, 0},
+ {"EM_AVR", Const, 11},
+ {"EM_AVR32", Const, 11},
+ {"EM_BA1", Const, 11},
+ {"EM_BA2", Const, 11},
+ {"EM_BLACKFIN", Const, 11},
+ {"EM_BPF", Const, 11},
+ {"EM_C166", Const, 11},
+ {"EM_CDP", Const, 11},
+ {"EM_CE", Const, 11},
+ {"EM_CLOUDSHIELD", Const, 11},
+ {"EM_COGE", Const, 11},
+ {"EM_COLDFIRE", Const, 0},
+ {"EM_COOL", Const, 11},
+ {"EM_COREA_1ST", Const, 11},
+ {"EM_COREA_2ND", Const, 11},
+ {"EM_CR", Const, 11},
+ {"EM_CR16", Const, 11},
+ {"EM_CRAYNV2", Const, 11},
+ {"EM_CRIS", Const, 11},
+ {"EM_CRX", Const, 11},
+ {"EM_CSR_KALIMBA", Const, 11},
+ {"EM_CUDA", Const, 11},
+ {"EM_CYPRESS_M8C", Const, 11},
+ {"EM_D10V", Const, 11},
+ {"EM_D30V", Const, 11},
+ {"EM_DSP24", Const, 11},
+ {"EM_DSPIC30F", Const, 11},
+ {"EM_DXP", Const, 11},
+ {"EM_ECOG1", Const, 11},
+ {"EM_ECOG16", Const, 11},
+ {"EM_ECOG1X", Const, 11},
+ {"EM_ECOG2", Const, 11},
+ {"EM_ETPU", Const, 11},
+ {"EM_EXCESS", Const, 11},
+ {"EM_F2MC16", Const, 11},
+ {"EM_FIREPATH", Const, 11},
+ {"EM_FR20", Const, 0},
+ {"EM_FR30", Const, 11},
+ {"EM_FT32", Const, 11},
+ {"EM_FX66", Const, 11},
+ {"EM_H8S", Const, 0},
+ {"EM_H8_300", Const, 0},
+ {"EM_H8_300H", Const, 0},
+ {"EM_H8_500", Const, 0},
+ {"EM_HUANY", Const, 11},
+ {"EM_IA_64", Const, 0},
+ {"EM_INTEL205", Const, 11},
+ {"EM_INTEL206", Const, 11},
+ {"EM_INTEL207", Const, 11},
+ {"EM_INTEL208", Const, 11},
+ {"EM_INTEL209", Const, 11},
+ {"EM_IP2K", Const, 11},
+ {"EM_JAVELIN", Const, 11},
+ {"EM_K10M", Const, 11},
+ {"EM_KM32", Const, 11},
+ {"EM_KMX16", Const, 11},
+ {"EM_KMX32", Const, 11},
+ {"EM_KMX8", Const, 11},
+ {"EM_KVARC", Const, 11},
+ {"EM_L10M", Const, 11},
+ {"EM_LANAI", Const, 11},
+ {"EM_LATTICEMICO32", Const, 11},
+ {"EM_LOONGARCH", Const, 19},
+ {"EM_M16C", Const, 11},
+ {"EM_M32", Const, 0},
+ {"EM_M32C", Const, 11},
+ {"EM_M32R", Const, 11},
+ {"EM_MANIK", Const, 11},
+ {"EM_MAX", Const, 11},
+ {"EM_MAXQ30", Const, 11},
+ {"EM_MCHP_PIC", Const, 11},
+ {"EM_MCST_ELBRUS", Const, 11},
+ {"EM_ME16", Const, 0},
+ {"EM_METAG", Const, 11},
+ {"EM_MICROBLAZE", Const, 11},
+ {"EM_MIPS", Const, 0},
+ {"EM_MIPS_RS3_LE", Const, 0},
+ {"EM_MIPS_RS4_BE", Const, 0},
+ {"EM_MIPS_X", Const, 0},
+ {"EM_MMA", Const, 0},
+ {"EM_MMDSP_PLUS", Const, 11},
+ {"EM_MMIX", Const, 11},
+ {"EM_MN10200", Const, 11},
+ {"EM_MN10300", Const, 11},
+ {"EM_MOXIE", Const, 11},
+ {"EM_MSP430", Const, 11},
+ {"EM_NCPU", Const, 0},
+ {"EM_NDR1", Const, 0},
+ {"EM_NDS32", Const, 11},
+ {"EM_NONE", Const, 0},
+ {"EM_NORC", Const, 11},
+ {"EM_NS32K", Const, 11},
+ {"EM_OPEN8", Const, 11},
+ {"EM_OPENRISC", Const, 11},
+ {"EM_PARISC", Const, 0},
+ {"EM_PCP", Const, 0},
+ {"EM_PDP10", Const, 11},
+ {"EM_PDP11", Const, 11},
+ {"EM_PDSP", Const, 11},
+ {"EM_PJ", Const, 11},
+ {"EM_PPC", Const, 0},
+ {"EM_PPC64", Const, 0},
+ {"EM_PRISM", Const, 11},
+ {"EM_QDSP6", Const, 11},
+ {"EM_R32C", Const, 11},
+ {"EM_RCE", Const, 0},
+ {"EM_RH32", Const, 0},
+ {"EM_RISCV", Const, 11},
+ {"EM_RL78", Const, 11},
+ {"EM_RS08", Const, 11},
+ {"EM_RX", Const, 11},
+ {"EM_S370", Const, 0},
+ {"EM_S390", Const, 0},
+ {"EM_SCORE7", Const, 11},
+ {"EM_SEP", Const, 11},
+ {"EM_SE_C17", Const, 11},
+ {"EM_SE_C33", Const, 11},
+ {"EM_SH", Const, 0},
+ {"EM_SHARC", Const, 11},
+ {"EM_SLE9X", Const, 11},
+ {"EM_SNP1K", Const, 11},
+ {"EM_SPARC", Const, 0},
+ {"EM_SPARC32PLUS", Const, 0},
+ {"EM_SPARCV9", Const, 0},
+ {"EM_ST100", Const, 0},
+ {"EM_ST19", Const, 11},
+ {"EM_ST200", Const, 11},
+ {"EM_ST7", Const, 11},
+ {"EM_ST9PLUS", Const, 11},
+ {"EM_STARCORE", Const, 0},
+ {"EM_STM8", Const, 11},
+ {"EM_STXP7X", Const, 11},
+ {"EM_SVX", Const, 11},
+ {"EM_TILE64", Const, 11},
+ {"EM_TILEGX", Const, 11},
+ {"EM_TILEPRO", Const, 11},
+ {"EM_TINYJ", Const, 0},
+ {"EM_TI_ARP32", Const, 11},
+ {"EM_TI_C2000", Const, 11},
+ {"EM_TI_C5500", Const, 11},
+ {"EM_TI_C6000", Const, 11},
+ {"EM_TI_PRU", Const, 11},
+ {"EM_TMM_GPP", Const, 11},
+ {"EM_TPC", Const, 11},
+ {"EM_TRICORE", Const, 0},
+ {"EM_TRIMEDIA", Const, 11},
+ {"EM_TSK3000", Const, 11},
+ {"EM_UNICORE", Const, 11},
+ {"EM_V800", Const, 0},
+ {"EM_V850", Const, 11},
+ {"EM_VAX", Const, 11},
+ {"EM_VIDEOCORE", Const, 11},
+ {"EM_VIDEOCORE3", Const, 11},
+ {"EM_VIDEOCORE5", Const, 11},
+ {"EM_VISIUM", Const, 11},
+ {"EM_VPP500", Const, 0},
+ {"EM_X86_64", Const, 0},
+ {"EM_XCORE", Const, 11},
+ {"EM_XGATE", Const, 11},
+ {"EM_XIMO16", Const, 11},
+ {"EM_XTENSA", Const, 11},
+ {"EM_Z80", Const, 11},
+ {"EM_ZSP", Const, 11},
+ {"ET_CORE", Const, 0},
+ {"ET_DYN", Const, 0},
+ {"ET_EXEC", Const, 0},
+ {"ET_HIOS", Const, 0},
+ {"ET_HIPROC", Const, 0},
+ {"ET_LOOS", Const, 0},
+ {"ET_LOPROC", Const, 0},
+ {"ET_NONE", Const, 0},
+ {"ET_REL", Const, 0},
+ {"EV_CURRENT", Const, 0},
+ {"EV_NONE", Const, 0},
+ {"ErrNoSymbols", Var, 4},
+ {"File", Type, 0},
+ {"File.FileHeader", Field, 0},
+ {"File.Progs", Field, 0},
+ {"File.Sections", Field, 0},
+ {"FileHeader", Type, 0},
+ {"FileHeader.ABIVersion", Field, 0},
+ {"FileHeader.ByteOrder", Field, 0},
+ {"FileHeader.Class", Field, 0},
+ {"FileHeader.Data", Field, 0},
+ {"FileHeader.Entry", Field, 1},
+ {"FileHeader.Machine", Field, 0},
+ {"FileHeader.OSABI", Field, 0},
+ {"FileHeader.Type", Field, 0},
+ {"FileHeader.Version", Field, 0},
+ {"FormatError", Type, 0},
+ {"Header32", Type, 0},
+ {"Header32.Ehsize", Field, 0},
+ {"Header32.Entry", Field, 0},
+ {"Header32.Flags", Field, 0},
+ {"Header32.Ident", Field, 0},
+ {"Header32.Machine", Field, 0},
+ {"Header32.Phentsize", Field, 0},
+ {"Header32.Phnum", Field, 0},
+ {"Header32.Phoff", Field, 0},
+ {"Header32.Shentsize", Field, 0},
+ {"Header32.Shnum", Field, 0},
+ {"Header32.Shoff", Field, 0},
+ {"Header32.Shstrndx", Field, 0},
+ {"Header32.Type", Field, 0},
+ {"Header32.Version", Field, 0},
+ {"Header64", Type, 0},
+ {"Header64.Ehsize", Field, 0},
+ {"Header64.Entry", Field, 0},
+ {"Header64.Flags", Field, 0},
+ {"Header64.Ident", Field, 0},
+ {"Header64.Machine", Field, 0},
+ {"Header64.Phentsize", Field, 0},
+ {"Header64.Phnum", Field, 0},
+ {"Header64.Phoff", Field, 0},
+ {"Header64.Shentsize", Field, 0},
+ {"Header64.Shnum", Field, 0},
+ {"Header64.Shoff", Field, 0},
+ {"Header64.Shstrndx", Field, 0},
+ {"Header64.Type", Field, 0},
+ {"Header64.Version", Field, 0},
+ {"ImportedSymbol", Type, 0},
+ {"ImportedSymbol.Library", Field, 0},
+ {"ImportedSymbol.Name", Field, 0},
+ {"ImportedSymbol.Version", Field, 0},
+ {"Machine", Type, 0},
+ {"NT_FPREGSET", Const, 0},
+ {"NT_PRPSINFO", Const, 0},
+ {"NT_PRSTATUS", Const, 0},
+ {"NType", Type, 0},
+ {"NewFile", Func, 0},
+ {"OSABI", Type, 0},
+ {"Open", Func, 0},
+ {"PF_MASKOS", Const, 0},
+ {"PF_MASKPROC", Const, 0},
+ {"PF_R", Const, 0},
+ {"PF_W", Const, 0},
+ {"PF_X", Const, 0},
+ {"PT_AARCH64_ARCHEXT", Const, 16},
+ {"PT_AARCH64_UNWIND", Const, 16},
+ {"PT_ARM_ARCHEXT", Const, 16},
+ {"PT_ARM_EXIDX", Const, 16},
+ {"PT_DYNAMIC", Const, 0},
+ {"PT_GNU_EH_FRAME", Const, 16},
+ {"PT_GNU_MBIND_HI", Const, 16},
+ {"PT_GNU_MBIND_LO", Const, 16},
+ {"PT_GNU_PROPERTY", Const, 16},
+ {"PT_GNU_RELRO", Const, 16},
+ {"PT_GNU_STACK", Const, 16},
+ {"PT_HIOS", Const, 0},
+ {"PT_HIPROC", Const, 0},
+ {"PT_INTERP", Const, 0},
+ {"PT_LOAD", Const, 0},
+ {"PT_LOOS", Const, 0},
+ {"PT_LOPROC", Const, 0},
+ {"PT_MIPS_ABIFLAGS", Const, 16},
+ {"PT_MIPS_OPTIONS", Const, 16},
+ {"PT_MIPS_REGINFO", Const, 16},
+ {"PT_MIPS_RTPROC", Const, 16},
+ {"PT_NOTE", Const, 0},
+ {"PT_NULL", Const, 0},
+ {"PT_OPENBSD_BOOTDATA", Const, 16},
+ {"PT_OPENBSD_NOBTCFI", Const, 23},
+ {"PT_OPENBSD_RANDOMIZE", Const, 16},
+ {"PT_OPENBSD_WXNEEDED", Const, 16},
+ {"PT_PAX_FLAGS", Const, 16},
+ {"PT_PHDR", Const, 0},
+ {"PT_S390_PGSTE", Const, 16},
+ {"PT_SHLIB", Const, 0},
+ {"PT_SUNWSTACK", Const, 16},
+ {"PT_SUNW_EH_FRAME", Const, 16},
+ {"PT_TLS", Const, 0},
+ {"Prog", Type, 0},
+ {"Prog.ProgHeader", Field, 0},
+ {"Prog.ReaderAt", Field, 0},
+ {"Prog32", Type, 0},
+ {"Prog32.Align", Field, 0},
+ {"Prog32.Filesz", Field, 0},
+ {"Prog32.Flags", Field, 0},
+ {"Prog32.Memsz", Field, 0},
+ {"Prog32.Off", Field, 0},
+ {"Prog32.Paddr", Field, 0},
+ {"Prog32.Type", Field, 0},
+ {"Prog32.Vaddr", Field, 0},
+ {"Prog64", Type, 0},
+ {"Prog64.Align", Field, 0},
+ {"Prog64.Filesz", Field, 0},
+ {"Prog64.Flags", Field, 0},
+ {"Prog64.Memsz", Field, 0},
+ {"Prog64.Off", Field, 0},
+ {"Prog64.Paddr", Field, 0},
+ {"Prog64.Type", Field, 0},
+ {"Prog64.Vaddr", Field, 0},
+ {"ProgFlag", Type, 0},
+ {"ProgHeader", Type, 0},
+ {"ProgHeader.Align", Field, 0},
+ {"ProgHeader.Filesz", Field, 0},
+ {"ProgHeader.Flags", Field, 0},
+ {"ProgHeader.Memsz", Field, 0},
+ {"ProgHeader.Off", Field, 0},
+ {"ProgHeader.Paddr", Field, 0},
+ {"ProgHeader.Type", Field, 0},
+ {"ProgHeader.Vaddr", Field, 0},
+ {"ProgType", Type, 0},
+ {"R_386", Type, 0},
+ {"R_386_16", Const, 10},
+ {"R_386_32", Const, 0},
+ {"R_386_32PLT", Const, 10},
+ {"R_386_8", Const, 10},
+ {"R_386_COPY", Const, 0},
+ {"R_386_GLOB_DAT", Const, 0},
+ {"R_386_GOT32", Const, 0},
+ {"R_386_GOT32X", Const, 10},
+ {"R_386_GOTOFF", Const, 0},
+ {"R_386_GOTPC", Const, 0},
+ {"R_386_IRELATIVE", Const, 10},
+ {"R_386_JMP_SLOT", Const, 0},
+ {"R_386_NONE", Const, 0},
+ {"R_386_PC16", Const, 10},
+ {"R_386_PC32", Const, 0},
+ {"R_386_PC8", Const, 10},
+ {"R_386_PLT32", Const, 0},
+ {"R_386_RELATIVE", Const, 0},
+ {"R_386_SIZE32", Const, 10},
+ {"R_386_TLS_DESC", Const, 10},
+ {"R_386_TLS_DESC_CALL", Const, 10},
+ {"R_386_TLS_DTPMOD32", Const, 0},
+ {"R_386_TLS_DTPOFF32", Const, 0},
+ {"R_386_TLS_GD", Const, 0},
+ {"R_386_TLS_GD_32", Const, 0},
+ {"R_386_TLS_GD_CALL", Const, 0},
+ {"R_386_TLS_GD_POP", Const, 0},
+ {"R_386_TLS_GD_PUSH", Const, 0},
+ {"R_386_TLS_GOTDESC", Const, 10},
+ {"R_386_TLS_GOTIE", Const, 0},
+ {"R_386_TLS_IE", Const, 0},
+ {"R_386_TLS_IE_32", Const, 0},
+ {"R_386_TLS_LDM", Const, 0},
+ {"R_386_TLS_LDM_32", Const, 0},
+ {"R_386_TLS_LDM_CALL", Const, 0},
+ {"R_386_TLS_LDM_POP", Const, 0},
+ {"R_386_TLS_LDM_PUSH", Const, 0},
+ {"R_386_TLS_LDO_32", Const, 0},
+ {"R_386_TLS_LE", Const, 0},
+ {"R_386_TLS_LE_32", Const, 0},
+ {"R_386_TLS_TPOFF", Const, 0},
+ {"R_386_TLS_TPOFF32", Const, 0},
+ {"R_390", Type, 7},
+ {"R_390_12", Const, 7},
+ {"R_390_16", Const, 7},
+ {"R_390_20", Const, 7},
+ {"R_390_32", Const, 7},
+ {"R_390_64", Const, 7},
+ {"R_390_8", Const, 7},
+ {"R_390_COPY", Const, 7},
+ {"R_390_GLOB_DAT", Const, 7},
+ {"R_390_GOT12", Const, 7},
+ {"R_390_GOT16", Const, 7},
+ {"R_390_GOT20", Const, 7},
+ {"R_390_GOT32", Const, 7},
+ {"R_390_GOT64", Const, 7},
+ {"R_390_GOTENT", Const, 7},
+ {"R_390_GOTOFF", Const, 7},
+ {"R_390_GOTOFF16", Const, 7},
+ {"R_390_GOTOFF64", Const, 7},
+ {"R_390_GOTPC", Const, 7},
+ {"R_390_GOTPCDBL", Const, 7},
+ {"R_390_GOTPLT12", Const, 7},
+ {"R_390_GOTPLT16", Const, 7},
+ {"R_390_GOTPLT20", Const, 7},
+ {"R_390_GOTPLT32", Const, 7},
+ {"R_390_GOTPLT64", Const, 7},
+ {"R_390_GOTPLTENT", Const, 7},
+ {"R_390_GOTPLTOFF16", Const, 7},
+ {"R_390_GOTPLTOFF32", Const, 7},
+ {"R_390_GOTPLTOFF64", Const, 7},
+ {"R_390_JMP_SLOT", Const, 7},
+ {"R_390_NONE", Const, 7},
+ {"R_390_PC16", Const, 7},
+ {"R_390_PC16DBL", Const, 7},
+ {"R_390_PC32", Const, 7},
+ {"R_390_PC32DBL", Const, 7},
+ {"R_390_PC64", Const, 7},
+ {"R_390_PLT16DBL", Const, 7},
+ {"R_390_PLT32", Const, 7},
+ {"R_390_PLT32DBL", Const, 7},
+ {"R_390_PLT64", Const, 7},
+ {"R_390_RELATIVE", Const, 7},
+ {"R_390_TLS_DTPMOD", Const, 7},
+ {"R_390_TLS_DTPOFF", Const, 7},
+ {"R_390_TLS_GD32", Const, 7},
+ {"R_390_TLS_GD64", Const, 7},
+ {"R_390_TLS_GDCALL", Const, 7},
+ {"R_390_TLS_GOTIE12", Const, 7},
+ {"R_390_TLS_GOTIE20", Const, 7},
+ {"R_390_TLS_GOTIE32", Const, 7},
+ {"R_390_TLS_GOTIE64", Const, 7},
+ {"R_390_TLS_IE32", Const, 7},
+ {"R_390_TLS_IE64", Const, 7},
+ {"R_390_TLS_IEENT", Const, 7},
+ {"R_390_TLS_LDCALL", Const, 7},
+ {"R_390_TLS_LDM32", Const, 7},
+ {"R_390_TLS_LDM64", Const, 7},
+ {"R_390_TLS_LDO32", Const, 7},
+ {"R_390_TLS_LDO64", Const, 7},
+ {"R_390_TLS_LE32", Const, 7},
+ {"R_390_TLS_LE64", Const, 7},
+ {"R_390_TLS_LOAD", Const, 7},
+ {"R_390_TLS_TPOFF", Const, 7},
+ {"R_AARCH64", Type, 4},
+ {"R_AARCH64_ABS16", Const, 4},
+ {"R_AARCH64_ABS32", Const, 4},
+ {"R_AARCH64_ABS64", Const, 4},
+ {"R_AARCH64_ADD_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_ADR_GOT_PAGE", Const, 4},
+ {"R_AARCH64_ADR_PREL_LO21", Const, 4},
+ {"R_AARCH64_ADR_PREL_PG_HI21", Const, 4},
+ {"R_AARCH64_ADR_PREL_PG_HI21_NC", Const, 4},
+ {"R_AARCH64_CALL26", Const, 4},
+ {"R_AARCH64_CONDBR19", Const, 4},
+ {"R_AARCH64_COPY", Const, 4},
+ {"R_AARCH64_GLOB_DAT", Const, 4},
+ {"R_AARCH64_GOT_LD_PREL19", Const, 4},
+ {"R_AARCH64_IRELATIVE", Const, 4},
+ {"R_AARCH64_JUMP26", Const, 4},
+ {"R_AARCH64_JUMP_SLOT", Const, 4},
+ {"R_AARCH64_LD64_GOTOFF_LO15", Const, 10},
+ {"R_AARCH64_LD64_GOTPAGE_LO15", Const, 10},
+ {"R_AARCH64_LD64_GOT_LO12_NC", Const, 4},
+ {"R_AARCH64_LDST128_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_LDST16_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_LDST32_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_LDST64_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_LDST8_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_LD_PREL_LO19", Const, 4},
+ {"R_AARCH64_MOVW_SABS_G0", Const, 4},
+ {"R_AARCH64_MOVW_SABS_G1", Const, 4},
+ {"R_AARCH64_MOVW_SABS_G2", Const, 4},
+ {"R_AARCH64_MOVW_UABS_G0", Const, 4},
+ {"R_AARCH64_MOVW_UABS_G0_NC", Const, 4},
+ {"R_AARCH64_MOVW_UABS_G1", Const, 4},
+ {"R_AARCH64_MOVW_UABS_G1_NC", Const, 4},
+ {"R_AARCH64_MOVW_UABS_G2", Const, 4},
+ {"R_AARCH64_MOVW_UABS_G2_NC", Const, 4},
+ {"R_AARCH64_MOVW_UABS_G3", Const, 4},
+ {"R_AARCH64_NONE", Const, 4},
+ {"R_AARCH64_NULL", Const, 4},
+ {"R_AARCH64_P32_ABS16", Const, 4},
+ {"R_AARCH64_P32_ABS32", Const, 4},
+ {"R_AARCH64_P32_ADD_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_ADR_GOT_PAGE", Const, 4},
+ {"R_AARCH64_P32_ADR_PREL_LO21", Const, 4},
+ {"R_AARCH64_P32_ADR_PREL_PG_HI21", Const, 4},
+ {"R_AARCH64_P32_CALL26", Const, 4},
+ {"R_AARCH64_P32_CONDBR19", Const, 4},
+ {"R_AARCH64_P32_COPY", Const, 4},
+ {"R_AARCH64_P32_GLOB_DAT", Const, 4},
+ {"R_AARCH64_P32_GOT_LD_PREL19", Const, 4},
+ {"R_AARCH64_P32_IRELATIVE", Const, 4},
+ {"R_AARCH64_P32_JUMP26", Const, 4},
+ {"R_AARCH64_P32_JUMP_SLOT", Const, 4},
+ {"R_AARCH64_P32_LD32_GOT_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_LDST128_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_LDST16_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_LDST32_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_LDST64_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_LDST8_ABS_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_LD_PREL_LO19", Const, 4},
+ {"R_AARCH64_P32_MOVW_SABS_G0", Const, 4},
+ {"R_AARCH64_P32_MOVW_UABS_G0", Const, 4},
+ {"R_AARCH64_P32_MOVW_UABS_G0_NC", Const, 4},
+ {"R_AARCH64_P32_MOVW_UABS_G1", Const, 4},
+ {"R_AARCH64_P32_PREL16", Const, 4},
+ {"R_AARCH64_P32_PREL32", Const, 4},
+ {"R_AARCH64_P32_RELATIVE", Const, 4},
+ {"R_AARCH64_P32_TLSDESC", Const, 4},
+ {"R_AARCH64_P32_TLSDESC_ADD_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_TLSDESC_ADR_PAGE21", Const, 4},
+ {"R_AARCH64_P32_TLSDESC_ADR_PREL21", Const, 4},
+ {"R_AARCH64_P32_TLSDESC_CALL", Const, 4},
+ {"R_AARCH64_P32_TLSDESC_LD32_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_TLSDESC_LD_PREL19", Const, 4},
+ {"R_AARCH64_P32_TLSGD_ADD_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_TLSGD_ADR_PAGE21", Const, 4},
+ {"R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4},
+ {"R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19", Const, 4},
+ {"R_AARCH64_P32_TLSLE_ADD_TPREL_HI12", Const, 4},
+ {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12", Const, 4},
+ {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC", Const, 4},
+ {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0", Const, 4},
+ {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC", Const, 4},
+ {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G1", Const, 4},
+ {"R_AARCH64_P32_TLS_DTPMOD", Const, 4},
+ {"R_AARCH64_P32_TLS_DTPREL", Const, 4},
+ {"R_AARCH64_P32_TLS_TPREL", Const, 4},
+ {"R_AARCH64_P32_TSTBR14", Const, 4},
+ {"R_AARCH64_PREL16", Const, 4},
+ {"R_AARCH64_PREL32", Const, 4},
+ {"R_AARCH64_PREL64", Const, 4},
+ {"R_AARCH64_RELATIVE", Const, 4},
+ {"R_AARCH64_TLSDESC", Const, 4},
+ {"R_AARCH64_TLSDESC_ADD", Const, 4},
+ {"R_AARCH64_TLSDESC_ADD_LO12_NC", Const, 4},
+ {"R_AARCH64_TLSDESC_ADR_PAGE21", Const, 4},
+ {"R_AARCH64_TLSDESC_ADR_PREL21", Const, 4},
+ {"R_AARCH64_TLSDESC_CALL", Const, 4},
+ {"R_AARCH64_TLSDESC_LD64_LO12_NC", Const, 4},
+ {"R_AARCH64_TLSDESC_LDR", Const, 4},
+ {"R_AARCH64_TLSDESC_LD_PREL19", Const, 4},
+ {"R_AARCH64_TLSDESC_OFF_G0_NC", Const, 4},
+ {"R_AARCH64_TLSDESC_OFF_G1", Const, 4},
+ {"R_AARCH64_TLSGD_ADD_LO12_NC", Const, 4},
+ {"R_AARCH64_TLSGD_ADR_PAGE21", Const, 4},
+ {"R_AARCH64_TLSGD_ADR_PREL21", Const, 10},
+ {"R_AARCH64_TLSGD_MOVW_G0_NC", Const, 10},
+ {"R_AARCH64_TLSGD_MOVW_G1", Const, 10},
+ {"R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4},
+ {"R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC", Const, 4},
+ {"R_AARCH64_TLSIE_LD_GOTTPREL_PREL19", Const, 4},
+ {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC", Const, 4},
+ {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G1", Const, 4},
+ {"R_AARCH64_TLSLD_ADR_PAGE21", Const, 10},
+ {"R_AARCH64_TLSLD_ADR_PREL21", Const, 10},
+ {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12", Const, 10},
+ {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC", Const, 10},
+ {"R_AARCH64_TLSLE_ADD_TPREL_HI12", Const, 4},
+ {"R_AARCH64_TLSLE_ADD_TPREL_LO12", Const, 4},
+ {"R_AARCH64_TLSLE_ADD_TPREL_LO12_NC", Const, 4},
+ {"R_AARCH64_TLSLE_LDST128_TPREL_LO12", Const, 10},
+ {"R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC", Const, 10},
+ {"R_AARCH64_TLSLE_MOVW_TPREL_G0", Const, 4},
+ {"R_AARCH64_TLSLE_MOVW_TPREL_G0_NC", Const, 4},
+ {"R_AARCH64_TLSLE_MOVW_TPREL_G1", Const, 4},
+ {"R_AARCH64_TLSLE_MOVW_TPREL_G1_NC", Const, 4},
+ {"R_AARCH64_TLSLE_MOVW_TPREL_G2", Const, 4},
+ {"R_AARCH64_TLS_DTPMOD64", Const, 4},
+ {"R_AARCH64_TLS_DTPREL64", Const, 4},
+ {"R_AARCH64_TLS_TPREL64", Const, 4},
+ {"R_AARCH64_TSTBR14", Const, 4},
+ {"R_ALPHA", Type, 0},
+ {"R_ALPHA_BRADDR", Const, 0},
+ {"R_ALPHA_COPY", Const, 0},
+ {"R_ALPHA_GLOB_DAT", Const, 0},
+ {"R_ALPHA_GPDISP", Const, 0},
+ {"R_ALPHA_GPREL32", Const, 0},
+ {"R_ALPHA_GPRELHIGH", Const, 0},
+ {"R_ALPHA_GPRELLOW", Const, 0},
+ {"R_ALPHA_GPVALUE", Const, 0},
+ {"R_ALPHA_HINT", Const, 0},
+ {"R_ALPHA_IMMED_BR_HI32", Const, 0},
+ {"R_ALPHA_IMMED_GP_16", Const, 0},
+ {"R_ALPHA_IMMED_GP_HI32", Const, 0},
+ {"R_ALPHA_IMMED_LO32", Const, 0},
+ {"R_ALPHA_IMMED_SCN_HI32", Const, 0},
+ {"R_ALPHA_JMP_SLOT", Const, 0},
+ {"R_ALPHA_LITERAL", Const, 0},
+ {"R_ALPHA_LITUSE", Const, 0},
+ {"R_ALPHA_NONE", Const, 0},
+ {"R_ALPHA_OP_PRSHIFT", Const, 0},
+ {"R_ALPHA_OP_PSUB", Const, 0},
+ {"R_ALPHA_OP_PUSH", Const, 0},
+ {"R_ALPHA_OP_STORE", Const, 0},
+ {"R_ALPHA_REFLONG", Const, 0},
+ {"R_ALPHA_REFQUAD", Const, 0},
+ {"R_ALPHA_RELATIVE", Const, 0},
+ {"R_ALPHA_SREL16", Const, 0},
+ {"R_ALPHA_SREL32", Const, 0},
+ {"R_ALPHA_SREL64", Const, 0},
+ {"R_ARM", Type, 0},
+ {"R_ARM_ABS12", Const, 0},
+ {"R_ARM_ABS16", Const, 0},
+ {"R_ARM_ABS32", Const, 0},
+ {"R_ARM_ABS32_NOI", Const, 10},
+ {"R_ARM_ABS8", Const, 0},
+ {"R_ARM_ALU_PCREL_15_8", Const, 10},
+ {"R_ARM_ALU_PCREL_23_15", Const, 10},
+ {"R_ARM_ALU_PCREL_7_0", Const, 10},
+ {"R_ARM_ALU_PC_G0", Const, 10},
+ {"R_ARM_ALU_PC_G0_NC", Const, 10},
+ {"R_ARM_ALU_PC_G1", Const, 10},
+ {"R_ARM_ALU_PC_G1_NC", Const, 10},
+ {"R_ARM_ALU_PC_G2", Const, 10},
+ {"R_ARM_ALU_SBREL_19_12_NC", Const, 10},
+ {"R_ARM_ALU_SBREL_27_20_CK", Const, 10},
+ {"R_ARM_ALU_SB_G0", Const, 10},
+ {"R_ARM_ALU_SB_G0_NC", Const, 10},
+ {"R_ARM_ALU_SB_G1", Const, 10},
+ {"R_ARM_ALU_SB_G1_NC", Const, 10},
+ {"R_ARM_ALU_SB_G2", Const, 10},
+ {"R_ARM_AMP_VCALL9", Const, 0},
+ {"R_ARM_BASE_ABS", Const, 10},
+ {"R_ARM_CALL", Const, 10},
+ {"R_ARM_COPY", Const, 0},
+ {"R_ARM_GLOB_DAT", Const, 0},
+ {"R_ARM_GNU_VTENTRY", Const, 0},
+ {"R_ARM_GNU_VTINHERIT", Const, 0},
+ {"R_ARM_GOT32", Const, 0},
+ {"R_ARM_GOTOFF", Const, 0},
+ {"R_ARM_GOTOFF12", Const, 10},
+ {"R_ARM_GOTPC", Const, 0},
+ {"R_ARM_GOTRELAX", Const, 10},
+ {"R_ARM_GOT_ABS", Const, 10},
+ {"R_ARM_GOT_BREL12", Const, 10},
+ {"R_ARM_GOT_PREL", Const, 10},
+ {"R_ARM_IRELATIVE", Const, 10},
+ {"R_ARM_JUMP24", Const, 10},
+ {"R_ARM_JUMP_SLOT", Const, 0},
+ {"R_ARM_LDC_PC_G0", Const, 10},
+ {"R_ARM_LDC_PC_G1", Const, 10},
+ {"R_ARM_LDC_PC_G2", Const, 10},
+ {"R_ARM_LDC_SB_G0", Const, 10},
+ {"R_ARM_LDC_SB_G1", Const, 10},
+ {"R_ARM_LDC_SB_G2", Const, 10},
+ {"R_ARM_LDRS_PC_G0", Const, 10},
+ {"R_ARM_LDRS_PC_G1", Const, 10},
+ {"R_ARM_LDRS_PC_G2", Const, 10},
+ {"R_ARM_LDRS_SB_G0", Const, 10},
+ {"R_ARM_LDRS_SB_G1", Const, 10},
+ {"R_ARM_LDRS_SB_G2", Const, 10},
+ {"R_ARM_LDR_PC_G1", Const, 10},
+ {"R_ARM_LDR_PC_G2", Const, 10},
+ {"R_ARM_LDR_SBREL_11_10_NC", Const, 10},
+ {"R_ARM_LDR_SB_G0", Const, 10},
+ {"R_ARM_LDR_SB_G1", Const, 10},
+ {"R_ARM_LDR_SB_G2", Const, 10},
+ {"R_ARM_ME_TOO", Const, 10},
+ {"R_ARM_MOVT_ABS", Const, 10},
+ {"R_ARM_MOVT_BREL", Const, 10},
+ {"R_ARM_MOVT_PREL", Const, 10},
+ {"R_ARM_MOVW_ABS_NC", Const, 10},
+ {"R_ARM_MOVW_BREL", Const, 10},
+ {"R_ARM_MOVW_BREL_NC", Const, 10},
+ {"R_ARM_MOVW_PREL_NC", Const, 10},
+ {"R_ARM_NONE", Const, 0},
+ {"R_ARM_PC13", Const, 0},
+ {"R_ARM_PC24", Const, 0},
+ {"R_ARM_PLT32", Const, 0},
+ {"R_ARM_PLT32_ABS", Const, 10},
+ {"R_ARM_PREL31", Const, 10},
+ {"R_ARM_PRIVATE_0", Const, 10},
+ {"R_ARM_PRIVATE_1", Const, 10},
+ {"R_ARM_PRIVATE_10", Const, 10},
+ {"R_ARM_PRIVATE_11", Const, 10},
+ {"R_ARM_PRIVATE_12", Const, 10},
+ {"R_ARM_PRIVATE_13", Const, 10},
+ {"R_ARM_PRIVATE_14", Const, 10},
+ {"R_ARM_PRIVATE_15", Const, 10},
+ {"R_ARM_PRIVATE_2", Const, 10},
+ {"R_ARM_PRIVATE_3", Const, 10},
+ {"R_ARM_PRIVATE_4", Const, 10},
+ {"R_ARM_PRIVATE_5", Const, 10},
+ {"R_ARM_PRIVATE_6", Const, 10},
+ {"R_ARM_PRIVATE_7", Const, 10},
+ {"R_ARM_PRIVATE_8", Const, 10},
+ {"R_ARM_PRIVATE_9", Const, 10},
+ {"R_ARM_RABS32", Const, 0},
+ {"R_ARM_RBASE", Const, 0},
+ {"R_ARM_REL32", Const, 0},
+ {"R_ARM_REL32_NOI", Const, 10},
+ {"R_ARM_RELATIVE", Const, 0},
+ {"R_ARM_RPC24", Const, 0},
+ {"R_ARM_RREL32", Const, 0},
+ {"R_ARM_RSBREL32", Const, 0},
+ {"R_ARM_RXPC25", Const, 10},
+ {"R_ARM_SBREL31", Const, 10},
+ {"R_ARM_SBREL32", Const, 0},
+ {"R_ARM_SWI24", Const, 0},
+ {"R_ARM_TARGET1", Const, 10},
+ {"R_ARM_TARGET2", Const, 10},
+ {"R_ARM_THM_ABS5", Const, 0},
+ {"R_ARM_THM_ALU_ABS_G0_NC", Const, 10},
+ {"R_ARM_THM_ALU_ABS_G1_NC", Const, 10},
+ {"R_ARM_THM_ALU_ABS_G2_NC", Const, 10},
+ {"R_ARM_THM_ALU_ABS_G3", Const, 10},
+ {"R_ARM_THM_ALU_PREL_11_0", Const, 10},
+ {"R_ARM_THM_GOT_BREL12", Const, 10},
+ {"R_ARM_THM_JUMP11", Const, 10},
+ {"R_ARM_THM_JUMP19", Const, 10},
+ {"R_ARM_THM_JUMP24", Const, 10},
+ {"R_ARM_THM_JUMP6", Const, 10},
+ {"R_ARM_THM_JUMP8", Const, 10},
+ {"R_ARM_THM_MOVT_ABS", Const, 10},
+ {"R_ARM_THM_MOVT_BREL", Const, 10},
+ {"R_ARM_THM_MOVT_PREL", Const, 10},
+ {"R_ARM_THM_MOVW_ABS_NC", Const, 10},
+ {"R_ARM_THM_MOVW_BREL", Const, 10},
+ {"R_ARM_THM_MOVW_BREL_NC", Const, 10},
+ {"R_ARM_THM_MOVW_PREL_NC", Const, 10},
+ {"R_ARM_THM_PC12", Const, 10},
+ {"R_ARM_THM_PC22", Const, 0},
+ {"R_ARM_THM_PC8", Const, 0},
+ {"R_ARM_THM_RPC22", Const, 0},
+ {"R_ARM_THM_SWI8", Const, 0},
+ {"R_ARM_THM_TLS_CALL", Const, 10},
+ {"R_ARM_THM_TLS_DESCSEQ16", Const, 10},
+ {"R_ARM_THM_TLS_DESCSEQ32", Const, 10},
+ {"R_ARM_THM_XPC22", Const, 0},
+ {"R_ARM_TLS_CALL", Const, 10},
+ {"R_ARM_TLS_DESCSEQ", Const, 10},
+ {"R_ARM_TLS_DTPMOD32", Const, 10},
+ {"R_ARM_TLS_DTPOFF32", Const, 10},
+ {"R_ARM_TLS_GD32", Const, 10},
+ {"R_ARM_TLS_GOTDESC", Const, 10},
+ {"R_ARM_TLS_IE12GP", Const, 10},
+ {"R_ARM_TLS_IE32", Const, 10},
+ {"R_ARM_TLS_LDM32", Const, 10},
+ {"R_ARM_TLS_LDO12", Const, 10},
+ {"R_ARM_TLS_LDO32", Const, 10},
+ {"R_ARM_TLS_LE12", Const, 10},
+ {"R_ARM_TLS_LE32", Const, 10},
+ {"R_ARM_TLS_TPOFF32", Const, 10},
+ {"R_ARM_V4BX", Const, 10},
+ {"R_ARM_XPC25", Const, 0},
+ {"R_INFO", Func, 0},
+ {"R_INFO32", Func, 0},
+ {"R_LARCH", Type, 19},
+ {"R_LARCH_32", Const, 19},
+ {"R_LARCH_32_PCREL", Const, 20},
+ {"R_LARCH_64", Const, 19},
+ {"R_LARCH_64_PCREL", Const, 22},
+ {"R_LARCH_ABS64_HI12", Const, 20},
+ {"R_LARCH_ABS64_LO20", Const, 20},
+ {"R_LARCH_ABS_HI20", Const, 20},
+ {"R_LARCH_ABS_LO12", Const, 20},
+ {"R_LARCH_ADD16", Const, 19},
+ {"R_LARCH_ADD24", Const, 19},
+ {"R_LARCH_ADD32", Const, 19},
+ {"R_LARCH_ADD6", Const, 22},
+ {"R_LARCH_ADD64", Const, 19},
+ {"R_LARCH_ADD8", Const, 19},
+ {"R_LARCH_ADD_ULEB128", Const, 22},
+ {"R_LARCH_ALIGN", Const, 22},
+ {"R_LARCH_B16", Const, 20},
+ {"R_LARCH_B21", Const, 20},
+ {"R_LARCH_B26", Const, 20},
+ {"R_LARCH_CFA", Const, 22},
+ {"R_LARCH_COPY", Const, 19},
+ {"R_LARCH_DELETE", Const, 22},
+ {"R_LARCH_GNU_VTENTRY", Const, 20},
+ {"R_LARCH_GNU_VTINHERIT", Const, 20},
+ {"R_LARCH_GOT64_HI12", Const, 20},
+ {"R_LARCH_GOT64_LO20", Const, 20},
+ {"R_LARCH_GOT64_PC_HI12", Const, 20},
+ {"R_LARCH_GOT64_PC_LO20", Const, 20},
+ {"R_LARCH_GOT_HI20", Const, 20},
+ {"R_LARCH_GOT_LO12", Const, 20},
+ {"R_LARCH_GOT_PC_HI20", Const, 20},
+ {"R_LARCH_GOT_PC_LO12", Const, 20},
+ {"R_LARCH_IRELATIVE", Const, 19},
+ {"R_LARCH_JUMP_SLOT", Const, 19},
+ {"R_LARCH_MARK_LA", Const, 19},
+ {"R_LARCH_MARK_PCREL", Const, 19},
+ {"R_LARCH_NONE", Const, 19},
+ {"R_LARCH_PCALA64_HI12", Const, 20},
+ {"R_LARCH_PCALA64_LO20", Const, 20},
+ {"R_LARCH_PCALA_HI20", Const, 20},
+ {"R_LARCH_PCALA_LO12", Const, 20},
+ {"R_LARCH_PCREL20_S2", Const, 22},
+ {"R_LARCH_RELATIVE", Const, 19},
+ {"R_LARCH_RELAX", Const, 20},
+ {"R_LARCH_SOP_ADD", Const, 19},
+ {"R_LARCH_SOP_AND", Const, 19},
+ {"R_LARCH_SOP_ASSERT", Const, 19},
+ {"R_LARCH_SOP_IF_ELSE", Const, 19},
+ {"R_LARCH_SOP_NOT", Const, 19},
+ {"R_LARCH_SOP_POP_32_S_0_10_10_16_S2", Const, 19},
+ {"R_LARCH_SOP_POP_32_S_0_5_10_16_S2", Const, 19},
+ {"R_LARCH_SOP_POP_32_S_10_12", Const, 19},
+ {"R_LARCH_SOP_POP_32_S_10_16", Const, 19},
+ {"R_LARCH_SOP_POP_32_S_10_16_S2", Const, 19},
+ {"R_LARCH_SOP_POP_32_S_10_5", Const, 19},
+ {"R_LARCH_SOP_POP_32_S_5_20", Const, 19},
+ {"R_LARCH_SOP_POP_32_U", Const, 19},
+ {"R_LARCH_SOP_POP_32_U_10_12", Const, 19},
+ {"R_LARCH_SOP_PUSH_ABSOLUTE", Const, 19},
+ {"R_LARCH_SOP_PUSH_DUP", Const, 19},
+ {"R_LARCH_SOP_PUSH_GPREL", Const, 19},
+ {"R_LARCH_SOP_PUSH_PCREL", Const, 19},
+ {"R_LARCH_SOP_PUSH_PLT_PCREL", Const, 19},
+ {"R_LARCH_SOP_PUSH_TLS_GD", Const, 19},
+ {"R_LARCH_SOP_PUSH_TLS_GOT", Const, 19},
+ {"R_LARCH_SOP_PUSH_TLS_TPREL", Const, 19},
+ {"R_LARCH_SOP_SL", Const, 19},
+ {"R_LARCH_SOP_SR", Const, 19},
+ {"R_LARCH_SOP_SUB", Const, 19},
+ {"R_LARCH_SUB16", Const, 19},
+ {"R_LARCH_SUB24", Const, 19},
+ {"R_LARCH_SUB32", Const, 19},
+ {"R_LARCH_SUB6", Const, 22},
+ {"R_LARCH_SUB64", Const, 19},
+ {"R_LARCH_SUB8", Const, 19},
+ {"R_LARCH_SUB_ULEB128", Const, 22},
+ {"R_LARCH_TLS_DTPMOD32", Const, 19},
+ {"R_LARCH_TLS_DTPMOD64", Const, 19},
+ {"R_LARCH_TLS_DTPREL32", Const, 19},
+ {"R_LARCH_TLS_DTPREL64", Const, 19},
+ {"R_LARCH_TLS_GD_HI20", Const, 20},
+ {"R_LARCH_TLS_GD_PC_HI20", Const, 20},
+ {"R_LARCH_TLS_IE64_HI12", Const, 20},
+ {"R_LARCH_TLS_IE64_LO20", Const, 20},
+ {"R_LARCH_TLS_IE64_PC_HI12", Const, 20},
+ {"R_LARCH_TLS_IE64_PC_LO20", Const, 20},
+ {"R_LARCH_TLS_IE_HI20", Const, 20},
+ {"R_LARCH_TLS_IE_LO12", Const, 20},
+ {"R_LARCH_TLS_IE_PC_HI20", Const, 20},
+ {"R_LARCH_TLS_IE_PC_LO12", Const, 20},
+ {"R_LARCH_TLS_LD_HI20", Const, 20},
+ {"R_LARCH_TLS_LD_PC_HI20", Const, 20},
+ {"R_LARCH_TLS_LE64_HI12", Const, 20},
+ {"R_LARCH_TLS_LE64_LO20", Const, 20},
+ {"R_LARCH_TLS_LE_HI20", Const, 20},
+ {"R_LARCH_TLS_LE_LO12", Const, 20},
+ {"R_LARCH_TLS_TPREL32", Const, 19},
+ {"R_LARCH_TLS_TPREL64", Const, 19},
+ {"R_MIPS", Type, 6},
+ {"R_MIPS_16", Const, 6},
+ {"R_MIPS_26", Const, 6},
+ {"R_MIPS_32", Const, 6},
+ {"R_MIPS_64", Const, 6},
+ {"R_MIPS_ADD_IMMEDIATE", Const, 6},
+ {"R_MIPS_CALL16", Const, 6},
+ {"R_MIPS_CALL_HI16", Const, 6},
+ {"R_MIPS_CALL_LO16", Const, 6},
+ {"R_MIPS_DELETE", Const, 6},
+ {"R_MIPS_GOT16", Const, 6},
+ {"R_MIPS_GOT_DISP", Const, 6},
+ {"R_MIPS_GOT_HI16", Const, 6},
+ {"R_MIPS_GOT_LO16", Const, 6},
+ {"R_MIPS_GOT_OFST", Const, 6},
+ {"R_MIPS_GOT_PAGE", Const, 6},
+ {"R_MIPS_GPREL16", Const, 6},
+ {"R_MIPS_GPREL32", Const, 6},
+ {"R_MIPS_HI16", Const, 6},
+ {"R_MIPS_HIGHER", Const, 6},
+ {"R_MIPS_HIGHEST", Const, 6},
+ {"R_MIPS_INSERT_A", Const, 6},
+ {"R_MIPS_INSERT_B", Const, 6},
+ {"R_MIPS_JALR", Const, 6},
+ {"R_MIPS_LITERAL", Const, 6},
+ {"R_MIPS_LO16", Const, 6},
+ {"R_MIPS_NONE", Const, 6},
+ {"R_MIPS_PC16", Const, 6},
+ {"R_MIPS_PC32", Const, 22},
+ {"R_MIPS_PJUMP", Const, 6},
+ {"R_MIPS_REL16", Const, 6},
+ {"R_MIPS_REL32", Const, 6},
+ {"R_MIPS_RELGOT", Const, 6},
+ {"R_MIPS_SCN_DISP", Const, 6},
+ {"R_MIPS_SHIFT5", Const, 6},
+ {"R_MIPS_SHIFT6", Const, 6},
+ {"R_MIPS_SUB", Const, 6},
+ {"R_MIPS_TLS_DTPMOD32", Const, 6},
+ {"R_MIPS_TLS_DTPMOD64", Const, 6},
+ {"R_MIPS_TLS_DTPREL32", Const, 6},
+ {"R_MIPS_TLS_DTPREL64", Const, 6},
+ {"R_MIPS_TLS_DTPREL_HI16", Const, 6},
+ {"R_MIPS_TLS_DTPREL_LO16", Const, 6},
+ {"R_MIPS_TLS_GD", Const, 6},
+ {"R_MIPS_TLS_GOTTPREL", Const, 6},
+ {"R_MIPS_TLS_LDM", Const, 6},
+ {"R_MIPS_TLS_TPREL32", Const, 6},
+ {"R_MIPS_TLS_TPREL64", Const, 6},
+ {"R_MIPS_TLS_TPREL_HI16", Const, 6},
+ {"R_MIPS_TLS_TPREL_LO16", Const, 6},
+ {"R_PPC", Type, 0},
+ {"R_PPC64", Type, 5},
+ {"R_PPC64_ADDR14", Const, 5},
+ {"R_PPC64_ADDR14_BRNTAKEN", Const, 5},
+ {"R_PPC64_ADDR14_BRTAKEN", Const, 5},
+ {"R_PPC64_ADDR16", Const, 5},
+ {"R_PPC64_ADDR16_DS", Const, 5},
+ {"R_PPC64_ADDR16_HA", Const, 5},
+ {"R_PPC64_ADDR16_HI", Const, 5},
+ {"R_PPC64_ADDR16_HIGH", Const, 10},
+ {"R_PPC64_ADDR16_HIGHA", Const, 10},
+ {"R_PPC64_ADDR16_HIGHER", Const, 5},
+ {"R_PPC64_ADDR16_HIGHER34", Const, 20},
+ {"R_PPC64_ADDR16_HIGHERA", Const, 5},
+ {"R_PPC64_ADDR16_HIGHERA34", Const, 20},
+ {"R_PPC64_ADDR16_HIGHEST", Const, 5},
+ {"R_PPC64_ADDR16_HIGHEST34", Const, 20},
+ {"R_PPC64_ADDR16_HIGHESTA", Const, 5},
+ {"R_PPC64_ADDR16_HIGHESTA34", Const, 20},
+ {"R_PPC64_ADDR16_LO", Const, 5},
+ {"R_PPC64_ADDR16_LO_DS", Const, 5},
+ {"R_PPC64_ADDR24", Const, 5},
+ {"R_PPC64_ADDR32", Const, 5},
+ {"R_PPC64_ADDR64", Const, 5},
+ {"R_PPC64_ADDR64_LOCAL", Const, 10},
+ {"R_PPC64_COPY", Const, 20},
+ {"R_PPC64_D28", Const, 20},
+ {"R_PPC64_D34", Const, 20},
+ {"R_PPC64_D34_HA30", Const, 20},
+ {"R_PPC64_D34_HI30", Const, 20},
+ {"R_PPC64_D34_LO", Const, 20},
+ {"R_PPC64_DTPMOD64", Const, 5},
+ {"R_PPC64_DTPREL16", Const, 5},
+ {"R_PPC64_DTPREL16_DS", Const, 5},
+ {"R_PPC64_DTPREL16_HA", Const, 5},
+ {"R_PPC64_DTPREL16_HI", Const, 5},
+ {"R_PPC64_DTPREL16_HIGH", Const, 10},
+ {"R_PPC64_DTPREL16_HIGHA", Const, 10},
+ {"R_PPC64_DTPREL16_HIGHER", Const, 5},
+ {"R_PPC64_DTPREL16_HIGHERA", Const, 5},
+ {"R_PPC64_DTPREL16_HIGHEST", Const, 5},
+ {"R_PPC64_DTPREL16_HIGHESTA", Const, 5},
+ {"R_PPC64_DTPREL16_LO", Const, 5},
+ {"R_PPC64_DTPREL16_LO_DS", Const, 5},
+ {"R_PPC64_DTPREL34", Const, 20},
+ {"R_PPC64_DTPREL64", Const, 5},
+ {"R_PPC64_ENTRY", Const, 10},
+ {"R_PPC64_GLOB_DAT", Const, 20},
+ {"R_PPC64_GNU_VTENTRY", Const, 20},
+ {"R_PPC64_GNU_VTINHERIT", Const, 20},
+ {"R_PPC64_GOT16", Const, 5},
+ {"R_PPC64_GOT16_DS", Const, 5},
+ {"R_PPC64_GOT16_HA", Const, 5},
+ {"R_PPC64_GOT16_HI", Const, 5},
+ {"R_PPC64_GOT16_LO", Const, 5},
+ {"R_PPC64_GOT16_LO_DS", Const, 5},
+ {"R_PPC64_GOT_DTPREL16_DS", Const, 5},
+ {"R_PPC64_GOT_DTPREL16_HA", Const, 5},
+ {"R_PPC64_GOT_DTPREL16_HI", Const, 5},
+ {"R_PPC64_GOT_DTPREL16_LO_DS", Const, 5},
+ {"R_PPC64_GOT_DTPREL_PCREL34", Const, 20},
+ {"R_PPC64_GOT_PCREL34", Const, 20},
+ {"R_PPC64_GOT_TLSGD16", Const, 5},
+ {"R_PPC64_GOT_TLSGD16_HA", Const, 5},
+ {"R_PPC64_GOT_TLSGD16_HI", Const, 5},
+ {"R_PPC64_GOT_TLSGD16_LO", Const, 5},
+ {"R_PPC64_GOT_TLSGD_PCREL34", Const, 20},
+ {"R_PPC64_GOT_TLSLD16", Const, 5},
+ {"R_PPC64_GOT_TLSLD16_HA", Const, 5},
+ {"R_PPC64_GOT_TLSLD16_HI", Const, 5},
+ {"R_PPC64_GOT_TLSLD16_LO", Const, 5},
+ {"R_PPC64_GOT_TLSLD_PCREL34", Const, 20},
+ {"R_PPC64_GOT_TPREL16_DS", Const, 5},
+ {"R_PPC64_GOT_TPREL16_HA", Const, 5},
+ {"R_PPC64_GOT_TPREL16_HI", Const, 5},
+ {"R_PPC64_GOT_TPREL16_LO_DS", Const, 5},
+ {"R_PPC64_GOT_TPREL_PCREL34", Const, 20},
+ {"R_PPC64_IRELATIVE", Const, 10},
+ {"R_PPC64_JMP_IREL", Const, 10},
+ {"R_PPC64_JMP_SLOT", Const, 5},
+ {"R_PPC64_NONE", Const, 5},
+ {"R_PPC64_PCREL28", Const, 20},
+ {"R_PPC64_PCREL34", Const, 20},
+ {"R_PPC64_PCREL_OPT", Const, 20},
+ {"R_PPC64_PLT16_HA", Const, 20},
+ {"R_PPC64_PLT16_HI", Const, 20},
+ {"R_PPC64_PLT16_LO", Const, 20},
+ {"R_PPC64_PLT16_LO_DS", Const, 10},
+ {"R_PPC64_PLT32", Const, 20},
+ {"R_PPC64_PLT64", Const, 20},
+ {"R_PPC64_PLTCALL", Const, 20},
+ {"R_PPC64_PLTCALL_NOTOC", Const, 20},
+ {"R_PPC64_PLTGOT16", Const, 10},
+ {"R_PPC64_PLTGOT16_DS", Const, 10},
+ {"R_PPC64_PLTGOT16_HA", Const, 10},
+ {"R_PPC64_PLTGOT16_HI", Const, 10},
+ {"R_PPC64_PLTGOT16_LO", Const, 10},
+ {"R_PPC64_PLTGOT_LO_DS", Const, 10},
+ {"R_PPC64_PLTREL32", Const, 20},
+ {"R_PPC64_PLTREL64", Const, 20},
+ {"R_PPC64_PLTSEQ", Const, 20},
+ {"R_PPC64_PLTSEQ_NOTOC", Const, 20},
+ {"R_PPC64_PLT_PCREL34", Const, 20},
+ {"R_PPC64_PLT_PCREL34_NOTOC", Const, 20},
+ {"R_PPC64_REL14", Const, 5},
+ {"R_PPC64_REL14_BRNTAKEN", Const, 5},
+ {"R_PPC64_REL14_BRTAKEN", Const, 5},
+ {"R_PPC64_REL16", Const, 5},
+ {"R_PPC64_REL16DX_HA", Const, 10},
+ {"R_PPC64_REL16_HA", Const, 5},
+ {"R_PPC64_REL16_HI", Const, 5},
+ {"R_PPC64_REL16_HIGH", Const, 20},
+ {"R_PPC64_REL16_HIGHA", Const, 20},
+ {"R_PPC64_REL16_HIGHER", Const, 20},
+ {"R_PPC64_REL16_HIGHER34", Const, 20},
+ {"R_PPC64_REL16_HIGHERA", Const, 20},
+ {"R_PPC64_REL16_HIGHERA34", Const, 20},
+ {"R_PPC64_REL16_HIGHEST", Const, 20},
+ {"R_PPC64_REL16_HIGHEST34", Const, 20},
+ {"R_PPC64_REL16_HIGHESTA", Const, 20},
+ {"R_PPC64_REL16_HIGHESTA34", Const, 20},
+ {"R_PPC64_REL16_LO", Const, 5},
+ {"R_PPC64_REL24", Const, 5},
+ {"R_PPC64_REL24_NOTOC", Const, 10},
+ {"R_PPC64_REL24_P9NOTOC", Const, 21},
+ {"R_PPC64_REL30", Const, 20},
+ {"R_PPC64_REL32", Const, 5},
+ {"R_PPC64_REL64", Const, 5},
+ {"R_PPC64_RELATIVE", Const, 18},
+ {"R_PPC64_SECTOFF", Const, 20},
+ {"R_PPC64_SECTOFF_DS", Const, 10},
+ {"R_PPC64_SECTOFF_HA", Const, 20},
+ {"R_PPC64_SECTOFF_HI", Const, 20},
+ {"R_PPC64_SECTOFF_LO", Const, 20},
+ {"R_PPC64_SECTOFF_LO_DS", Const, 10},
+ {"R_PPC64_TLS", Const, 5},
+ {"R_PPC64_TLSGD", Const, 5},
+ {"R_PPC64_TLSLD", Const, 5},
+ {"R_PPC64_TOC", Const, 5},
+ {"R_PPC64_TOC16", Const, 5},
+ {"R_PPC64_TOC16_DS", Const, 5},
+ {"R_PPC64_TOC16_HA", Const, 5},
+ {"R_PPC64_TOC16_HI", Const, 5},
+ {"R_PPC64_TOC16_LO", Const, 5},
+ {"R_PPC64_TOC16_LO_DS", Const, 5},
+ {"R_PPC64_TOCSAVE", Const, 10},
+ {"R_PPC64_TPREL16", Const, 5},
+ {"R_PPC64_TPREL16_DS", Const, 5},
+ {"R_PPC64_TPREL16_HA", Const, 5},
+ {"R_PPC64_TPREL16_HI", Const, 5},
+ {"R_PPC64_TPREL16_HIGH", Const, 10},
+ {"R_PPC64_TPREL16_HIGHA", Const, 10},
+ {"R_PPC64_TPREL16_HIGHER", Const, 5},
+ {"R_PPC64_TPREL16_HIGHERA", Const, 5},
+ {"R_PPC64_TPREL16_HIGHEST", Const, 5},
+ {"R_PPC64_TPREL16_HIGHESTA", Const, 5},
+ {"R_PPC64_TPREL16_LO", Const, 5},
+ {"R_PPC64_TPREL16_LO_DS", Const, 5},
+ {"R_PPC64_TPREL34", Const, 20},
+ {"R_PPC64_TPREL64", Const, 5},
+ {"R_PPC64_UADDR16", Const, 20},
+ {"R_PPC64_UADDR32", Const, 20},
+ {"R_PPC64_UADDR64", Const, 20},
+ {"R_PPC_ADDR14", Const, 0},
+ {"R_PPC_ADDR14_BRNTAKEN", Const, 0},
+ {"R_PPC_ADDR14_BRTAKEN", Const, 0},
+ {"R_PPC_ADDR16", Const, 0},
+ {"R_PPC_ADDR16_HA", Const, 0},
+ {"R_PPC_ADDR16_HI", Const, 0},
+ {"R_PPC_ADDR16_LO", Const, 0},
+ {"R_PPC_ADDR24", Const, 0},
+ {"R_PPC_ADDR32", Const, 0},
+ {"R_PPC_COPY", Const, 0},
+ {"R_PPC_DTPMOD32", Const, 0},
+ {"R_PPC_DTPREL16", Const, 0},
+ {"R_PPC_DTPREL16_HA", Const, 0},
+ {"R_PPC_DTPREL16_HI", Const, 0},
+ {"R_PPC_DTPREL16_LO", Const, 0},
+ {"R_PPC_DTPREL32", Const, 0},
+ {"R_PPC_EMB_BIT_FLD", Const, 0},
+ {"R_PPC_EMB_MRKREF", Const, 0},
+ {"R_PPC_EMB_NADDR16", Const, 0},
+ {"R_PPC_EMB_NADDR16_HA", Const, 0},
+ {"R_PPC_EMB_NADDR16_HI", Const, 0},
+ {"R_PPC_EMB_NADDR16_LO", Const, 0},
+ {"R_PPC_EMB_NADDR32", Const, 0},
+ {"R_PPC_EMB_RELSDA", Const, 0},
+ {"R_PPC_EMB_RELSEC16", Const, 0},
+ {"R_PPC_EMB_RELST_HA", Const, 0},
+ {"R_PPC_EMB_RELST_HI", Const, 0},
+ {"R_PPC_EMB_RELST_LO", Const, 0},
+ {"R_PPC_EMB_SDA21", Const, 0},
+ {"R_PPC_EMB_SDA2I16", Const, 0},
+ {"R_PPC_EMB_SDA2REL", Const, 0},
+ {"R_PPC_EMB_SDAI16", Const, 0},
+ {"R_PPC_GLOB_DAT", Const, 0},
+ {"R_PPC_GOT16", Const, 0},
+ {"R_PPC_GOT16_HA", Const, 0},
+ {"R_PPC_GOT16_HI", Const, 0},
+ {"R_PPC_GOT16_LO", Const, 0},
+ {"R_PPC_GOT_TLSGD16", Const, 0},
+ {"R_PPC_GOT_TLSGD16_HA", Const, 0},
+ {"R_PPC_GOT_TLSGD16_HI", Const, 0},
+ {"R_PPC_GOT_TLSGD16_LO", Const, 0},
+ {"R_PPC_GOT_TLSLD16", Const, 0},
+ {"R_PPC_GOT_TLSLD16_HA", Const, 0},
+ {"R_PPC_GOT_TLSLD16_HI", Const, 0},
+ {"R_PPC_GOT_TLSLD16_LO", Const, 0},
+ {"R_PPC_GOT_TPREL16", Const, 0},
+ {"R_PPC_GOT_TPREL16_HA", Const, 0},
+ {"R_PPC_GOT_TPREL16_HI", Const, 0},
+ {"R_PPC_GOT_TPREL16_LO", Const, 0},
+ {"R_PPC_JMP_SLOT", Const, 0},
+ {"R_PPC_LOCAL24PC", Const, 0},
+ {"R_PPC_NONE", Const, 0},
+ {"R_PPC_PLT16_HA", Const, 0},
+ {"R_PPC_PLT16_HI", Const, 0},
+ {"R_PPC_PLT16_LO", Const, 0},
+ {"R_PPC_PLT32", Const, 0},
+ {"R_PPC_PLTREL24", Const, 0},
+ {"R_PPC_PLTREL32", Const, 0},
+ {"R_PPC_REL14", Const, 0},
+ {"R_PPC_REL14_BRNTAKEN", Const, 0},
+ {"R_PPC_REL14_BRTAKEN", Const, 0},
+ {"R_PPC_REL24", Const, 0},
+ {"R_PPC_REL32", Const, 0},
+ {"R_PPC_RELATIVE", Const, 0},
+ {"R_PPC_SDAREL16", Const, 0},
+ {"R_PPC_SECTOFF", Const, 0},
+ {"R_PPC_SECTOFF_HA", Const, 0},
+ {"R_PPC_SECTOFF_HI", Const, 0},
+ {"R_PPC_SECTOFF_LO", Const, 0},
+ {"R_PPC_TLS", Const, 0},
+ {"R_PPC_TPREL16", Const, 0},
+ {"R_PPC_TPREL16_HA", Const, 0},
+ {"R_PPC_TPREL16_HI", Const, 0},
+ {"R_PPC_TPREL16_LO", Const, 0},
+ {"R_PPC_TPREL32", Const, 0},
+ {"R_PPC_UADDR16", Const, 0},
+ {"R_PPC_UADDR32", Const, 0},
+ {"R_RISCV", Type, 11},
+ {"R_RISCV_32", Const, 11},
+ {"R_RISCV_32_PCREL", Const, 12},
+ {"R_RISCV_64", Const, 11},
+ {"R_RISCV_ADD16", Const, 11},
+ {"R_RISCV_ADD32", Const, 11},
+ {"R_RISCV_ADD64", Const, 11},
+ {"R_RISCV_ADD8", Const, 11},
+ {"R_RISCV_ALIGN", Const, 11},
+ {"R_RISCV_BRANCH", Const, 11},
+ {"R_RISCV_CALL", Const, 11},
+ {"R_RISCV_CALL_PLT", Const, 11},
+ {"R_RISCV_COPY", Const, 11},
+ {"R_RISCV_GNU_VTENTRY", Const, 11},
+ {"R_RISCV_GNU_VTINHERIT", Const, 11},
+ {"R_RISCV_GOT_HI20", Const, 11},
+ {"R_RISCV_GPREL_I", Const, 11},
+ {"R_RISCV_GPREL_S", Const, 11},
+ {"R_RISCV_HI20", Const, 11},
+ {"R_RISCV_JAL", Const, 11},
+ {"R_RISCV_JUMP_SLOT", Const, 11},
+ {"R_RISCV_LO12_I", Const, 11},
+ {"R_RISCV_LO12_S", Const, 11},
+ {"R_RISCV_NONE", Const, 11},
+ {"R_RISCV_PCREL_HI20", Const, 11},
+ {"R_RISCV_PCREL_LO12_I", Const, 11},
+ {"R_RISCV_PCREL_LO12_S", Const, 11},
+ {"R_RISCV_RELATIVE", Const, 11},
+ {"R_RISCV_RELAX", Const, 11},
+ {"R_RISCV_RVC_BRANCH", Const, 11},
+ {"R_RISCV_RVC_JUMP", Const, 11},
+ {"R_RISCV_RVC_LUI", Const, 11},
+ {"R_RISCV_SET16", Const, 11},
+ {"R_RISCV_SET32", Const, 11},
+ {"R_RISCV_SET6", Const, 11},
+ {"R_RISCV_SET8", Const, 11},
+ {"R_RISCV_SUB16", Const, 11},
+ {"R_RISCV_SUB32", Const, 11},
+ {"R_RISCV_SUB6", Const, 11},
+ {"R_RISCV_SUB64", Const, 11},
+ {"R_RISCV_SUB8", Const, 11},
+ {"R_RISCV_TLS_DTPMOD32", Const, 11},
+ {"R_RISCV_TLS_DTPMOD64", Const, 11},
+ {"R_RISCV_TLS_DTPREL32", Const, 11},
+ {"R_RISCV_TLS_DTPREL64", Const, 11},
+ {"R_RISCV_TLS_GD_HI20", Const, 11},
+ {"R_RISCV_TLS_GOT_HI20", Const, 11},
+ {"R_RISCV_TLS_TPREL32", Const, 11},
+ {"R_RISCV_TLS_TPREL64", Const, 11},
+ {"R_RISCV_TPREL_ADD", Const, 11},
+ {"R_RISCV_TPREL_HI20", Const, 11},
+ {"R_RISCV_TPREL_I", Const, 11},
+ {"R_RISCV_TPREL_LO12_I", Const, 11},
+ {"R_RISCV_TPREL_LO12_S", Const, 11},
+ {"R_RISCV_TPREL_S", Const, 11},
+ {"R_SPARC", Type, 0},
+ {"R_SPARC_10", Const, 0},
+ {"R_SPARC_11", Const, 0},
+ {"R_SPARC_13", Const, 0},
+ {"R_SPARC_16", Const, 0},
+ {"R_SPARC_22", Const, 0},
+ {"R_SPARC_32", Const, 0},
+ {"R_SPARC_5", Const, 0},
+ {"R_SPARC_6", Const, 0},
+ {"R_SPARC_64", Const, 0},
+ {"R_SPARC_7", Const, 0},
+ {"R_SPARC_8", Const, 0},
+ {"R_SPARC_COPY", Const, 0},
+ {"R_SPARC_DISP16", Const, 0},
+ {"R_SPARC_DISP32", Const, 0},
+ {"R_SPARC_DISP64", Const, 0},
+ {"R_SPARC_DISP8", Const, 0},
+ {"R_SPARC_GLOB_DAT", Const, 0},
+ {"R_SPARC_GLOB_JMP", Const, 0},
+ {"R_SPARC_GOT10", Const, 0},
+ {"R_SPARC_GOT13", Const, 0},
+ {"R_SPARC_GOT22", Const, 0},
+ {"R_SPARC_H44", Const, 0},
+ {"R_SPARC_HH22", Const, 0},
+ {"R_SPARC_HI22", Const, 0},
+ {"R_SPARC_HIPLT22", Const, 0},
+ {"R_SPARC_HIX22", Const, 0},
+ {"R_SPARC_HM10", Const, 0},
+ {"R_SPARC_JMP_SLOT", Const, 0},
+ {"R_SPARC_L44", Const, 0},
+ {"R_SPARC_LM22", Const, 0},
+ {"R_SPARC_LO10", Const, 0},
+ {"R_SPARC_LOPLT10", Const, 0},
+ {"R_SPARC_LOX10", Const, 0},
+ {"R_SPARC_M44", Const, 0},
+ {"R_SPARC_NONE", Const, 0},
+ {"R_SPARC_OLO10", Const, 0},
+ {"R_SPARC_PC10", Const, 0},
+ {"R_SPARC_PC22", Const, 0},
+ {"R_SPARC_PCPLT10", Const, 0},
+ {"R_SPARC_PCPLT22", Const, 0},
+ {"R_SPARC_PCPLT32", Const, 0},
+ {"R_SPARC_PC_HH22", Const, 0},
+ {"R_SPARC_PC_HM10", Const, 0},
+ {"R_SPARC_PC_LM22", Const, 0},
+ {"R_SPARC_PLT32", Const, 0},
+ {"R_SPARC_PLT64", Const, 0},
+ {"R_SPARC_REGISTER", Const, 0},
+ {"R_SPARC_RELATIVE", Const, 0},
+ {"R_SPARC_UA16", Const, 0},
+ {"R_SPARC_UA32", Const, 0},
+ {"R_SPARC_UA64", Const, 0},
+ {"R_SPARC_WDISP16", Const, 0},
+ {"R_SPARC_WDISP19", Const, 0},
+ {"R_SPARC_WDISP22", Const, 0},
+ {"R_SPARC_WDISP30", Const, 0},
+ {"R_SPARC_WPLT30", Const, 0},
+ {"R_SYM32", Func, 0},
+ {"R_SYM64", Func, 0},
+ {"R_TYPE32", Func, 0},
+ {"R_TYPE64", Func, 0},
+ {"R_X86_64", Type, 0},
+ {"R_X86_64_16", Const, 0},
+ {"R_X86_64_32", Const, 0},
+ {"R_X86_64_32S", Const, 0},
+ {"R_X86_64_64", Const, 0},
+ {"R_X86_64_8", Const, 0},
+ {"R_X86_64_COPY", Const, 0},
+ {"R_X86_64_DTPMOD64", Const, 0},
+ {"R_X86_64_DTPOFF32", Const, 0},
+ {"R_X86_64_DTPOFF64", Const, 0},
+ {"R_X86_64_GLOB_DAT", Const, 0},
+ {"R_X86_64_GOT32", Const, 0},
+ {"R_X86_64_GOT64", Const, 10},
+ {"R_X86_64_GOTOFF64", Const, 10},
+ {"R_X86_64_GOTPC32", Const, 10},
+ {"R_X86_64_GOTPC32_TLSDESC", Const, 10},
+ {"R_X86_64_GOTPC64", Const, 10},
+ {"R_X86_64_GOTPCREL", Const, 0},
+ {"R_X86_64_GOTPCREL64", Const, 10},
+ {"R_X86_64_GOTPCRELX", Const, 10},
+ {"R_X86_64_GOTPLT64", Const, 10},
+ {"R_X86_64_GOTTPOFF", Const, 0},
+ {"R_X86_64_IRELATIVE", Const, 10},
+ {"R_X86_64_JMP_SLOT", Const, 0},
+ {"R_X86_64_NONE", Const, 0},
+ {"R_X86_64_PC16", Const, 0},
+ {"R_X86_64_PC32", Const, 0},
+ {"R_X86_64_PC32_BND", Const, 10},
+ {"R_X86_64_PC64", Const, 10},
+ {"R_X86_64_PC8", Const, 0},
+ {"R_X86_64_PLT32", Const, 0},
+ {"R_X86_64_PLT32_BND", Const, 10},
+ {"R_X86_64_PLTOFF64", Const, 10},
+ {"R_X86_64_RELATIVE", Const, 0},
+ {"R_X86_64_RELATIVE64", Const, 10},
+ {"R_X86_64_REX_GOTPCRELX", Const, 10},
+ {"R_X86_64_SIZE32", Const, 10},
+ {"R_X86_64_SIZE64", Const, 10},
+ {"R_X86_64_TLSDESC", Const, 10},
+ {"R_X86_64_TLSDESC_CALL", Const, 10},
+ {"R_X86_64_TLSGD", Const, 0},
+ {"R_X86_64_TLSLD", Const, 0},
+ {"R_X86_64_TPOFF32", Const, 0},
+ {"R_X86_64_TPOFF64", Const, 0},
+ {"Rel32", Type, 0},
+ {"Rel32.Info", Field, 0},
+ {"Rel32.Off", Field, 0},
+ {"Rel64", Type, 0},
+ {"Rel64.Info", Field, 0},
+ {"Rel64.Off", Field, 0},
+ {"Rela32", Type, 0},
+ {"Rela32.Addend", Field, 0},
+ {"Rela32.Info", Field, 0},
+ {"Rela32.Off", Field, 0},
+ {"Rela64", Type, 0},
+ {"Rela64.Addend", Field, 0},
+ {"Rela64.Info", Field, 0},
+ {"Rela64.Off", Field, 0},
+ {"SHF_ALLOC", Const, 0},
+ {"SHF_COMPRESSED", Const, 6},
+ {"SHF_EXECINSTR", Const, 0},
+ {"SHF_GROUP", Const, 0},
+ {"SHF_INFO_LINK", Const, 0},
+ {"SHF_LINK_ORDER", Const, 0},
+ {"SHF_MASKOS", Const, 0},
+ {"SHF_MASKPROC", Const, 0},
+ {"SHF_MERGE", Const, 0},
+ {"SHF_OS_NONCONFORMING", Const, 0},
+ {"SHF_STRINGS", Const, 0},
+ {"SHF_TLS", Const, 0},
+ {"SHF_WRITE", Const, 0},
+ {"SHN_ABS", Const, 0},
+ {"SHN_COMMON", Const, 0},
+ {"SHN_HIOS", Const, 0},
+ {"SHN_HIPROC", Const, 0},
+ {"SHN_HIRESERVE", Const, 0},
+ {"SHN_LOOS", Const, 0},
+ {"SHN_LOPROC", Const, 0},
+ {"SHN_LORESERVE", Const, 0},
+ {"SHN_UNDEF", Const, 0},
+ {"SHN_XINDEX", Const, 0},
+ {"SHT_DYNAMIC", Const, 0},
+ {"SHT_DYNSYM", Const, 0},
+ {"SHT_FINI_ARRAY", Const, 0},
+ {"SHT_GNU_ATTRIBUTES", Const, 0},
+ {"SHT_GNU_HASH", Const, 0},
+ {"SHT_GNU_LIBLIST", Const, 0},
+ {"SHT_GNU_VERDEF", Const, 0},
+ {"SHT_GNU_VERNEED", Const, 0},
+ {"SHT_GNU_VERSYM", Const, 0},
+ {"SHT_GROUP", Const, 0},
+ {"SHT_HASH", Const, 0},
+ {"SHT_HIOS", Const, 0},
+ {"SHT_HIPROC", Const, 0},
+ {"SHT_HIUSER", Const, 0},
+ {"SHT_INIT_ARRAY", Const, 0},
+ {"SHT_LOOS", Const, 0},
+ {"SHT_LOPROC", Const, 0},
+ {"SHT_LOUSER", Const, 0},
+ {"SHT_MIPS_ABIFLAGS", Const, 17},
+ {"SHT_NOBITS", Const, 0},
+ {"SHT_NOTE", Const, 0},
+ {"SHT_NULL", Const, 0},
+ {"SHT_PREINIT_ARRAY", Const, 0},
+ {"SHT_PROGBITS", Const, 0},
+ {"SHT_REL", Const, 0},
+ {"SHT_RELA", Const, 0},
+ {"SHT_SHLIB", Const, 0},
+ {"SHT_STRTAB", Const, 0},
+ {"SHT_SYMTAB", Const, 0},
+ {"SHT_SYMTAB_SHNDX", Const, 0},
+ {"STB_GLOBAL", Const, 0},
+ {"STB_HIOS", Const, 0},
+ {"STB_HIPROC", Const, 0},
+ {"STB_LOCAL", Const, 0},
+ {"STB_LOOS", Const, 0},
+ {"STB_LOPROC", Const, 0},
+ {"STB_WEAK", Const, 0},
+ {"STT_COMMON", Const, 0},
+ {"STT_FILE", Const, 0},
+ {"STT_FUNC", Const, 0},
+ {"STT_GNU_IFUNC", Const, 23},
+ {"STT_HIOS", Const, 0},
+ {"STT_HIPROC", Const, 0},
+ {"STT_LOOS", Const, 0},
+ {"STT_LOPROC", Const, 0},
+ {"STT_NOTYPE", Const, 0},
+ {"STT_OBJECT", Const, 0},
+ {"STT_RELC", Const, 23},
+ {"STT_SECTION", Const, 0},
+ {"STT_SRELC", Const, 23},
+ {"STT_TLS", Const, 0},
+ {"STV_DEFAULT", Const, 0},
+ {"STV_HIDDEN", Const, 0},
+ {"STV_INTERNAL", Const, 0},
+ {"STV_PROTECTED", Const, 0},
+ {"ST_BIND", Func, 0},
+ {"ST_INFO", Func, 0},
+ {"ST_TYPE", Func, 0},
+ {"ST_VISIBILITY", Func, 0},
+ {"Section", Type, 0},
+ {"Section.ReaderAt", Field, 0},
+ {"Section.SectionHeader", Field, 0},
+ {"Section32", Type, 0},
+ {"Section32.Addr", Field, 0},
+ {"Section32.Addralign", Field, 0},
+ {"Section32.Entsize", Field, 0},
+ {"Section32.Flags", Field, 0},
+ {"Section32.Info", Field, 0},
+ {"Section32.Link", Field, 0},
+ {"Section32.Name", Field, 0},
+ {"Section32.Off", Field, 0},
+ {"Section32.Size", Field, 0},
+ {"Section32.Type", Field, 0},
+ {"Section64", Type, 0},
+ {"Section64.Addr", Field, 0},
+ {"Section64.Addralign", Field, 0},
+ {"Section64.Entsize", Field, 0},
+ {"Section64.Flags", Field, 0},
+ {"Section64.Info", Field, 0},
+ {"Section64.Link", Field, 0},
+ {"Section64.Name", Field, 0},
+ {"Section64.Off", Field, 0},
+ {"Section64.Size", Field, 0},
+ {"Section64.Type", Field, 0},
+ {"SectionFlag", Type, 0},
+ {"SectionHeader", Type, 0},
+ {"SectionHeader.Addr", Field, 0},
+ {"SectionHeader.Addralign", Field, 0},
+ {"SectionHeader.Entsize", Field, 0},
+ {"SectionHeader.FileSize", Field, 6},
+ {"SectionHeader.Flags", Field, 0},
+ {"SectionHeader.Info", Field, 0},
+ {"SectionHeader.Link", Field, 0},
+ {"SectionHeader.Name", Field, 0},
+ {"SectionHeader.Offset", Field, 0},
+ {"SectionHeader.Size", Field, 0},
+ {"SectionHeader.Type", Field, 0},
+ {"SectionIndex", Type, 0},
+ {"SectionType", Type, 0},
+ {"Sym32", Type, 0},
+ {"Sym32.Info", Field, 0},
+ {"Sym32.Name", Field, 0},
+ {"Sym32.Other", Field, 0},
+ {"Sym32.Shndx", Field, 0},
+ {"Sym32.Size", Field, 0},
+ {"Sym32.Value", Field, 0},
+ {"Sym32Size", Const, 0},
+ {"Sym64", Type, 0},
+ {"Sym64.Info", Field, 0},
+ {"Sym64.Name", Field, 0},
+ {"Sym64.Other", Field, 0},
+ {"Sym64.Shndx", Field, 0},
+ {"Sym64.Size", Field, 0},
+ {"Sym64.Value", Field, 0},
+ {"Sym64Size", Const, 0},
+ {"SymBind", Type, 0},
+ {"SymType", Type, 0},
+ {"SymVis", Type, 0},
+ {"Symbol", Type, 0},
+ {"Symbol.Info", Field, 0},
+ {"Symbol.Library", Field, 13},
+ {"Symbol.Name", Field, 0},
+ {"Symbol.Other", Field, 0},
+ {"Symbol.Section", Field, 0},
+ {"Symbol.Size", Field, 0},
+ {"Symbol.Value", Field, 0},
+ {"Symbol.Version", Field, 13},
+ {"Type", Type, 0},
+ {"Version", Type, 0},
+ },
+ "debug/gosym": {
+ {"(*DecodingError).Error", Method, 0},
+ {"(*LineTable).LineToPC", Method, 0},
+ {"(*LineTable).PCToLine", Method, 0},
+ {"(*Sym).BaseName", Method, 0},
+ {"(*Sym).PackageName", Method, 0},
+ {"(*Sym).ReceiverName", Method, 0},
+ {"(*Sym).Static", Method, 0},
+ {"(*Table).LineToPC", Method, 0},
+ {"(*Table).LookupFunc", Method, 0},
+ {"(*Table).LookupSym", Method, 0},
+ {"(*Table).PCToFunc", Method, 0},
+ {"(*Table).PCToLine", Method, 0},
+ {"(*Table).SymByAddr", Method, 0},
+ {"(*UnknownLineError).Error", Method, 0},
+ {"(Func).BaseName", Method, 0},
+ {"(Func).PackageName", Method, 0},
+ {"(Func).ReceiverName", Method, 0},
+ {"(Func).Static", Method, 0},
+ {"(UnknownFileError).Error", Method, 0},
+ {"DecodingError", Type, 0},
+ {"Func", Type, 0},
+ {"Func.End", Field, 0},
+ {"Func.Entry", Field, 0},
+ {"Func.FrameSize", Field, 0},
+ {"Func.LineTable", Field, 0},
+ {"Func.Locals", Field, 0},
+ {"Func.Obj", Field, 0},
+ {"Func.Params", Field, 0},
+ {"Func.Sym", Field, 0},
+ {"LineTable", Type, 0},
+ {"LineTable.Data", Field, 0},
+ {"LineTable.Line", Field, 0},
+ {"LineTable.PC", Field, 0},
+ {"NewLineTable", Func, 0},
+ {"NewTable", Func, 0},
+ {"Obj", Type, 0},
+ {"Obj.Funcs", Field, 0},
+ {"Obj.Paths", Field, 0},
+ {"Sym", Type, 0},
+ {"Sym.Func", Field, 0},
+ {"Sym.GoType", Field, 0},
+ {"Sym.Name", Field, 0},
+ {"Sym.Type", Field, 0},
+ {"Sym.Value", Field, 0},
+ {"Table", Type, 0},
+ {"Table.Files", Field, 0},
+ {"Table.Funcs", Field, 0},
+ {"Table.Objs", Field, 0},
+ {"Table.Syms", Field, 0},
+ {"UnknownFileError", Type, 0},
+ {"UnknownLineError", Type, 0},
+ {"UnknownLineError.File", Field, 0},
+ {"UnknownLineError.Line", Field, 0},
+ },
+ "debug/macho": {
+ {"(*FatFile).Close", Method, 3},
+ {"(*File).Close", Method, 0},
+ {"(*File).DWARF", Method, 0},
+ {"(*File).ImportedLibraries", Method, 0},
+ {"(*File).ImportedSymbols", Method, 0},
+ {"(*File).Section", Method, 0},
+ {"(*File).Segment", Method, 0},
+ {"(*FormatError).Error", Method, 0},
+ {"(*Section).Data", Method, 0},
+ {"(*Section).Open", Method, 0},
+ {"(*Segment).Data", Method, 0},
+ {"(*Segment).Open", Method, 0},
+ {"(Cpu).GoString", Method, 0},
+ {"(Cpu).String", Method, 0},
+ {"(Dylib).Raw", Method, 0},
+ {"(Dysymtab).Raw", Method, 0},
+ {"(FatArch).Close", Method, 3},
+ {"(FatArch).DWARF", Method, 3},
+ {"(FatArch).ImportedLibraries", Method, 3},
+ {"(FatArch).ImportedSymbols", Method, 3},
+ {"(FatArch).Section", Method, 3},
+ {"(FatArch).Segment", Method, 3},
+ {"(LoadBytes).Raw", Method, 0},
+ {"(LoadCmd).GoString", Method, 0},
+ {"(LoadCmd).String", Method, 0},
+ {"(RelocTypeARM).GoString", Method, 10},
+ {"(RelocTypeARM).String", Method, 10},
+ {"(RelocTypeARM64).GoString", Method, 10},
+ {"(RelocTypeARM64).String", Method, 10},
+ {"(RelocTypeGeneric).GoString", Method, 10},
+ {"(RelocTypeGeneric).String", Method, 10},
+ {"(RelocTypeX86_64).GoString", Method, 10},
+ {"(RelocTypeX86_64).String", Method, 10},
+ {"(Rpath).Raw", Method, 10},
+ {"(Section).ReadAt", Method, 0},
+ {"(Segment).Raw", Method, 0},
+ {"(Segment).ReadAt", Method, 0},
+ {"(Symtab).Raw", Method, 0},
+ {"(Type).GoString", Method, 10},
+ {"(Type).String", Method, 10},
+ {"ARM64_RELOC_ADDEND", Const, 10},
+ {"ARM64_RELOC_BRANCH26", Const, 10},
+ {"ARM64_RELOC_GOT_LOAD_PAGE21", Const, 10},
+ {"ARM64_RELOC_GOT_LOAD_PAGEOFF12", Const, 10},
+ {"ARM64_RELOC_PAGE21", Const, 10},
+ {"ARM64_RELOC_PAGEOFF12", Const, 10},
+ {"ARM64_RELOC_POINTER_TO_GOT", Const, 10},
+ {"ARM64_RELOC_SUBTRACTOR", Const, 10},
+ {"ARM64_RELOC_TLVP_LOAD_PAGE21", Const, 10},
+ {"ARM64_RELOC_TLVP_LOAD_PAGEOFF12", Const, 10},
+ {"ARM64_RELOC_UNSIGNED", Const, 10},
+ {"ARM_RELOC_BR24", Const, 10},
+ {"ARM_RELOC_HALF", Const, 10},
+ {"ARM_RELOC_HALF_SECTDIFF", Const, 10},
+ {"ARM_RELOC_LOCAL_SECTDIFF", Const, 10},
+ {"ARM_RELOC_PAIR", Const, 10},
+ {"ARM_RELOC_PB_LA_PTR", Const, 10},
+ {"ARM_RELOC_SECTDIFF", Const, 10},
+ {"ARM_RELOC_VANILLA", Const, 10},
+ {"ARM_THUMB_32BIT_BRANCH", Const, 10},
+ {"ARM_THUMB_RELOC_BR22", Const, 10},
+ {"Cpu", Type, 0},
+ {"Cpu386", Const, 0},
+ {"CpuAmd64", Const, 0},
+ {"CpuArm", Const, 3},
+ {"CpuArm64", Const, 11},
+ {"CpuPpc", Const, 3},
+ {"CpuPpc64", Const, 3},
+ {"Dylib", Type, 0},
+ {"Dylib.CompatVersion", Field, 0},
+ {"Dylib.CurrentVersion", Field, 0},
+ {"Dylib.LoadBytes", Field, 0},
+ {"Dylib.Name", Field, 0},
+ {"Dylib.Time", Field, 0},
+ {"DylibCmd", Type, 0},
+ {"DylibCmd.Cmd", Field, 0},
+ {"DylibCmd.CompatVersion", Field, 0},
+ {"DylibCmd.CurrentVersion", Field, 0},
+ {"DylibCmd.Len", Field, 0},
+ {"DylibCmd.Name", Field, 0},
+ {"DylibCmd.Time", Field, 0},
+ {"Dysymtab", Type, 0},
+ {"Dysymtab.DysymtabCmd", Field, 0},
+ {"Dysymtab.IndirectSyms", Field, 0},
+ {"Dysymtab.LoadBytes", Field, 0},
+ {"DysymtabCmd", Type, 0},
+ {"DysymtabCmd.Cmd", Field, 0},
+ {"DysymtabCmd.Extrefsymoff", Field, 0},
+ {"DysymtabCmd.Extreloff", Field, 0},
+ {"DysymtabCmd.Iextdefsym", Field, 0},
+ {"DysymtabCmd.Ilocalsym", Field, 0},
+ {"DysymtabCmd.Indirectsymoff", Field, 0},
+ {"DysymtabCmd.Iundefsym", Field, 0},
+ {"DysymtabCmd.Len", Field, 0},
+ {"DysymtabCmd.Locreloff", Field, 0},
+ {"DysymtabCmd.Modtaboff", Field, 0},
+ {"DysymtabCmd.Nextdefsym", Field, 0},
+ {"DysymtabCmd.Nextrefsyms", Field, 0},
+ {"DysymtabCmd.Nextrel", Field, 0},
+ {"DysymtabCmd.Nindirectsyms", Field, 0},
+ {"DysymtabCmd.Nlocalsym", Field, 0},
+ {"DysymtabCmd.Nlocrel", Field, 0},
+ {"DysymtabCmd.Nmodtab", Field, 0},
+ {"DysymtabCmd.Ntoc", Field, 0},
+ {"DysymtabCmd.Nundefsym", Field, 0},
+ {"DysymtabCmd.Tocoffset", Field, 0},
+ {"ErrNotFat", Var, 3},
+ {"FatArch", Type, 3},
+ {"FatArch.FatArchHeader", Field, 3},
+ {"FatArch.File", Field, 3},
+ {"FatArchHeader", Type, 3},
+ {"FatArchHeader.Align", Field, 3},
+ {"FatArchHeader.Cpu", Field, 3},
+ {"FatArchHeader.Offset", Field, 3},
+ {"FatArchHeader.Size", Field, 3},
+ {"FatArchHeader.SubCpu", Field, 3},
+ {"FatFile", Type, 3},
+ {"FatFile.Arches", Field, 3},
+ {"FatFile.Magic", Field, 3},
+ {"File", Type, 0},
+ {"File.ByteOrder", Field, 0},
+ {"File.Dysymtab", Field, 0},
+ {"File.FileHeader", Field, 0},
+ {"File.Loads", Field, 0},
+ {"File.Sections", Field, 0},
+ {"File.Symtab", Field, 0},
+ {"FileHeader", Type, 0},
+ {"FileHeader.Cmdsz", Field, 0},
+ {"FileHeader.Cpu", Field, 0},
+ {"FileHeader.Flags", Field, 0},
+ {"FileHeader.Magic", Field, 0},
+ {"FileHeader.Ncmd", Field, 0},
+ {"FileHeader.SubCpu", Field, 0},
+ {"FileHeader.Type", Field, 0},
+ {"FlagAllModsBound", Const, 10},
+ {"FlagAllowStackExecution", Const, 10},
+ {"FlagAppExtensionSafe", Const, 10},
+ {"FlagBindAtLoad", Const, 10},
+ {"FlagBindsToWeak", Const, 10},
+ {"FlagCanonical", Const, 10},
+ {"FlagDeadStrippableDylib", Const, 10},
+ {"FlagDyldLink", Const, 10},
+ {"FlagForceFlat", Const, 10},
+ {"FlagHasTLVDescriptors", Const, 10},
+ {"FlagIncrLink", Const, 10},
+ {"FlagLazyInit", Const, 10},
+ {"FlagNoFixPrebinding", Const, 10},
+ {"FlagNoHeapExecution", Const, 10},
+ {"FlagNoMultiDefs", Const, 10},
+ {"FlagNoReexportedDylibs", Const, 10},
+ {"FlagNoUndefs", Const, 10},
+ {"FlagPIE", Const, 10},
+ {"FlagPrebindable", Const, 10},
+ {"FlagPrebound", Const, 10},
+ {"FlagRootSafe", Const, 10},
+ {"FlagSetuidSafe", Const, 10},
+ {"FlagSplitSegs", Const, 10},
+ {"FlagSubsectionsViaSymbols", Const, 10},
+ {"FlagTwoLevel", Const, 10},
+ {"FlagWeakDefines", Const, 10},
+ {"FormatError", Type, 0},
+ {"GENERIC_RELOC_LOCAL_SECTDIFF", Const, 10},
+ {"GENERIC_RELOC_PAIR", Const, 10},
+ {"GENERIC_RELOC_PB_LA_PTR", Const, 10},
+ {"GENERIC_RELOC_SECTDIFF", Const, 10},
+ {"GENERIC_RELOC_TLV", Const, 10},
+ {"GENERIC_RELOC_VANILLA", Const, 10},
+ {"Load", Type, 0},
+ {"LoadBytes", Type, 0},
+ {"LoadCmd", Type, 0},
+ {"LoadCmdDylib", Const, 0},
+ {"LoadCmdDylinker", Const, 0},
+ {"LoadCmdDysymtab", Const, 0},
+ {"LoadCmdRpath", Const, 10},
+ {"LoadCmdSegment", Const, 0},
+ {"LoadCmdSegment64", Const, 0},
+ {"LoadCmdSymtab", Const, 0},
+ {"LoadCmdThread", Const, 0},
+ {"LoadCmdUnixThread", Const, 0},
+ {"Magic32", Const, 0},
+ {"Magic64", Const, 0},
+ {"MagicFat", Const, 3},
+ {"NewFatFile", Func, 3},
+ {"NewFile", Func, 0},
+ {"Nlist32", Type, 0},
+ {"Nlist32.Desc", Field, 0},
+ {"Nlist32.Name", Field, 0},
+ {"Nlist32.Sect", Field, 0},
+ {"Nlist32.Type", Field, 0},
+ {"Nlist32.Value", Field, 0},
+ {"Nlist64", Type, 0},
+ {"Nlist64.Desc", Field, 0},
+ {"Nlist64.Name", Field, 0},
+ {"Nlist64.Sect", Field, 0},
+ {"Nlist64.Type", Field, 0},
+ {"Nlist64.Value", Field, 0},
+ {"Open", Func, 0},
+ {"OpenFat", Func, 3},
+ {"Regs386", Type, 0},
+ {"Regs386.AX", Field, 0},
+ {"Regs386.BP", Field, 0},
+ {"Regs386.BX", Field, 0},
+ {"Regs386.CS", Field, 0},
+ {"Regs386.CX", Field, 0},
+ {"Regs386.DI", Field, 0},
+ {"Regs386.DS", Field, 0},
+ {"Regs386.DX", Field, 0},
+ {"Regs386.ES", Field, 0},
+ {"Regs386.FLAGS", Field, 0},
+ {"Regs386.FS", Field, 0},
+ {"Regs386.GS", Field, 0},
+ {"Regs386.IP", Field, 0},
+ {"Regs386.SI", Field, 0},
+ {"Regs386.SP", Field, 0},
+ {"Regs386.SS", Field, 0},
+ {"RegsAMD64", Type, 0},
+ {"RegsAMD64.AX", Field, 0},
+ {"RegsAMD64.BP", Field, 0},
+ {"RegsAMD64.BX", Field, 0},
+ {"RegsAMD64.CS", Field, 0},
+ {"RegsAMD64.CX", Field, 0},
+ {"RegsAMD64.DI", Field, 0},
+ {"RegsAMD64.DX", Field, 0},
+ {"RegsAMD64.FLAGS", Field, 0},
+ {"RegsAMD64.FS", Field, 0},
+ {"RegsAMD64.GS", Field, 0},
+ {"RegsAMD64.IP", Field, 0},
+ {"RegsAMD64.R10", Field, 0},
+ {"RegsAMD64.R11", Field, 0},
+ {"RegsAMD64.R12", Field, 0},
+ {"RegsAMD64.R13", Field, 0},
+ {"RegsAMD64.R14", Field, 0},
+ {"RegsAMD64.R15", Field, 0},
+ {"RegsAMD64.R8", Field, 0},
+ {"RegsAMD64.R9", Field, 0},
+ {"RegsAMD64.SI", Field, 0},
+ {"RegsAMD64.SP", Field, 0},
+ {"Reloc", Type, 10},
+ {"Reloc.Addr", Field, 10},
+ {"Reloc.Extern", Field, 10},
+ {"Reloc.Len", Field, 10},
+ {"Reloc.Pcrel", Field, 10},
+ {"Reloc.Scattered", Field, 10},
+ {"Reloc.Type", Field, 10},
+ {"Reloc.Value", Field, 10},
+ {"RelocTypeARM", Type, 10},
+ {"RelocTypeARM64", Type, 10},
+ {"RelocTypeGeneric", Type, 10},
+ {"RelocTypeX86_64", Type, 10},
+ {"Rpath", Type, 10},
+ {"Rpath.LoadBytes", Field, 10},
+ {"Rpath.Path", Field, 10},
+ {"RpathCmd", Type, 10},
+ {"RpathCmd.Cmd", Field, 10},
+ {"RpathCmd.Len", Field, 10},
+ {"RpathCmd.Path", Field, 10},
+ {"Section", Type, 0},
+ {"Section.ReaderAt", Field, 0},
+ {"Section.Relocs", Field, 10},
+ {"Section.SectionHeader", Field, 0},
+ {"Section32", Type, 0},
+ {"Section32.Addr", Field, 0},
+ {"Section32.Align", Field, 0},
+ {"Section32.Flags", Field, 0},
+ {"Section32.Name", Field, 0},
+ {"Section32.Nreloc", Field, 0},
+ {"Section32.Offset", Field, 0},
+ {"Section32.Reloff", Field, 0},
+ {"Section32.Reserve1", Field, 0},
+ {"Section32.Reserve2", Field, 0},
+ {"Section32.Seg", Field, 0},
+ {"Section32.Size", Field, 0},
+ {"Section64", Type, 0},
+ {"Section64.Addr", Field, 0},
+ {"Section64.Align", Field, 0},
+ {"Section64.Flags", Field, 0},
+ {"Section64.Name", Field, 0},
+ {"Section64.Nreloc", Field, 0},
+ {"Section64.Offset", Field, 0},
+ {"Section64.Reloff", Field, 0},
+ {"Section64.Reserve1", Field, 0},
+ {"Section64.Reserve2", Field, 0},
+ {"Section64.Reserve3", Field, 0},
+ {"Section64.Seg", Field, 0},
+ {"Section64.Size", Field, 0},
+ {"SectionHeader", Type, 0},
+ {"SectionHeader.Addr", Field, 0},
+ {"SectionHeader.Align", Field, 0},
+ {"SectionHeader.Flags", Field, 0},
+ {"SectionHeader.Name", Field, 0},
+ {"SectionHeader.Nreloc", Field, 0},
+ {"SectionHeader.Offset", Field, 0},
+ {"SectionHeader.Reloff", Field, 0},
+ {"SectionHeader.Seg", Field, 0},
+ {"SectionHeader.Size", Field, 0},
+ {"Segment", Type, 0},
+ {"Segment.LoadBytes", Field, 0},
+ {"Segment.ReaderAt", Field, 0},
+ {"Segment.SegmentHeader", Field, 0},
+ {"Segment32", Type, 0},
+ {"Segment32.Addr", Field, 0},
+ {"Segment32.Cmd", Field, 0},
+ {"Segment32.Filesz", Field, 0},
+ {"Segment32.Flag", Field, 0},
+ {"Segment32.Len", Field, 0},
+ {"Segment32.Maxprot", Field, 0},
+ {"Segment32.Memsz", Field, 0},
+ {"Segment32.Name", Field, 0},
+ {"Segment32.Nsect", Field, 0},
+ {"Segment32.Offset", Field, 0},
+ {"Segment32.Prot", Field, 0},
+ {"Segment64", Type, 0},
+ {"Segment64.Addr", Field, 0},
+ {"Segment64.Cmd", Field, 0},
+ {"Segment64.Filesz", Field, 0},
+ {"Segment64.Flag", Field, 0},
+ {"Segment64.Len", Field, 0},
+ {"Segment64.Maxprot", Field, 0},
+ {"Segment64.Memsz", Field, 0},
+ {"Segment64.Name", Field, 0},
+ {"Segment64.Nsect", Field, 0},
+ {"Segment64.Offset", Field, 0},
+ {"Segment64.Prot", Field, 0},
+ {"SegmentHeader", Type, 0},
+ {"SegmentHeader.Addr", Field, 0},
+ {"SegmentHeader.Cmd", Field, 0},
+ {"SegmentHeader.Filesz", Field, 0},
+ {"SegmentHeader.Flag", Field, 0},
+ {"SegmentHeader.Len", Field, 0},
+ {"SegmentHeader.Maxprot", Field, 0},
+ {"SegmentHeader.Memsz", Field, 0},
+ {"SegmentHeader.Name", Field, 0},
+ {"SegmentHeader.Nsect", Field, 0},
+ {"SegmentHeader.Offset", Field, 0},
+ {"SegmentHeader.Prot", Field, 0},
+ {"Symbol", Type, 0},
+ {"Symbol.Desc", Field, 0},
+ {"Symbol.Name", Field, 0},
+ {"Symbol.Sect", Field, 0},
+ {"Symbol.Type", Field, 0},
+ {"Symbol.Value", Field, 0},
+ {"Symtab", Type, 0},
+ {"Symtab.LoadBytes", Field, 0},
+ {"Symtab.Syms", Field, 0},
+ {"Symtab.SymtabCmd", Field, 0},
+ {"SymtabCmd", Type, 0},
+ {"SymtabCmd.Cmd", Field, 0},
+ {"SymtabCmd.Len", Field, 0},
+ {"SymtabCmd.Nsyms", Field, 0},
+ {"SymtabCmd.Stroff", Field, 0},
+ {"SymtabCmd.Strsize", Field, 0},
+ {"SymtabCmd.Symoff", Field, 0},
+ {"Thread", Type, 0},
+ {"Thread.Cmd", Field, 0},
+ {"Thread.Data", Field, 0},
+ {"Thread.Len", Field, 0},
+ {"Thread.Type", Field, 0},
+ {"Type", Type, 0},
+ {"TypeBundle", Const, 3},
+ {"TypeDylib", Const, 3},
+ {"TypeExec", Const, 0},
+ {"TypeObj", Const, 0},
+ {"X86_64_RELOC_BRANCH", Const, 10},
+ {"X86_64_RELOC_GOT", Const, 10},
+ {"X86_64_RELOC_GOT_LOAD", Const, 10},
+ {"X86_64_RELOC_SIGNED", Const, 10},
+ {"X86_64_RELOC_SIGNED_1", Const, 10},
+ {"X86_64_RELOC_SIGNED_2", Const, 10},
+ {"X86_64_RELOC_SIGNED_4", Const, 10},
+ {"X86_64_RELOC_SUBTRACTOR", Const, 10},
+ {"X86_64_RELOC_TLV", Const, 10},
+ {"X86_64_RELOC_UNSIGNED", Const, 10},
+ },
+ "debug/pe": {
+ {"(*COFFSymbol).FullName", Method, 8},
+ {"(*File).COFFSymbolReadSectionDefAux", Method, 19},
+ {"(*File).Close", Method, 0},
+ {"(*File).DWARF", Method, 0},
+ {"(*File).ImportedLibraries", Method, 0},
+ {"(*File).ImportedSymbols", Method, 0},
+ {"(*File).Section", Method, 0},
+ {"(*FormatError).Error", Method, 0},
+ {"(*Section).Data", Method, 0},
+ {"(*Section).Open", Method, 0},
+ {"(Section).ReadAt", Method, 0},
+ {"(StringTable).String", Method, 8},
+ {"COFFSymbol", Type, 1},
+ {"COFFSymbol.Name", Field, 1},
+ {"COFFSymbol.NumberOfAuxSymbols", Field, 1},
+ {"COFFSymbol.SectionNumber", Field, 1},
+ {"COFFSymbol.StorageClass", Field, 1},
+ {"COFFSymbol.Type", Field, 1},
+ {"COFFSymbol.Value", Field, 1},
+ {"COFFSymbolAuxFormat5", Type, 19},
+ {"COFFSymbolAuxFormat5.Checksum", Field, 19},
+ {"COFFSymbolAuxFormat5.NumLineNumbers", Field, 19},
+ {"COFFSymbolAuxFormat5.NumRelocs", Field, 19},
+ {"COFFSymbolAuxFormat5.SecNum", Field, 19},
+ {"COFFSymbolAuxFormat5.Selection", Field, 19},
+ {"COFFSymbolAuxFormat5.Size", Field, 19},
+ {"COFFSymbolSize", Const, 1},
+ {"DataDirectory", Type, 3},
+ {"DataDirectory.Size", Field, 3},
+ {"DataDirectory.VirtualAddress", Field, 3},
+ {"File", Type, 0},
+ {"File.COFFSymbols", Field, 8},
+ {"File.FileHeader", Field, 0},
+ {"File.OptionalHeader", Field, 3},
+ {"File.Sections", Field, 0},
+ {"File.StringTable", Field, 8},
+ {"File.Symbols", Field, 1},
+ {"FileHeader", Type, 0},
+ {"FileHeader.Characteristics", Field, 0},
+ {"FileHeader.Machine", Field, 0},
+ {"FileHeader.NumberOfSections", Field, 0},
+ {"FileHeader.NumberOfSymbols", Field, 0},
+ {"FileHeader.PointerToSymbolTable", Field, 0},
+ {"FileHeader.SizeOfOptionalHeader", Field, 0},
+ {"FileHeader.TimeDateStamp", Field, 0},
+ {"FormatError", Type, 0},
+ {"IMAGE_COMDAT_SELECT_ANY", Const, 19},
+ {"IMAGE_COMDAT_SELECT_ASSOCIATIVE", Const, 19},
+ {"IMAGE_COMDAT_SELECT_EXACT_MATCH", Const, 19},
+ {"IMAGE_COMDAT_SELECT_LARGEST", Const, 19},
+ {"IMAGE_COMDAT_SELECT_NODUPLICATES", Const, 19},
+ {"IMAGE_COMDAT_SELECT_SAME_SIZE", Const, 19},
+ {"IMAGE_DIRECTORY_ENTRY_ARCHITECTURE", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_BASERELOC", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_DEBUG", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_EXCEPTION", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_EXPORT", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_GLOBALPTR", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_IAT", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_IMPORT", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_RESOURCE", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_SECURITY", Const, 11},
+ {"IMAGE_DIRECTORY_ENTRY_TLS", Const, 11},
+ {"IMAGE_DLLCHARACTERISTICS_APPCONTAINER", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_GUARD_CF", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_NO_BIND", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_NO_ISOLATION", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_NO_SEH", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_NX_COMPAT", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE", Const, 15},
+ {"IMAGE_DLLCHARACTERISTICS_WDM_DRIVER", Const, 15},
+ {"IMAGE_FILE_32BIT_MACHINE", Const, 15},
+ {"IMAGE_FILE_AGGRESIVE_WS_TRIM", Const, 15},
+ {"IMAGE_FILE_BYTES_REVERSED_HI", Const, 15},
+ {"IMAGE_FILE_BYTES_REVERSED_LO", Const, 15},
+ {"IMAGE_FILE_DEBUG_STRIPPED", Const, 15},
+ {"IMAGE_FILE_DLL", Const, 15},
+ {"IMAGE_FILE_EXECUTABLE_IMAGE", Const, 15},
+ {"IMAGE_FILE_LARGE_ADDRESS_AWARE", Const, 15},
+ {"IMAGE_FILE_LINE_NUMS_STRIPPED", Const, 15},
+ {"IMAGE_FILE_LOCAL_SYMS_STRIPPED", Const, 15},
+ {"IMAGE_FILE_MACHINE_AM33", Const, 0},
+ {"IMAGE_FILE_MACHINE_AMD64", Const, 0},
+ {"IMAGE_FILE_MACHINE_ARM", Const, 0},
+ {"IMAGE_FILE_MACHINE_ARM64", Const, 11},
+ {"IMAGE_FILE_MACHINE_ARMNT", Const, 12},
+ {"IMAGE_FILE_MACHINE_EBC", Const, 0},
+ {"IMAGE_FILE_MACHINE_I386", Const, 0},
+ {"IMAGE_FILE_MACHINE_IA64", Const, 0},
+ {"IMAGE_FILE_MACHINE_LOONGARCH32", Const, 19},
+ {"IMAGE_FILE_MACHINE_LOONGARCH64", Const, 19},
+ {"IMAGE_FILE_MACHINE_M32R", Const, 0},
+ {"IMAGE_FILE_MACHINE_MIPS16", Const, 0},
+ {"IMAGE_FILE_MACHINE_MIPSFPU", Const, 0},
+ {"IMAGE_FILE_MACHINE_MIPSFPU16", Const, 0},
+ {"IMAGE_FILE_MACHINE_POWERPC", Const, 0},
+ {"IMAGE_FILE_MACHINE_POWERPCFP", Const, 0},
+ {"IMAGE_FILE_MACHINE_R4000", Const, 0},
+ {"IMAGE_FILE_MACHINE_RISCV128", Const, 20},
+ {"IMAGE_FILE_MACHINE_RISCV32", Const, 20},
+ {"IMAGE_FILE_MACHINE_RISCV64", Const, 20},
+ {"IMAGE_FILE_MACHINE_SH3", Const, 0},
+ {"IMAGE_FILE_MACHINE_SH3DSP", Const, 0},
+ {"IMAGE_FILE_MACHINE_SH4", Const, 0},
+ {"IMAGE_FILE_MACHINE_SH5", Const, 0},
+ {"IMAGE_FILE_MACHINE_THUMB", Const, 0},
+ {"IMAGE_FILE_MACHINE_UNKNOWN", Const, 0},
+ {"IMAGE_FILE_MACHINE_WCEMIPSV2", Const, 0},
+ {"IMAGE_FILE_NET_RUN_FROM_SWAP", Const, 15},
+ {"IMAGE_FILE_RELOCS_STRIPPED", Const, 15},
+ {"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP", Const, 15},
+ {"IMAGE_FILE_SYSTEM", Const, 15},
+ {"IMAGE_FILE_UP_SYSTEM_ONLY", Const, 15},
+ {"IMAGE_SCN_CNT_CODE", Const, 19},
+ {"IMAGE_SCN_CNT_INITIALIZED_DATA", Const, 19},
+ {"IMAGE_SCN_CNT_UNINITIALIZED_DATA", Const, 19},
+ {"IMAGE_SCN_LNK_COMDAT", Const, 19},
+ {"IMAGE_SCN_MEM_DISCARDABLE", Const, 19},
+ {"IMAGE_SCN_MEM_EXECUTE", Const, 19},
+ {"IMAGE_SCN_MEM_READ", Const, 19},
+ {"IMAGE_SCN_MEM_WRITE", Const, 19},
+ {"IMAGE_SUBSYSTEM_EFI_APPLICATION", Const, 15},
+ {"IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER", Const, 15},
+ {"IMAGE_SUBSYSTEM_EFI_ROM", Const, 15},
+ {"IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER", Const, 15},
+ {"IMAGE_SUBSYSTEM_NATIVE", Const, 15},
+ {"IMAGE_SUBSYSTEM_NATIVE_WINDOWS", Const, 15},
+ {"IMAGE_SUBSYSTEM_OS2_CUI", Const, 15},
+ {"IMAGE_SUBSYSTEM_POSIX_CUI", Const, 15},
+ {"IMAGE_SUBSYSTEM_UNKNOWN", Const, 15},
+ {"IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION", Const, 15},
+ {"IMAGE_SUBSYSTEM_WINDOWS_CE_GUI", Const, 15},
+ {"IMAGE_SUBSYSTEM_WINDOWS_CUI", Const, 15},
+ {"IMAGE_SUBSYSTEM_WINDOWS_GUI", Const, 15},
+ {"IMAGE_SUBSYSTEM_XBOX", Const, 15},
+ {"ImportDirectory", Type, 0},
+ {"ImportDirectory.FirstThunk", Field, 0},
+ {"ImportDirectory.ForwarderChain", Field, 0},
+ {"ImportDirectory.Name", Field, 0},
+ {"ImportDirectory.OriginalFirstThunk", Field, 0},
+ {"ImportDirectory.TimeDateStamp", Field, 0},
+ {"NewFile", Func, 0},
+ {"Open", Func, 0},
+ {"OptionalHeader32", Type, 3},
+ {"OptionalHeader32.AddressOfEntryPoint", Field, 3},
+ {"OptionalHeader32.BaseOfCode", Field, 3},
+ {"OptionalHeader32.BaseOfData", Field, 3},
+ {"OptionalHeader32.CheckSum", Field, 3},
+ {"OptionalHeader32.DataDirectory", Field, 3},
+ {"OptionalHeader32.DllCharacteristics", Field, 3},
+ {"OptionalHeader32.FileAlignment", Field, 3},
+ {"OptionalHeader32.ImageBase", Field, 3},
+ {"OptionalHeader32.LoaderFlags", Field, 3},
+ {"OptionalHeader32.Magic", Field, 3},
+ {"OptionalHeader32.MajorImageVersion", Field, 3},
+ {"OptionalHeader32.MajorLinkerVersion", Field, 3},
+ {"OptionalHeader32.MajorOperatingSystemVersion", Field, 3},
+ {"OptionalHeader32.MajorSubsystemVersion", Field, 3},
+ {"OptionalHeader32.MinorImageVersion", Field, 3},
+ {"OptionalHeader32.MinorLinkerVersion", Field, 3},
+ {"OptionalHeader32.MinorOperatingSystemVersion", Field, 3},
+ {"OptionalHeader32.MinorSubsystemVersion", Field, 3},
+ {"OptionalHeader32.NumberOfRvaAndSizes", Field, 3},
+ {"OptionalHeader32.SectionAlignment", Field, 3},
+ {"OptionalHeader32.SizeOfCode", Field, 3},
+ {"OptionalHeader32.SizeOfHeaders", Field, 3},
+ {"OptionalHeader32.SizeOfHeapCommit", Field, 3},
+ {"OptionalHeader32.SizeOfHeapReserve", Field, 3},
+ {"OptionalHeader32.SizeOfImage", Field, 3},
+ {"OptionalHeader32.SizeOfInitializedData", Field, 3},
+ {"OptionalHeader32.SizeOfStackCommit", Field, 3},
+ {"OptionalHeader32.SizeOfStackReserve", Field, 3},
+ {"OptionalHeader32.SizeOfUninitializedData", Field, 3},
+ {"OptionalHeader32.Subsystem", Field, 3},
+ {"OptionalHeader32.Win32VersionValue", Field, 3},
+ {"OptionalHeader64", Type, 3},
+ {"OptionalHeader64.AddressOfEntryPoint", Field, 3},
+ {"OptionalHeader64.BaseOfCode", Field, 3},
+ {"OptionalHeader64.CheckSum", Field, 3},
+ {"OptionalHeader64.DataDirectory", Field, 3},
+ {"OptionalHeader64.DllCharacteristics", Field, 3},
+ {"OptionalHeader64.FileAlignment", Field, 3},
+ {"OptionalHeader64.ImageBase", Field, 3},
+ {"OptionalHeader64.LoaderFlags", Field, 3},
+ {"OptionalHeader64.Magic", Field, 3},
+ {"OptionalHeader64.MajorImageVersion", Field, 3},
+ {"OptionalHeader64.MajorLinkerVersion", Field, 3},
+ {"OptionalHeader64.MajorOperatingSystemVersion", Field, 3},
+ {"OptionalHeader64.MajorSubsystemVersion", Field, 3},
+ {"OptionalHeader64.MinorImageVersion", Field, 3},
+ {"OptionalHeader64.MinorLinkerVersion", Field, 3},
+ {"OptionalHeader64.MinorOperatingSystemVersion", Field, 3},
+ {"OptionalHeader64.MinorSubsystemVersion", Field, 3},
+ {"OptionalHeader64.NumberOfRvaAndSizes", Field, 3},
+ {"OptionalHeader64.SectionAlignment", Field, 3},
+ {"OptionalHeader64.SizeOfCode", Field, 3},
+ {"OptionalHeader64.SizeOfHeaders", Field, 3},
+ {"OptionalHeader64.SizeOfHeapCommit", Field, 3},
+ {"OptionalHeader64.SizeOfHeapReserve", Field, 3},
+ {"OptionalHeader64.SizeOfImage", Field, 3},
+ {"OptionalHeader64.SizeOfInitializedData", Field, 3},
+ {"OptionalHeader64.SizeOfStackCommit", Field, 3},
+ {"OptionalHeader64.SizeOfStackReserve", Field, 3},
+ {"OptionalHeader64.SizeOfUninitializedData", Field, 3},
+ {"OptionalHeader64.Subsystem", Field, 3},
+ {"OptionalHeader64.Win32VersionValue", Field, 3},
+ {"Reloc", Type, 8},
+ {"Reloc.SymbolTableIndex", Field, 8},
+ {"Reloc.Type", Field, 8},
+ {"Reloc.VirtualAddress", Field, 8},
+ {"Section", Type, 0},
+ {"Section.ReaderAt", Field, 0},
+ {"Section.Relocs", Field, 8},
+ {"Section.SectionHeader", Field, 0},
+ {"SectionHeader", Type, 0},
+ {"SectionHeader.Characteristics", Field, 0},
+ {"SectionHeader.Name", Field, 0},
+ {"SectionHeader.NumberOfLineNumbers", Field, 0},
+ {"SectionHeader.NumberOfRelocations", Field, 0},
+ {"SectionHeader.Offset", Field, 0},
+ {"SectionHeader.PointerToLineNumbers", Field, 0},
+ {"SectionHeader.PointerToRelocations", Field, 0},
+ {"SectionHeader.Size", Field, 0},
+ {"SectionHeader.VirtualAddress", Field, 0},
+ {"SectionHeader.VirtualSize", Field, 0},
+ {"SectionHeader32", Type, 0},
+ {"SectionHeader32.Characteristics", Field, 0},
+ {"SectionHeader32.Name", Field, 0},
+ {"SectionHeader32.NumberOfLineNumbers", Field, 0},
+ {"SectionHeader32.NumberOfRelocations", Field, 0},
+ {"SectionHeader32.PointerToLineNumbers", Field, 0},
+ {"SectionHeader32.PointerToRawData", Field, 0},
+ {"SectionHeader32.PointerToRelocations", Field, 0},
+ {"SectionHeader32.SizeOfRawData", Field, 0},
+ {"SectionHeader32.VirtualAddress", Field, 0},
+ {"SectionHeader32.VirtualSize", Field, 0},
+ {"StringTable", Type, 8},
+ {"Symbol", Type, 1},
+ {"Symbol.Name", Field, 1},
+ {"Symbol.SectionNumber", Field, 1},
+ {"Symbol.StorageClass", Field, 1},
+ {"Symbol.Type", Field, 1},
+ {"Symbol.Value", Field, 1},
+ },
+ "debug/plan9obj": {
+ {"(*File).Close", Method, 3},
+ {"(*File).Section", Method, 3},
+ {"(*File).Symbols", Method, 3},
+ {"(*Section).Data", Method, 3},
+ {"(*Section).Open", Method, 3},
+ {"(Section).ReadAt", Method, 3},
+ {"ErrNoSymbols", Var, 18},
+ {"File", Type, 3},
+ {"File.FileHeader", Field, 3},
+ {"File.Sections", Field, 3},
+ {"FileHeader", Type, 3},
+ {"FileHeader.Bss", Field, 3},
+ {"FileHeader.Entry", Field, 3},
+ {"FileHeader.HdrSize", Field, 4},
+ {"FileHeader.LoadAddress", Field, 4},
+ {"FileHeader.Magic", Field, 3},
+ {"FileHeader.PtrSize", Field, 3},
+ {"Magic386", Const, 3},
+ {"Magic64", Const, 3},
+ {"MagicAMD64", Const, 3},
+ {"MagicARM", Const, 3},
+ {"NewFile", Func, 3},
+ {"Open", Func, 3},
+ {"Section", Type, 3},
+ {"Section.ReaderAt", Field, 3},
+ {"Section.SectionHeader", Field, 3},
+ {"SectionHeader", Type, 3},
+ {"SectionHeader.Name", Field, 3},
+ {"SectionHeader.Offset", Field, 3},
+ {"SectionHeader.Size", Field, 3},
+ {"Sym", Type, 3},
+ {"Sym.Name", Field, 3},
+ {"Sym.Type", Field, 3},
+ {"Sym.Value", Field, 3},
+ },
+ "embed": {
+ {"(FS).Open", Method, 16},
+ {"(FS).ReadDir", Method, 16},
+ {"(FS).ReadFile", Method, 16},
+ {"FS", Type, 16},
+ },
+ "encoding": {
+ {"BinaryMarshaler", Type, 2},
+ {"BinaryUnmarshaler", Type, 2},
+ {"TextMarshaler", Type, 2},
+ {"TextUnmarshaler", Type, 2},
+ },
+ "encoding/ascii85": {
+ {"(CorruptInputError).Error", Method, 0},
+ {"CorruptInputError", Type, 0},
+ {"Decode", Func, 0},
+ {"Encode", Func, 0},
+ {"MaxEncodedLen", Func, 0},
+ {"NewDecoder", Func, 0},
+ {"NewEncoder", Func, 0},
+ },
+ "encoding/asn1": {
+ {"(BitString).At", Method, 0},
+ {"(BitString).RightAlign", Method, 0},
+ {"(ObjectIdentifier).Equal", Method, 0},
+ {"(ObjectIdentifier).String", Method, 3},
+ {"(StructuralError).Error", Method, 0},
+ {"(SyntaxError).Error", Method, 0},
+ {"BitString", Type, 0},
+ {"BitString.BitLength", Field, 0},
+ {"BitString.Bytes", Field, 0},
+ {"ClassApplication", Const, 6},
+ {"ClassContextSpecific", Const, 6},
+ {"ClassPrivate", Const, 6},
+ {"ClassUniversal", Const, 6},
+ {"Enumerated", Type, 0},
+ {"Flag", Type, 0},
+ {"Marshal", Func, 0},
+ {"MarshalWithParams", Func, 10},
+ {"NullBytes", Var, 9},
+ {"NullRawValue", Var, 9},
+ {"ObjectIdentifier", Type, 0},
+ {"RawContent", Type, 0},
+ {"RawValue", Type, 0},
+ {"RawValue.Bytes", Field, 0},
+ {"RawValue.Class", Field, 0},
+ {"RawValue.FullBytes", Field, 0},
+ {"RawValue.IsCompound", Field, 0},
+ {"RawValue.Tag", Field, 0},
+ {"StructuralError", Type, 0},
+ {"StructuralError.Msg", Field, 0},
+ {"SyntaxError", Type, 0},
+ {"SyntaxError.Msg", Field, 0},
+ {"TagBMPString", Const, 14},
+ {"TagBitString", Const, 6},
+ {"TagBoolean", Const, 6},
+ {"TagEnum", Const, 6},
+ {"TagGeneralString", Const, 6},
+ {"TagGeneralizedTime", Const, 6},
+ {"TagIA5String", Const, 6},
+ {"TagInteger", Const, 6},
+ {"TagNull", Const, 9},
+ {"TagNumericString", Const, 10},
+ {"TagOID", Const, 6},
+ {"TagOctetString", Const, 6},
+ {"TagPrintableString", Const, 6},
+ {"TagSequence", Const, 6},
+ {"TagSet", Const, 6},
+ {"TagT61String", Const, 6},
+ {"TagUTCTime", Const, 6},
+ {"TagUTF8String", Const, 6},
+ {"Unmarshal", Func, 0},
+ {"UnmarshalWithParams", Func, 0},
+ },
+ "encoding/base32": {
+ {"(*Encoding).AppendDecode", Method, 22},
+ {"(*Encoding).AppendEncode", Method, 22},
+ {"(*Encoding).Decode", Method, 0},
+ {"(*Encoding).DecodeString", Method, 0},
+ {"(*Encoding).DecodedLen", Method, 0},
+ {"(*Encoding).Encode", Method, 0},
+ {"(*Encoding).EncodeToString", Method, 0},
+ {"(*Encoding).EncodedLen", Method, 0},
+ {"(CorruptInputError).Error", Method, 0},
+ {"(Encoding).WithPadding", Method, 9},
+ {"CorruptInputError", Type, 0},
+ {"Encoding", Type, 0},
+ {"HexEncoding", Var, 0},
+ {"NewDecoder", Func, 0},
+ {"NewEncoder", Func, 0},
+ {"NewEncoding", Func, 0},
+ {"NoPadding", Const, 9},
+ {"StdEncoding", Var, 0},
+ {"StdPadding", Const, 9},
+ },
+ "encoding/base64": {
+ {"(*Encoding).AppendDecode", Method, 22},
+ {"(*Encoding).AppendEncode", Method, 22},
+ {"(*Encoding).Decode", Method, 0},
+ {"(*Encoding).DecodeString", Method, 0},
+ {"(*Encoding).DecodedLen", Method, 0},
+ {"(*Encoding).Encode", Method, 0},
+ {"(*Encoding).EncodeToString", Method, 0},
+ {"(*Encoding).EncodedLen", Method, 0},
+ {"(CorruptInputError).Error", Method, 0},
+ {"(Encoding).Strict", Method, 8},
+ {"(Encoding).WithPadding", Method, 5},
+ {"CorruptInputError", Type, 0},
+ {"Encoding", Type, 0},
+ {"NewDecoder", Func, 0},
+ {"NewEncoder", Func, 0},
+ {"NewEncoding", Func, 0},
+ {"NoPadding", Const, 5},
+ {"RawStdEncoding", Var, 5},
+ {"RawURLEncoding", Var, 5},
+ {"StdEncoding", Var, 0},
+ {"StdPadding", Const, 5},
+ {"URLEncoding", Var, 0},
+ },
+ "encoding/binary": {
+ {"Append", Func, 23},
+ {"AppendByteOrder", Type, 19},
+ {"AppendUvarint", Func, 19},
+ {"AppendVarint", Func, 19},
+ {"BigEndian", Var, 0},
+ {"ByteOrder", Type, 0},
+ {"Decode", Func, 23},
+ {"Encode", Func, 23},
+ {"LittleEndian", Var, 0},
+ {"MaxVarintLen16", Const, 0},
+ {"MaxVarintLen32", Const, 0},
+ {"MaxVarintLen64", Const, 0},
+ {"NativeEndian", Var, 21},
+ {"PutUvarint", Func, 0},
+ {"PutVarint", Func, 0},
+ {"Read", Func, 0},
+ {"ReadUvarint", Func, 0},
+ {"ReadVarint", Func, 0},
+ {"Size", Func, 0},
+ {"Uvarint", Func, 0},
+ {"Varint", Func, 0},
+ {"Write", Func, 0},
+ },
+ "encoding/csv": {
+ {"(*ParseError).Error", Method, 0},
+ {"(*ParseError).Unwrap", Method, 13},
+ {"(*Reader).FieldPos", Method, 17},
+ {"(*Reader).InputOffset", Method, 19},
+ {"(*Reader).Read", Method, 0},
+ {"(*Reader).ReadAll", Method, 0},
+ {"(*Writer).Error", Method, 1},
+ {"(*Writer).Flush", Method, 0},
+ {"(*Writer).Write", Method, 0},
+ {"(*Writer).WriteAll", Method, 0},
+ {"ErrBareQuote", Var, 0},
+ {"ErrFieldCount", Var, 0},
+ {"ErrQuote", Var, 0},
+ {"ErrTrailingComma", Var, 0},
+ {"NewReader", Func, 0},
+ {"NewWriter", Func, 0},
+ {"ParseError", Type, 0},
+ {"ParseError.Column", Field, 0},
+ {"ParseError.Err", Field, 0},
+ {"ParseError.Line", Field, 0},
+ {"ParseError.StartLine", Field, 10},
+ {"Reader", Type, 0},
+ {"Reader.Comma", Field, 0},
+ {"Reader.Comment", Field, 0},
+ {"Reader.FieldsPerRecord", Field, 0},
+ {"Reader.LazyQuotes", Field, 0},
+ {"Reader.ReuseRecord", Field, 9},
+ {"Reader.TrailingComma", Field, 0},
+ {"Reader.TrimLeadingSpace", Field, 0},
+ {"Writer", Type, 0},
+ {"Writer.Comma", Field, 0},
+ {"Writer.UseCRLF", Field, 0},
+ },
+ "encoding/gob": {
+ {"(*Decoder).Decode", Method, 0},
+ {"(*Decoder).DecodeValue", Method, 0},
+ {"(*Encoder).Encode", Method, 0},
+ {"(*Encoder).EncodeValue", Method, 0},
+ {"CommonType", Type, 0},
+ {"CommonType.Id", Field, 0},
+ {"CommonType.Name", Field, 0},
+ {"Decoder", Type, 0},
+ {"Encoder", Type, 0},
+ {"GobDecoder", Type, 0},
+ {"GobEncoder", Type, 0},
+ {"NewDecoder", Func, 0},
+ {"NewEncoder", Func, 0},
+ {"Register", Func, 0},
+ {"RegisterName", Func, 0},
+ },
+ "encoding/hex": {
+ {"(InvalidByteError).Error", Method, 0},
+ {"AppendDecode", Func, 22},
+ {"AppendEncode", Func, 22},
+ {"Decode", Func, 0},
+ {"DecodeString", Func, 0},
+ {"DecodedLen", Func, 0},
+ {"Dump", Func, 0},
+ {"Dumper", Func, 0},
+ {"Encode", Func, 0},
+ {"EncodeToString", Func, 0},
+ {"EncodedLen", Func, 0},
+ {"ErrLength", Var, 0},
+ {"InvalidByteError", Type, 0},
+ {"NewDecoder", Func, 10},
+ {"NewEncoder", Func, 10},
+ },
+ "encoding/json": {
+ {"(*Decoder).Buffered", Method, 1},
+ {"(*Decoder).Decode", Method, 0},
+ {"(*Decoder).DisallowUnknownFields", Method, 10},
+ {"(*Decoder).InputOffset", Method, 14},
+ {"(*Decoder).More", Method, 5},
+ {"(*Decoder).Token", Method, 5},
+ {"(*Decoder).UseNumber", Method, 1},
+ {"(*Encoder).Encode", Method, 0},
+ {"(*Encoder).SetEscapeHTML", Method, 7},
+ {"(*Encoder).SetIndent", Method, 7},
+ {"(*InvalidUTF8Error).Error", Method, 0},
+ {"(*InvalidUnmarshalError).Error", Method, 0},
+ {"(*MarshalerError).Error", Method, 0},
+ {"(*MarshalerError).Unwrap", Method, 13},
+ {"(*RawMessage).MarshalJSON", Method, 0},
+ {"(*RawMessage).UnmarshalJSON", Method, 0},
+ {"(*SyntaxError).Error", Method, 0},
+ {"(*UnmarshalFieldError).Error", Method, 0},
+ {"(*UnmarshalTypeError).Error", Method, 0},
+ {"(*UnsupportedTypeError).Error", Method, 0},
+ {"(*UnsupportedValueError).Error", Method, 0},
+ {"(Delim).String", Method, 5},
+ {"(Number).Float64", Method, 1},
+ {"(Number).Int64", Method, 1},
+ {"(Number).String", Method, 1},
+ {"(RawMessage).MarshalJSON", Method, 8},
+ {"Compact", Func, 0},
+ {"Decoder", Type, 0},
+ {"Delim", Type, 5},
+ {"Encoder", Type, 0},
+ {"HTMLEscape", Func, 0},
+ {"Indent", Func, 0},
+ {"InvalidUTF8Error", Type, 0},
+ {"InvalidUTF8Error.S", Field, 0},
+ {"InvalidUnmarshalError", Type, 0},
+ {"InvalidUnmarshalError.Type", Field, 0},
+ {"Marshal", Func, 0},
+ {"MarshalIndent", Func, 0},
+ {"Marshaler", Type, 0},
+ {"MarshalerError", Type, 0},
+ {"MarshalerError.Err", Field, 0},
+ {"MarshalerError.Type", Field, 0},
+ {"NewDecoder", Func, 0},
+ {"NewEncoder", Func, 0},
+ {"Number", Type, 1},
+ {"RawMessage", Type, 0},
+ {"SyntaxError", Type, 0},
+ {"SyntaxError.Offset", Field, 0},
+ {"Token", Type, 5},
+ {"Unmarshal", Func, 0},
+ {"UnmarshalFieldError", Type, 0},
+ {"UnmarshalFieldError.Field", Field, 0},
+ {"UnmarshalFieldError.Key", Field, 0},
+ {"UnmarshalFieldError.Type", Field, 0},
+ {"UnmarshalTypeError", Type, 0},
+ {"UnmarshalTypeError.Field", Field, 8},
+ {"UnmarshalTypeError.Offset", Field, 5},
+ {"UnmarshalTypeError.Struct", Field, 8},
+ {"UnmarshalTypeError.Type", Field, 0},
+ {"UnmarshalTypeError.Value", Field, 0},
+ {"Unmarshaler", Type, 0},
+ {"UnsupportedTypeError", Type, 0},
+ {"UnsupportedTypeError.Type", Field, 0},
+ {"UnsupportedValueError", Type, 0},
+ {"UnsupportedValueError.Str", Field, 0},
+ {"UnsupportedValueError.Value", Field, 0},
+ {"Valid", Func, 9},
+ },
+ "encoding/pem": {
+ {"Block", Type, 0},
+ {"Block.Bytes", Field, 0},
+ {"Block.Headers", Field, 0},
+ {"Block.Type", Field, 0},
+ {"Decode", Func, 0},
+ {"Encode", Func, 0},
+ {"EncodeToMemory", Func, 0},
+ },
+ "encoding/xml": {
+ {"(*Decoder).Decode", Method, 0},
+ {"(*Decoder).DecodeElement", Method, 0},
+ {"(*Decoder).InputOffset", Method, 4},
+ {"(*Decoder).InputPos", Method, 19},
+ {"(*Decoder).RawToken", Method, 0},
+ {"(*Decoder).Skip", Method, 0},
+ {"(*Decoder).Token", Method, 0},
+ {"(*Encoder).Close", Method, 20},
+ {"(*Encoder).Encode", Method, 0},
+ {"(*Encoder).EncodeElement", Method, 2},
+ {"(*Encoder).EncodeToken", Method, 2},
+ {"(*Encoder).Flush", Method, 2},
+ {"(*Encoder).Indent", Method, 1},
+ {"(*SyntaxError).Error", Method, 0},
+ {"(*TagPathError).Error", Method, 0},
+ {"(*UnsupportedTypeError).Error", Method, 0},
+ {"(CharData).Copy", Method, 0},
+ {"(Comment).Copy", Method, 0},
+ {"(Directive).Copy", Method, 0},
+ {"(ProcInst).Copy", Method, 0},
+ {"(StartElement).Copy", Method, 0},
+ {"(StartElement).End", Method, 2},
+ {"(UnmarshalError).Error", Method, 0},
+ {"Attr", Type, 0},
+ {"Attr.Name", Field, 0},
+ {"Attr.Value", Field, 0},
+ {"CharData", Type, 0},
+ {"Comment", Type, 0},
+ {"CopyToken", Func, 0},
+ {"Decoder", Type, 0},
+ {"Decoder.AutoClose", Field, 0},
+ {"Decoder.CharsetReader", Field, 0},
+ {"Decoder.DefaultSpace", Field, 1},
+ {"Decoder.Entity", Field, 0},
+ {"Decoder.Strict", Field, 0},
+ {"Directive", Type, 0},
+ {"Encoder", Type, 0},
+ {"EndElement", Type, 0},
+ {"EndElement.Name", Field, 0},
+ {"Escape", Func, 0},
+ {"EscapeText", Func, 1},
+ {"HTMLAutoClose", Var, 0},
+ {"HTMLEntity", Var, 0},
+ {"Header", Const, 0},
+ {"Marshal", Func, 0},
+ {"MarshalIndent", Func, 0},
+ {"Marshaler", Type, 2},
+ {"MarshalerAttr", Type, 2},
+ {"Name", Type, 0},
+ {"Name.Local", Field, 0},
+ {"Name.Space", Field, 0},
+ {"NewDecoder", Func, 0},
+ {"NewEncoder", Func, 0},
+ {"NewTokenDecoder", Func, 10},
+ {"ProcInst", Type, 0},
+ {"ProcInst.Inst", Field, 0},
+ {"ProcInst.Target", Field, 0},
+ {"StartElement", Type, 0},
+ {"StartElement.Attr", Field, 0},
+ {"StartElement.Name", Field, 0},
+ {"SyntaxError", Type, 0},
+ {"SyntaxError.Line", Field, 0},
+ {"SyntaxError.Msg", Field, 0},
+ {"TagPathError", Type, 0},
+ {"TagPathError.Field1", Field, 0},
+ {"TagPathError.Field2", Field, 0},
+ {"TagPathError.Struct", Field, 0},
+ {"TagPathError.Tag1", Field, 0},
+ {"TagPathError.Tag2", Field, 0},
+ {"Token", Type, 0},
+ {"TokenReader", Type, 10},
+ {"Unmarshal", Func, 0},
+ {"UnmarshalError", Type, 0},
+ {"Unmarshaler", Type, 2},
+ {"UnmarshalerAttr", Type, 2},
+ {"UnsupportedTypeError", Type, 0},
+ {"UnsupportedTypeError.Type", Field, 0},
+ },
+ "errors": {
+ {"As", Func, 13},
+ {"ErrUnsupported", Var, 21},
+ {"Is", Func, 13},
+ {"Join", Func, 20},
+ {"New", Func, 0},
+ {"Unwrap", Func, 13},
+ },
+ "expvar": {
+ {"(*Float).Add", Method, 0},
+ {"(*Float).Set", Method, 0},
+ {"(*Float).String", Method, 0},
+ {"(*Float).Value", Method, 8},
+ {"(*Int).Add", Method, 0},
+ {"(*Int).Set", Method, 0},
+ {"(*Int).String", Method, 0},
+ {"(*Int).Value", Method, 8},
+ {"(*Map).Add", Method, 0},
+ {"(*Map).AddFloat", Method, 0},
+ {"(*Map).Delete", Method, 12},
+ {"(*Map).Do", Method, 0},
+ {"(*Map).Get", Method, 0},
+ {"(*Map).Init", Method, 0},
+ {"(*Map).Set", Method, 0},
+ {"(*Map).String", Method, 0},
+ {"(*String).Set", Method, 0},
+ {"(*String).String", Method, 0},
+ {"(*String).Value", Method, 8},
+ {"(Func).String", Method, 0},
+ {"(Func).Value", Method, 8},
+ {"Do", Func, 0},
+ {"Float", Type, 0},
+ {"Func", Type, 0},
+ {"Get", Func, 0},
+ {"Handler", Func, 8},
+ {"Int", Type, 0},
+ {"KeyValue", Type, 0},
+ {"KeyValue.Key", Field, 0},
+ {"KeyValue.Value", Field, 0},
+ {"Map", Type, 0},
+ {"NewFloat", Func, 0},
+ {"NewInt", Func, 0},
+ {"NewMap", Func, 0},
+ {"NewString", Func, 0},
+ {"Publish", Func, 0},
+ {"String", Type, 0},
+ {"Var", Type, 0},
+ },
+ "flag": {
+ {"(*FlagSet).Arg", Method, 0},
+ {"(*FlagSet).Args", Method, 0},
+ {"(*FlagSet).Bool", Method, 0},
+ {"(*FlagSet).BoolFunc", Method, 21},
+ {"(*FlagSet).BoolVar", Method, 0},
+ {"(*FlagSet).Duration", Method, 0},
+ {"(*FlagSet).DurationVar", Method, 0},
+ {"(*FlagSet).ErrorHandling", Method, 10},
+ {"(*FlagSet).Float64", Method, 0},
+ {"(*FlagSet).Float64Var", Method, 0},
+ {"(*FlagSet).Func", Method, 16},
+ {"(*FlagSet).Init", Method, 0},
+ {"(*FlagSet).Int", Method, 0},
+ {"(*FlagSet).Int64", Method, 0},
+ {"(*FlagSet).Int64Var", Method, 0},
+ {"(*FlagSet).IntVar", Method, 0},
+ {"(*FlagSet).Lookup", Method, 0},
+ {"(*FlagSet).NArg", Method, 0},
+ {"(*FlagSet).NFlag", Method, 0},
+ {"(*FlagSet).Name", Method, 10},
+ {"(*FlagSet).Output", Method, 10},
+ {"(*FlagSet).Parse", Method, 0},
+ {"(*FlagSet).Parsed", Method, 0},
+ {"(*FlagSet).PrintDefaults", Method, 0},
+ {"(*FlagSet).Set", Method, 0},
+ {"(*FlagSet).SetOutput", Method, 0},
+ {"(*FlagSet).String", Method, 0},
+ {"(*FlagSet).StringVar", Method, 0},
+ {"(*FlagSet).TextVar", Method, 19},
+ {"(*FlagSet).Uint", Method, 0},
+ {"(*FlagSet).Uint64", Method, 0},
+ {"(*FlagSet).Uint64Var", Method, 0},
+ {"(*FlagSet).UintVar", Method, 0},
+ {"(*FlagSet).Var", Method, 0},
+ {"(*FlagSet).Visit", Method, 0},
+ {"(*FlagSet).VisitAll", Method, 0},
+ {"Arg", Func, 0},
+ {"Args", Func, 0},
+ {"Bool", Func, 0},
+ {"BoolFunc", Func, 21},
+ {"BoolVar", Func, 0},
+ {"CommandLine", Var, 2},
+ {"ContinueOnError", Const, 0},
+ {"Duration", Func, 0},
+ {"DurationVar", Func, 0},
+ {"ErrHelp", Var, 0},
+ {"ErrorHandling", Type, 0},
+ {"ExitOnError", Const, 0},
+ {"Flag", Type, 0},
+ {"Flag.DefValue", Field, 0},
+ {"Flag.Name", Field, 0},
+ {"Flag.Usage", Field, 0},
+ {"Flag.Value", Field, 0},
+ {"FlagSet", Type, 0},
+ {"FlagSet.Usage", Field, 0},
+ {"Float64", Func, 0},
+ {"Float64Var", Func, 0},
+ {"Func", Func, 16},
+ {"Getter", Type, 2},
+ {"Int", Func, 0},
+ {"Int64", Func, 0},
+ {"Int64Var", Func, 0},
+ {"IntVar", Func, 0},
+ {"Lookup", Func, 0},
+ {"NArg", Func, 0},
+ {"NFlag", Func, 0},
+ {"NewFlagSet", Func, 0},
+ {"PanicOnError", Const, 0},
+ {"Parse", Func, 0},
+ {"Parsed", Func, 0},
+ {"PrintDefaults", Func, 0},
+ {"Set", Func, 0},
+ {"String", Func, 0},
+ {"StringVar", Func, 0},
+ {"TextVar", Func, 19},
+ {"Uint", Func, 0},
+ {"Uint64", Func, 0},
+ {"Uint64Var", Func, 0},
+ {"UintVar", Func, 0},
+ {"UnquoteUsage", Func, 5},
+ {"Usage", Var, 0},
+ {"Value", Type, 0},
+ {"Var", Func, 0},
+ {"Visit", Func, 0},
+ {"VisitAll", Func, 0},
+ },
+ "fmt": {
+ {"Append", Func, 19},
+ {"Appendf", Func, 19},
+ {"Appendln", Func, 19},
+ {"Errorf", Func, 0},
+ {"FormatString", Func, 20},
+ {"Formatter", Type, 0},
+ {"Fprint", Func, 0},
+ {"Fprintf", Func, 0},
+ {"Fprintln", Func, 0},
+ {"Fscan", Func, 0},
+ {"Fscanf", Func, 0},
+ {"Fscanln", Func, 0},
+ {"GoStringer", Type, 0},
+ {"Print", Func, 0},
+ {"Printf", Func, 0},
+ {"Println", Func, 0},
+ {"Scan", Func, 0},
+ {"ScanState", Type, 0},
+ {"Scanf", Func, 0},
+ {"Scanln", Func, 0},
+ {"Scanner", Type, 0},
+ {"Sprint", Func, 0},
+ {"Sprintf", Func, 0},
+ {"Sprintln", Func, 0},
+ {"Sscan", Func, 0},
+ {"Sscanf", Func, 0},
+ {"Sscanln", Func, 0},
+ {"State", Type, 0},
+ {"Stringer", Type, 0},
+ },
+ "go/ast": {
+ {"(*ArrayType).End", Method, 0},
+ {"(*ArrayType).Pos", Method, 0},
+ {"(*AssignStmt).End", Method, 0},
+ {"(*AssignStmt).Pos", Method, 0},
+ {"(*BadDecl).End", Method, 0},
+ {"(*BadDecl).Pos", Method, 0},
+ {"(*BadExpr).End", Method, 0},
+ {"(*BadExpr).Pos", Method, 0},
+ {"(*BadStmt).End", Method, 0},
+ {"(*BadStmt).Pos", Method, 0},
+ {"(*BasicLit).End", Method, 0},
+ {"(*BasicLit).Pos", Method, 0},
+ {"(*BinaryExpr).End", Method, 0},
+ {"(*BinaryExpr).Pos", Method, 0},
+ {"(*BlockStmt).End", Method, 0},
+ {"(*BlockStmt).Pos", Method, 0},
+ {"(*BranchStmt).End", Method, 0},
+ {"(*BranchStmt).Pos", Method, 0},
+ {"(*CallExpr).End", Method, 0},
+ {"(*CallExpr).Pos", Method, 0},
+ {"(*CaseClause).End", Method, 0},
+ {"(*CaseClause).Pos", Method, 0},
+ {"(*ChanType).End", Method, 0},
+ {"(*ChanType).Pos", Method, 0},
+ {"(*CommClause).End", Method, 0},
+ {"(*CommClause).Pos", Method, 0},
+ {"(*Comment).End", Method, 0},
+ {"(*Comment).Pos", Method, 0},
+ {"(*CommentGroup).End", Method, 0},
+ {"(*CommentGroup).Pos", Method, 0},
+ {"(*CommentGroup).Text", Method, 0},
+ {"(*CompositeLit).End", Method, 0},
+ {"(*CompositeLit).Pos", Method, 0},
+ {"(*DeclStmt).End", Method, 0},
+ {"(*DeclStmt).Pos", Method, 0},
+ {"(*DeferStmt).End", Method, 0},
+ {"(*DeferStmt).Pos", Method, 0},
+ {"(*Ellipsis).End", Method, 0},
+ {"(*Ellipsis).Pos", Method, 0},
+ {"(*EmptyStmt).End", Method, 0},
+ {"(*EmptyStmt).Pos", Method, 0},
+ {"(*ExprStmt).End", Method, 0},
+ {"(*ExprStmt).Pos", Method, 0},
+ {"(*Field).End", Method, 0},
+ {"(*Field).Pos", Method, 0},
+ {"(*FieldList).End", Method, 0},
+ {"(*FieldList).NumFields", Method, 0},
+ {"(*FieldList).Pos", Method, 0},
+ {"(*File).End", Method, 0},
+ {"(*File).Pos", Method, 0},
+ {"(*ForStmt).End", Method, 0},
+ {"(*ForStmt).Pos", Method, 0},
+ {"(*FuncDecl).End", Method, 0},
+ {"(*FuncDecl).Pos", Method, 0},
+ {"(*FuncLit).End", Method, 0},
+ {"(*FuncLit).Pos", Method, 0},
+ {"(*FuncType).End", Method, 0},
+ {"(*FuncType).Pos", Method, 0},
+ {"(*GenDecl).End", Method, 0},
+ {"(*GenDecl).Pos", Method, 0},
+ {"(*GoStmt).End", Method, 0},
+ {"(*GoStmt).Pos", Method, 0},
+ {"(*Ident).End", Method, 0},
+ {"(*Ident).IsExported", Method, 0},
+ {"(*Ident).Pos", Method, 0},
+ {"(*Ident).String", Method, 0},
+ {"(*IfStmt).End", Method, 0},
+ {"(*IfStmt).Pos", Method, 0},
+ {"(*ImportSpec).End", Method, 0},
+ {"(*ImportSpec).Pos", Method, 0},
+ {"(*IncDecStmt).End", Method, 0},
+ {"(*IncDecStmt).Pos", Method, 0},
+ {"(*IndexExpr).End", Method, 0},
+ {"(*IndexExpr).Pos", Method, 0},
+ {"(*IndexListExpr).End", Method, 18},
+ {"(*IndexListExpr).Pos", Method, 18},
+ {"(*InterfaceType).End", Method, 0},
+ {"(*InterfaceType).Pos", Method, 0},
+ {"(*KeyValueExpr).End", Method, 0},
+ {"(*KeyValueExpr).Pos", Method, 0},
+ {"(*LabeledStmt).End", Method, 0},
+ {"(*LabeledStmt).Pos", Method, 0},
+ {"(*MapType).End", Method, 0},
+ {"(*MapType).Pos", Method, 0},
+ {"(*Object).Pos", Method, 0},
+ {"(*Package).End", Method, 0},
+ {"(*Package).Pos", Method, 0},
+ {"(*ParenExpr).End", Method, 0},
+ {"(*ParenExpr).Pos", Method, 0},
+ {"(*RangeStmt).End", Method, 0},
+ {"(*RangeStmt).Pos", Method, 0},
+ {"(*ReturnStmt).End", Method, 0},
+ {"(*ReturnStmt).Pos", Method, 0},
+ {"(*Scope).Insert", Method, 0},
+ {"(*Scope).Lookup", Method, 0},
+ {"(*Scope).String", Method, 0},
+ {"(*SelectStmt).End", Method, 0},
+ {"(*SelectStmt).Pos", Method, 0},
+ {"(*SelectorExpr).End", Method, 0},
+ {"(*SelectorExpr).Pos", Method, 0},
+ {"(*SendStmt).End", Method, 0},
+ {"(*SendStmt).Pos", Method, 0},
+ {"(*SliceExpr).End", Method, 0},
+ {"(*SliceExpr).Pos", Method, 0},
+ {"(*StarExpr).End", Method, 0},
+ {"(*StarExpr).Pos", Method, 0},
+ {"(*StructType).End", Method, 0},
+ {"(*StructType).Pos", Method, 0},
+ {"(*SwitchStmt).End", Method, 0},
+ {"(*SwitchStmt).Pos", Method, 0},
+ {"(*TypeAssertExpr).End", Method, 0},
+ {"(*TypeAssertExpr).Pos", Method, 0},
+ {"(*TypeSpec).End", Method, 0},
+ {"(*TypeSpec).Pos", Method, 0},
+ {"(*TypeSwitchStmt).End", Method, 0},
+ {"(*TypeSwitchStmt).Pos", Method, 0},
+ {"(*UnaryExpr).End", Method, 0},
+ {"(*UnaryExpr).Pos", Method, 0},
+ {"(*ValueSpec).End", Method, 0},
+ {"(*ValueSpec).Pos", Method, 0},
+ {"(CommentMap).Comments", Method, 1},
+ {"(CommentMap).Filter", Method, 1},
+ {"(CommentMap).String", Method, 1},
+ {"(CommentMap).Update", Method, 1},
+ {"(ObjKind).String", Method, 0},
+ {"ArrayType", Type, 0},
+ {"ArrayType.Elt", Field, 0},
+ {"ArrayType.Lbrack", Field, 0},
+ {"ArrayType.Len", Field, 0},
+ {"AssignStmt", Type, 0},
+ {"AssignStmt.Lhs", Field, 0},
+ {"AssignStmt.Rhs", Field, 0},
+ {"AssignStmt.Tok", Field, 0},
+ {"AssignStmt.TokPos", Field, 0},
+ {"Bad", Const, 0},
+ {"BadDecl", Type, 0},
+ {"BadDecl.From", Field, 0},
+ {"BadDecl.To", Field, 0},
+ {"BadExpr", Type, 0},
+ {"BadExpr.From", Field, 0},
+ {"BadExpr.To", Field, 0},
+ {"BadStmt", Type, 0},
+ {"BadStmt.From", Field, 0},
+ {"BadStmt.To", Field, 0},
+ {"BasicLit", Type, 0},
+ {"BasicLit.Kind", Field, 0},
+ {"BasicLit.Value", Field, 0},
+ {"BasicLit.ValuePos", Field, 0},
+ {"BinaryExpr", Type, 0},
+ {"BinaryExpr.Op", Field, 0},
+ {"BinaryExpr.OpPos", Field, 0},
+ {"BinaryExpr.X", Field, 0},
+ {"BinaryExpr.Y", Field, 0},
+ {"BlockStmt", Type, 0},
+ {"BlockStmt.Lbrace", Field, 0},
+ {"BlockStmt.List", Field, 0},
+ {"BlockStmt.Rbrace", Field, 0},
+ {"BranchStmt", Type, 0},
+ {"BranchStmt.Label", Field, 0},
+ {"BranchStmt.Tok", Field, 0},
+ {"BranchStmt.TokPos", Field, 0},
+ {"CallExpr", Type, 0},
+ {"CallExpr.Args", Field, 0},
+ {"CallExpr.Ellipsis", Field, 0},
+ {"CallExpr.Fun", Field, 0},
+ {"CallExpr.Lparen", Field, 0},
+ {"CallExpr.Rparen", Field, 0},
+ {"CaseClause", Type, 0},
+ {"CaseClause.Body", Field, 0},
+ {"CaseClause.Case", Field, 0},
+ {"CaseClause.Colon", Field, 0},
+ {"CaseClause.List", Field, 0},
+ {"ChanDir", Type, 0},
+ {"ChanType", Type, 0},
+ {"ChanType.Arrow", Field, 1},
+ {"ChanType.Begin", Field, 0},
+ {"ChanType.Dir", Field, 0},
+ {"ChanType.Value", Field, 0},
+ {"CommClause", Type, 0},
+ {"CommClause.Body", Field, 0},
+ {"CommClause.Case", Field, 0},
+ {"CommClause.Colon", Field, 0},
+ {"CommClause.Comm", Field, 0},
+ {"Comment", Type, 0},
+ {"Comment.Slash", Field, 0},
+ {"Comment.Text", Field, 0},
+ {"CommentGroup", Type, 0},
+ {"CommentGroup.List", Field, 0},
+ {"CommentMap", Type, 1},
+ {"CompositeLit", Type, 0},
+ {"CompositeLit.Elts", Field, 0},
+ {"CompositeLit.Incomplete", Field, 11},
+ {"CompositeLit.Lbrace", Field, 0},
+ {"CompositeLit.Rbrace", Field, 0},
+ {"CompositeLit.Type", Field, 0},
+ {"Con", Const, 0},
+ {"Decl", Type, 0},
+ {"DeclStmt", Type, 0},
+ {"DeclStmt.Decl", Field, 0},
+ {"DeferStmt", Type, 0},
+ {"DeferStmt.Call", Field, 0},
+ {"DeferStmt.Defer", Field, 0},
+ {"Ellipsis", Type, 0},
+ {"Ellipsis.Ellipsis", Field, 0},
+ {"Ellipsis.Elt", Field, 0},
+ {"EmptyStmt", Type, 0},
+ {"EmptyStmt.Implicit", Field, 5},
+ {"EmptyStmt.Semicolon", Field, 0},
+ {"Expr", Type, 0},
+ {"ExprStmt", Type, 0},
+ {"ExprStmt.X", Field, 0},
+ {"Field", Type, 0},
+ {"Field.Comment", Field, 0},
+ {"Field.Doc", Field, 0},
+ {"Field.Names", Field, 0},
+ {"Field.Tag", Field, 0},
+ {"Field.Type", Field, 0},
+ {"FieldFilter", Type, 0},
+ {"FieldList", Type, 0},
+ {"FieldList.Closing", Field, 0},
+ {"FieldList.List", Field, 0},
+ {"FieldList.Opening", Field, 0},
+ {"File", Type, 0},
+ {"File.Comments", Field, 0},
+ {"File.Decls", Field, 0},
+ {"File.Doc", Field, 0},
+ {"File.FileEnd", Field, 20},
+ {"File.FileStart", Field, 20},
+ {"File.GoVersion", Field, 21},
+ {"File.Imports", Field, 0},
+ {"File.Name", Field, 0},
+ {"File.Package", Field, 0},
+ {"File.Scope", Field, 0},
+ {"File.Unresolved", Field, 0},
+ {"FileExports", Func, 0},
+ {"Filter", Type, 0},
+ {"FilterDecl", Func, 0},
+ {"FilterFile", Func, 0},
+ {"FilterFuncDuplicates", Const, 0},
+ {"FilterImportDuplicates", Const, 0},
+ {"FilterPackage", Func, 0},
+ {"FilterUnassociatedComments", Const, 0},
+ {"ForStmt", Type, 0},
+ {"ForStmt.Body", Field, 0},
+ {"ForStmt.Cond", Field, 0},
+ {"ForStmt.For", Field, 0},
+ {"ForStmt.Init", Field, 0},
+ {"ForStmt.Post", Field, 0},
+ {"Fprint", Func, 0},
+ {"Fun", Const, 0},
+ {"FuncDecl", Type, 0},
+ {"FuncDecl.Body", Field, 0},
+ {"FuncDecl.Doc", Field, 0},
+ {"FuncDecl.Name", Field, 0},
+ {"FuncDecl.Recv", Field, 0},
+ {"FuncDecl.Type", Field, 0},
+ {"FuncLit", Type, 0},
+ {"FuncLit.Body", Field, 0},
+ {"FuncLit.Type", Field, 0},
+ {"FuncType", Type, 0},
+ {"FuncType.Func", Field, 0},
+ {"FuncType.Params", Field, 0},
+ {"FuncType.Results", Field, 0},
+ {"FuncType.TypeParams", Field, 18},
+ {"GenDecl", Type, 0},
+ {"GenDecl.Doc", Field, 0},
+ {"GenDecl.Lparen", Field, 0},
+ {"GenDecl.Rparen", Field, 0},
+ {"GenDecl.Specs", Field, 0},
+ {"GenDecl.Tok", Field, 0},
+ {"GenDecl.TokPos", Field, 0},
+ {"GoStmt", Type, 0},
+ {"GoStmt.Call", Field, 0},
+ {"GoStmt.Go", Field, 0},
+ {"Ident", Type, 0},
+ {"Ident.Name", Field, 0},
+ {"Ident.NamePos", Field, 0},
+ {"Ident.Obj", Field, 0},
+ {"IfStmt", Type, 0},
+ {"IfStmt.Body", Field, 0},
+ {"IfStmt.Cond", Field, 0},
+ {"IfStmt.Else", Field, 0},
+ {"IfStmt.If", Field, 0},
+ {"IfStmt.Init", Field, 0},
+ {"ImportSpec", Type, 0},
+ {"ImportSpec.Comment", Field, 0},
+ {"ImportSpec.Doc", Field, 0},
+ {"ImportSpec.EndPos", Field, 0},
+ {"ImportSpec.Name", Field, 0},
+ {"ImportSpec.Path", Field, 0},
+ {"Importer", Type, 0},
+ {"IncDecStmt", Type, 0},
+ {"IncDecStmt.Tok", Field, 0},
+ {"IncDecStmt.TokPos", Field, 0},
+ {"IncDecStmt.X", Field, 0},
+ {"IndexExpr", Type, 0},
+ {"IndexExpr.Index", Field, 0},
+ {"IndexExpr.Lbrack", Field, 0},
+ {"IndexExpr.Rbrack", Field, 0},
+ {"IndexExpr.X", Field, 0},
+ {"IndexListExpr", Type, 18},
+ {"IndexListExpr.Indices", Field, 18},
+ {"IndexListExpr.Lbrack", Field, 18},
+ {"IndexListExpr.Rbrack", Field, 18},
+ {"IndexListExpr.X", Field, 18},
+ {"Inspect", Func, 0},
+ {"InterfaceType", Type, 0},
+ {"InterfaceType.Incomplete", Field, 0},
+ {"InterfaceType.Interface", Field, 0},
+ {"InterfaceType.Methods", Field, 0},
+ {"IsExported", Func, 0},
+ {"IsGenerated", Func, 21},
+ {"KeyValueExpr", Type, 0},
+ {"KeyValueExpr.Colon", Field, 0},
+ {"KeyValueExpr.Key", Field, 0},
+ {"KeyValueExpr.Value", Field, 0},
+ {"LabeledStmt", Type, 0},
+ {"LabeledStmt.Colon", Field, 0},
+ {"LabeledStmt.Label", Field, 0},
+ {"LabeledStmt.Stmt", Field, 0},
+ {"Lbl", Const, 0},
+ {"MapType", Type, 0},
+ {"MapType.Key", Field, 0},
+ {"MapType.Map", Field, 0},
+ {"MapType.Value", Field, 0},
+ {"MergeMode", Type, 0},
+ {"MergePackageFiles", Func, 0},
+ {"NewCommentMap", Func, 1},
+ {"NewIdent", Func, 0},
+ {"NewObj", Func, 0},
+ {"NewPackage", Func, 0},
+ {"NewScope", Func, 0},
+ {"Node", Type, 0},
+ {"NotNilFilter", Func, 0},
+ {"ObjKind", Type, 0},
+ {"Object", Type, 0},
+ {"Object.Data", Field, 0},
+ {"Object.Decl", Field, 0},
+ {"Object.Kind", Field, 0},
+ {"Object.Name", Field, 0},
+ {"Object.Type", Field, 0},
+ {"Package", Type, 0},
+ {"Package.Files", Field, 0},
+ {"Package.Imports", Field, 0},
+ {"Package.Name", Field, 0},
+ {"Package.Scope", Field, 0},
+ {"PackageExports", Func, 0},
+ {"ParenExpr", Type, 0},
+ {"ParenExpr.Lparen", Field, 0},
+ {"ParenExpr.Rparen", Field, 0},
+ {"ParenExpr.X", Field, 0},
+ {"Pkg", Const, 0},
+ {"Preorder", Func, 23},
+ {"Print", Func, 0},
+ {"RECV", Const, 0},
+ {"RangeStmt", Type, 0},
+ {"RangeStmt.Body", Field, 0},
+ {"RangeStmt.For", Field, 0},
+ {"RangeStmt.Key", Field, 0},
+ {"RangeStmt.Range", Field, 20},
+ {"RangeStmt.Tok", Field, 0},
+ {"RangeStmt.TokPos", Field, 0},
+ {"RangeStmt.Value", Field, 0},
+ {"RangeStmt.X", Field, 0},
+ {"ReturnStmt", Type, 0},
+ {"ReturnStmt.Results", Field, 0},
+ {"ReturnStmt.Return", Field, 0},
+ {"SEND", Const, 0},
+ {"Scope", Type, 0},
+ {"Scope.Objects", Field, 0},
+ {"Scope.Outer", Field, 0},
+ {"SelectStmt", Type, 0},
+ {"SelectStmt.Body", Field, 0},
+ {"SelectStmt.Select", Field, 0},
+ {"SelectorExpr", Type, 0},
+ {"SelectorExpr.Sel", Field, 0},
+ {"SelectorExpr.X", Field, 0},
+ {"SendStmt", Type, 0},
+ {"SendStmt.Arrow", Field, 0},
+ {"SendStmt.Chan", Field, 0},
+ {"SendStmt.Value", Field, 0},
+ {"SliceExpr", Type, 0},
+ {"SliceExpr.High", Field, 0},
+ {"SliceExpr.Lbrack", Field, 0},
+ {"SliceExpr.Low", Field, 0},
+ {"SliceExpr.Max", Field, 2},
+ {"SliceExpr.Rbrack", Field, 0},
+ {"SliceExpr.Slice3", Field, 2},
+ {"SliceExpr.X", Field, 0},
+ {"SortImports", Func, 0},
+ {"Spec", Type, 0},
+ {"StarExpr", Type, 0},
+ {"StarExpr.Star", Field, 0},
+ {"StarExpr.X", Field, 0},
+ {"Stmt", Type, 0},
+ {"StructType", Type, 0},
+ {"StructType.Fields", Field, 0},
+ {"StructType.Incomplete", Field, 0},
+ {"StructType.Struct", Field, 0},
+ {"SwitchStmt", Type, 0},
+ {"SwitchStmt.Body", Field, 0},
+ {"SwitchStmt.Init", Field, 0},
+ {"SwitchStmt.Switch", Field, 0},
+ {"SwitchStmt.Tag", Field, 0},
+ {"Typ", Const, 0},
+ {"TypeAssertExpr", Type, 0},
+ {"TypeAssertExpr.Lparen", Field, 2},
+ {"TypeAssertExpr.Rparen", Field, 2},
+ {"TypeAssertExpr.Type", Field, 0},
+ {"TypeAssertExpr.X", Field, 0},
+ {"TypeSpec", Type, 0},
+ {"TypeSpec.Assign", Field, 9},
+ {"TypeSpec.Comment", Field, 0},
+ {"TypeSpec.Doc", Field, 0},
+ {"TypeSpec.Name", Field, 0},
+ {"TypeSpec.Type", Field, 0},
+ {"TypeSpec.TypeParams", Field, 18},
+ {"TypeSwitchStmt", Type, 0},
+ {"TypeSwitchStmt.Assign", Field, 0},
+ {"TypeSwitchStmt.Body", Field, 0},
+ {"TypeSwitchStmt.Init", Field, 0},
+ {"TypeSwitchStmt.Switch", Field, 0},
+ {"UnaryExpr", Type, 0},
+ {"UnaryExpr.Op", Field, 0},
+ {"UnaryExpr.OpPos", Field, 0},
+ {"UnaryExpr.X", Field, 0},
+ {"Unparen", Func, 22},
+ {"ValueSpec", Type, 0},
+ {"ValueSpec.Comment", Field, 0},
+ {"ValueSpec.Doc", Field, 0},
+ {"ValueSpec.Names", Field, 0},
+ {"ValueSpec.Type", Field, 0},
+ {"ValueSpec.Values", Field, 0},
+ {"Var", Const, 0},
+ {"Visitor", Type, 0},
+ {"Walk", Func, 0},
+ },
+ "go/build": {
+ {"(*Context).Import", Method, 0},
+ {"(*Context).ImportDir", Method, 0},
+ {"(*Context).MatchFile", Method, 2},
+ {"(*Context).SrcDirs", Method, 0},
+ {"(*MultiplePackageError).Error", Method, 4},
+ {"(*NoGoError).Error", Method, 0},
+ {"(*Package).IsCommand", Method, 0},
+ {"AllowBinary", Const, 0},
+ {"ArchChar", Func, 0},
+ {"Context", Type, 0},
+ {"Context.BuildTags", Field, 0},
+ {"Context.CgoEnabled", Field, 0},
+ {"Context.Compiler", Field, 0},
+ {"Context.Dir", Field, 14},
+ {"Context.GOARCH", Field, 0},
+ {"Context.GOOS", Field, 0},
+ {"Context.GOPATH", Field, 0},
+ {"Context.GOROOT", Field, 0},
+ {"Context.HasSubdir", Field, 0},
+ {"Context.InstallSuffix", Field, 1},
+ {"Context.IsAbsPath", Field, 0},
+ {"Context.IsDir", Field, 0},
+ {"Context.JoinPath", Field, 0},
+ {"Context.OpenFile", Field, 0},
+ {"Context.ReadDir", Field, 0},
+ {"Context.ReleaseTags", Field, 1},
+ {"Context.SplitPathList", Field, 0},
+ {"Context.ToolTags", Field, 17},
+ {"Context.UseAllFiles", Field, 0},
+ {"Default", Var, 0},
+ {"Directive", Type, 21},
+ {"Directive.Pos", Field, 21},
+ {"Directive.Text", Field, 21},
+ {"FindOnly", Const, 0},
+ {"IgnoreVendor", Const, 6},
+ {"Import", Func, 0},
+ {"ImportComment", Const, 4},
+ {"ImportDir", Func, 0},
+ {"ImportMode", Type, 0},
+ {"IsLocalImport", Func, 0},
+ {"MultiplePackageError", Type, 4},
+ {"MultiplePackageError.Dir", Field, 4},
+ {"MultiplePackageError.Files", Field, 4},
+ {"MultiplePackageError.Packages", Field, 4},
+ {"NoGoError", Type, 0},
+ {"NoGoError.Dir", Field, 0},
+ {"Package", Type, 0},
+ {"Package.AllTags", Field, 2},
+ {"Package.BinDir", Field, 0},
+ {"Package.BinaryOnly", Field, 7},
+ {"Package.CFiles", Field, 0},
+ {"Package.CXXFiles", Field, 2},
+ {"Package.CgoCFLAGS", Field, 0},
+ {"Package.CgoCPPFLAGS", Field, 2},
+ {"Package.CgoCXXFLAGS", Field, 2},
+ {"Package.CgoFFLAGS", Field, 7},
+ {"Package.CgoFiles", Field, 0},
+ {"Package.CgoLDFLAGS", Field, 0},
+ {"Package.CgoPkgConfig", Field, 0},
+ {"Package.ConflictDir", Field, 2},
+ {"Package.Dir", Field, 0},
+ {"Package.Directives", Field, 21},
+ {"Package.Doc", Field, 0},
+ {"Package.EmbedPatternPos", Field, 16},
+ {"Package.EmbedPatterns", Field, 16},
+ {"Package.FFiles", Field, 7},
+ {"Package.GoFiles", Field, 0},
+ {"Package.Goroot", Field, 0},
+ {"Package.HFiles", Field, 0},
+ {"Package.IgnoredGoFiles", Field, 1},
+ {"Package.IgnoredOtherFiles", Field, 16},
+ {"Package.ImportComment", Field, 4},
+ {"Package.ImportPath", Field, 0},
+ {"Package.ImportPos", Field, 0},
+ {"Package.Imports", Field, 0},
+ {"Package.InvalidGoFiles", Field, 6},
+ {"Package.MFiles", Field, 3},
+ {"Package.Name", Field, 0},
+ {"Package.PkgObj", Field, 0},
+ {"Package.PkgRoot", Field, 0},
+ {"Package.PkgTargetRoot", Field, 5},
+ {"Package.Root", Field, 0},
+ {"Package.SFiles", Field, 0},
+ {"Package.SrcRoot", Field, 0},
+ {"Package.SwigCXXFiles", Field, 1},
+ {"Package.SwigFiles", Field, 1},
+ {"Package.SysoFiles", Field, 0},
+ {"Package.TestDirectives", Field, 21},
+ {"Package.TestEmbedPatternPos", Field, 16},
+ {"Package.TestEmbedPatterns", Field, 16},
+ {"Package.TestGoFiles", Field, 0},
+ {"Package.TestImportPos", Field, 0},
+ {"Package.TestImports", Field, 0},
+ {"Package.XTestDirectives", Field, 21},
+ {"Package.XTestEmbedPatternPos", Field, 16},
+ {"Package.XTestEmbedPatterns", Field, 16},
+ {"Package.XTestGoFiles", Field, 0},
+ {"Package.XTestImportPos", Field, 0},
+ {"Package.XTestImports", Field, 0},
+ {"ToolDir", Var, 0},
+ },
+ "go/build/constraint": {
+ {"(*AndExpr).Eval", Method, 16},
+ {"(*AndExpr).String", Method, 16},
+ {"(*NotExpr).Eval", Method, 16},
+ {"(*NotExpr).String", Method, 16},
+ {"(*OrExpr).Eval", Method, 16},
+ {"(*OrExpr).String", Method, 16},
+ {"(*SyntaxError).Error", Method, 16},
+ {"(*TagExpr).Eval", Method, 16},
+ {"(*TagExpr).String", Method, 16},
+ {"AndExpr", Type, 16},
+ {"AndExpr.X", Field, 16},
+ {"AndExpr.Y", Field, 16},
+ {"Expr", Type, 16},
+ {"GoVersion", Func, 21},
+ {"IsGoBuild", Func, 16},
+ {"IsPlusBuild", Func, 16},
+ {"NotExpr", Type, 16},
+ {"NotExpr.X", Field, 16},
+ {"OrExpr", Type, 16},
+ {"OrExpr.X", Field, 16},
+ {"OrExpr.Y", Field, 16},
+ {"Parse", Func, 16},
+ {"PlusBuildLines", Func, 16},
+ {"SyntaxError", Type, 16},
+ {"SyntaxError.Err", Field, 16},
+ {"SyntaxError.Offset", Field, 16},
+ {"TagExpr", Type, 16},
+ {"TagExpr.Tag", Field, 16},
+ },
+ "go/constant": {
+ {"(Kind).String", Method, 18},
+ {"BinaryOp", Func, 5},
+ {"BitLen", Func, 5},
+ {"Bool", Const, 5},
+ {"BoolVal", Func, 5},
+ {"Bytes", Func, 5},
+ {"Compare", Func, 5},
+ {"Complex", Const, 5},
+ {"Denom", Func, 5},
+ {"Float", Const, 5},
+ {"Float32Val", Func, 5},
+ {"Float64Val", Func, 5},
+ {"Imag", Func, 5},
+ {"Int", Const, 5},
+ {"Int64Val", Func, 5},
+ {"Kind", Type, 5},
+ {"Make", Func, 13},
+ {"MakeBool", Func, 5},
+ {"MakeFloat64", Func, 5},
+ {"MakeFromBytes", Func, 5},
+ {"MakeFromLiteral", Func, 5},
+ {"MakeImag", Func, 5},
+ {"MakeInt64", Func, 5},
+ {"MakeString", Func, 5},
+ {"MakeUint64", Func, 5},
+ {"MakeUnknown", Func, 5},
+ {"Num", Func, 5},
+ {"Real", Func, 5},
+ {"Shift", Func, 5},
+ {"Sign", Func, 5},
+ {"String", Const, 5},
+ {"StringVal", Func, 5},
+ {"ToComplex", Func, 6},
+ {"ToFloat", Func, 6},
+ {"ToInt", Func, 6},
+ {"Uint64Val", Func, 5},
+ {"UnaryOp", Func, 5},
+ {"Unknown", Const, 5},
+ {"Val", Func, 13},
+ {"Value", Type, 5},
+ },
+ "go/doc": {
+ {"(*Package).Filter", Method, 0},
+ {"(*Package).HTML", Method, 19},
+ {"(*Package).Markdown", Method, 19},
+ {"(*Package).Parser", Method, 19},
+ {"(*Package).Printer", Method, 19},
+ {"(*Package).Synopsis", Method, 19},
+ {"(*Package).Text", Method, 19},
+ {"AllDecls", Const, 0},
+ {"AllMethods", Const, 0},
+ {"Example", Type, 0},
+ {"Example.Code", Field, 0},
+ {"Example.Comments", Field, 0},
+ {"Example.Doc", Field, 0},
+ {"Example.EmptyOutput", Field, 1},
+ {"Example.Name", Field, 0},
+ {"Example.Order", Field, 1},
+ {"Example.Output", Field, 0},
+ {"Example.Play", Field, 1},
+ {"Example.Suffix", Field, 14},
+ {"Example.Unordered", Field, 7},
+ {"Examples", Func, 0},
+ {"Filter", Type, 0},
+ {"Func", Type, 0},
+ {"Func.Decl", Field, 0},
+ {"Func.Doc", Field, 0},
+ {"Func.Examples", Field, 14},
+ {"Func.Level", Field, 0},
+ {"Func.Name", Field, 0},
+ {"Func.Orig", Field, 0},
+ {"Func.Recv", Field, 0},
+ {"IllegalPrefixes", Var, 1},
+ {"IsPredeclared", Func, 8},
+ {"Mode", Type, 0},
+ {"New", Func, 0},
+ {"NewFromFiles", Func, 14},
+ {"Note", Type, 1},
+ {"Note.Body", Field, 1},
+ {"Note.End", Field, 1},
+ {"Note.Pos", Field, 1},
+ {"Note.UID", Field, 1},
+ {"Package", Type, 0},
+ {"Package.Bugs", Field, 0},
+ {"Package.Consts", Field, 0},
+ {"Package.Doc", Field, 0},
+ {"Package.Examples", Field, 14},
+ {"Package.Filenames", Field, 0},
+ {"Package.Funcs", Field, 0},
+ {"Package.ImportPath", Field, 0},
+ {"Package.Imports", Field, 0},
+ {"Package.Name", Field, 0},
+ {"Package.Notes", Field, 1},
+ {"Package.Types", Field, 0},
+ {"Package.Vars", Field, 0},
+ {"PreserveAST", Const, 12},
+ {"Synopsis", Func, 0},
+ {"ToHTML", Func, 0},
+ {"ToText", Func, 0},
+ {"Type", Type, 0},
+ {"Type.Consts", Field, 0},
+ {"Type.Decl", Field, 0},
+ {"Type.Doc", Field, 0},
+ {"Type.Examples", Field, 14},
+ {"Type.Funcs", Field, 0},
+ {"Type.Methods", Field, 0},
+ {"Type.Name", Field, 0},
+ {"Type.Vars", Field, 0},
+ {"Value", Type, 0},
+ {"Value.Decl", Field, 0},
+ {"Value.Doc", Field, 0},
+ {"Value.Names", Field, 0},
+ },
+ "go/doc/comment": {
+ {"(*DocLink).DefaultURL", Method, 19},
+ {"(*Heading).DefaultID", Method, 19},
+ {"(*List).BlankBefore", Method, 19},
+ {"(*List).BlankBetween", Method, 19},
+ {"(*Parser).Parse", Method, 19},
+ {"(*Printer).Comment", Method, 19},
+ {"(*Printer).HTML", Method, 19},
+ {"(*Printer).Markdown", Method, 19},
+ {"(*Printer).Text", Method, 19},
+ {"Block", Type, 19},
+ {"Code", Type, 19},
+ {"Code.Text", Field, 19},
+ {"DefaultLookupPackage", Func, 19},
+ {"Doc", Type, 19},
+ {"Doc.Content", Field, 19},
+ {"Doc.Links", Field, 19},
+ {"DocLink", Type, 19},
+ {"DocLink.ImportPath", Field, 19},
+ {"DocLink.Name", Field, 19},
+ {"DocLink.Recv", Field, 19},
+ {"DocLink.Text", Field, 19},
+ {"Heading", Type, 19},
+ {"Heading.Text", Field, 19},
+ {"Italic", Type, 19},
+ {"Link", Type, 19},
+ {"Link.Auto", Field, 19},
+ {"Link.Text", Field, 19},
+ {"Link.URL", Field, 19},
+ {"LinkDef", Type, 19},
+ {"LinkDef.Text", Field, 19},
+ {"LinkDef.URL", Field, 19},
+ {"LinkDef.Used", Field, 19},
+ {"List", Type, 19},
+ {"List.ForceBlankBefore", Field, 19},
+ {"List.ForceBlankBetween", Field, 19},
+ {"List.Items", Field, 19},
+ {"ListItem", Type, 19},
+ {"ListItem.Content", Field, 19},
+ {"ListItem.Number", Field, 19},
+ {"Paragraph", Type, 19},
+ {"Paragraph.Text", Field, 19},
+ {"Parser", Type, 19},
+ {"Parser.LookupPackage", Field, 19},
+ {"Parser.LookupSym", Field, 19},
+ {"Parser.Words", Field, 19},
+ {"Plain", Type, 19},
+ {"Printer", Type, 19},
+ {"Printer.DocLinkBaseURL", Field, 19},
+ {"Printer.DocLinkURL", Field, 19},
+ {"Printer.HeadingID", Field, 19},
+ {"Printer.HeadingLevel", Field, 19},
+ {"Printer.TextCodePrefix", Field, 19},
+ {"Printer.TextPrefix", Field, 19},
+ {"Printer.TextWidth", Field, 19},
+ {"Text", Type, 19},
+ },
+ "go/format": {
+ {"Node", Func, 1},
+ {"Source", Func, 1},
+ },
+ "go/importer": {
+ {"Default", Func, 5},
+ {"For", Func, 5},
+ {"ForCompiler", Func, 12},
+ {"Lookup", Type, 5},
+ },
+ "go/parser": {
+ {"AllErrors", Const, 1},
+ {"DeclarationErrors", Const, 0},
+ {"ImportsOnly", Const, 0},
+ {"Mode", Type, 0},
+ {"PackageClauseOnly", Const, 0},
+ {"ParseComments", Const, 0},
+ {"ParseDir", Func, 0},
+ {"ParseExpr", Func, 0},
+ {"ParseExprFrom", Func, 5},
+ {"ParseFile", Func, 0},
+ {"SkipObjectResolution", Const, 17},
+ {"SpuriousErrors", Const, 0},
+ {"Trace", Const, 0},
+ },
+ "go/printer": {
+ {"(*Config).Fprint", Method, 0},
+ {"CommentedNode", Type, 0},
+ {"CommentedNode.Comments", Field, 0},
+ {"CommentedNode.Node", Field, 0},
+ {"Config", Type, 0},
+ {"Config.Indent", Field, 1},
+ {"Config.Mode", Field, 0},
+ {"Config.Tabwidth", Field, 0},
+ {"Fprint", Func, 0},
+ {"Mode", Type, 0},
+ {"RawFormat", Const, 0},
+ {"SourcePos", Const, 0},
+ {"TabIndent", Const, 0},
+ {"UseSpaces", Const, 0},
+ },
+ "go/scanner": {
+ {"(*ErrorList).Add", Method, 0},
+ {"(*ErrorList).RemoveMultiples", Method, 0},
+ {"(*ErrorList).Reset", Method, 0},
+ {"(*Scanner).Init", Method, 0},
+ {"(*Scanner).Scan", Method, 0},
+ {"(Error).Error", Method, 0},
+ {"(ErrorList).Err", Method, 0},
+ {"(ErrorList).Error", Method, 0},
+ {"(ErrorList).Len", Method, 0},
+ {"(ErrorList).Less", Method, 0},
+ {"(ErrorList).Sort", Method, 0},
+ {"(ErrorList).Swap", Method, 0},
+ {"Error", Type, 0},
+ {"Error.Msg", Field, 0},
+ {"Error.Pos", Field, 0},
+ {"ErrorHandler", Type, 0},
+ {"ErrorList", Type, 0},
+ {"Mode", Type, 0},
+ {"PrintError", Func, 0},
+ {"ScanComments", Const, 0},
+ {"Scanner", Type, 0},
+ {"Scanner.ErrorCount", Field, 0},
+ },
+ "go/token": {
+ {"(*File).AddLine", Method, 0},
+ {"(*File).AddLineColumnInfo", Method, 11},
+ {"(*File).AddLineInfo", Method, 0},
+ {"(*File).Base", Method, 0},
+ {"(*File).Line", Method, 0},
+ {"(*File).LineCount", Method, 0},
+ {"(*File).LineStart", Method, 12},
+ {"(*File).Lines", Method, 21},
+ {"(*File).MergeLine", Method, 2},
+ {"(*File).Name", Method, 0},
+ {"(*File).Offset", Method, 0},
+ {"(*File).Pos", Method, 0},
+ {"(*File).Position", Method, 0},
+ {"(*File).PositionFor", Method, 4},
+ {"(*File).SetLines", Method, 0},
+ {"(*File).SetLinesForContent", Method, 0},
+ {"(*File).Size", Method, 0},
+ {"(*FileSet).AddFile", Method, 0},
+ {"(*FileSet).Base", Method, 0},
+ {"(*FileSet).File", Method, 0},
+ {"(*FileSet).Iterate", Method, 0},
+ {"(*FileSet).Position", Method, 0},
+ {"(*FileSet).PositionFor", Method, 4},
+ {"(*FileSet).Read", Method, 0},
+ {"(*FileSet).RemoveFile", Method, 20},
+ {"(*FileSet).Write", Method, 0},
+ {"(*Position).IsValid", Method, 0},
+ {"(Pos).IsValid", Method, 0},
+ {"(Position).String", Method, 0},
+ {"(Token).IsKeyword", Method, 0},
+ {"(Token).IsLiteral", Method, 0},
+ {"(Token).IsOperator", Method, 0},
+ {"(Token).Precedence", Method, 0},
+ {"(Token).String", Method, 0},
+ {"ADD", Const, 0},
+ {"ADD_ASSIGN", Const, 0},
+ {"AND", Const, 0},
+ {"AND_ASSIGN", Const, 0},
+ {"AND_NOT", Const, 0},
+ {"AND_NOT_ASSIGN", Const, 0},
+ {"ARROW", Const, 0},
+ {"ASSIGN", Const, 0},
+ {"BREAK", Const, 0},
+ {"CASE", Const, 0},
+ {"CHAN", Const, 0},
+ {"CHAR", Const, 0},
+ {"COLON", Const, 0},
+ {"COMMA", Const, 0},
+ {"COMMENT", Const, 0},
+ {"CONST", Const, 0},
+ {"CONTINUE", Const, 0},
+ {"DEC", Const, 0},
+ {"DEFAULT", Const, 0},
+ {"DEFER", Const, 0},
+ {"DEFINE", Const, 0},
+ {"ELLIPSIS", Const, 0},
+ {"ELSE", Const, 0},
+ {"EOF", Const, 0},
+ {"EQL", Const, 0},
+ {"FALLTHROUGH", Const, 0},
+ {"FLOAT", Const, 0},
+ {"FOR", Const, 0},
+ {"FUNC", Const, 0},
+ {"File", Type, 0},
+ {"FileSet", Type, 0},
+ {"GEQ", Const, 0},
+ {"GO", Const, 0},
+ {"GOTO", Const, 0},
+ {"GTR", Const, 0},
+ {"HighestPrec", Const, 0},
+ {"IDENT", Const, 0},
+ {"IF", Const, 0},
+ {"ILLEGAL", Const, 0},
+ {"IMAG", Const, 0},
+ {"IMPORT", Const, 0},
+ {"INC", Const, 0},
+ {"INT", Const, 0},
+ {"INTERFACE", Const, 0},
+ {"IsExported", Func, 13},
+ {"IsIdentifier", Func, 13},
+ {"IsKeyword", Func, 13},
+ {"LAND", Const, 0},
+ {"LBRACE", Const, 0},
+ {"LBRACK", Const, 0},
+ {"LEQ", Const, 0},
+ {"LOR", Const, 0},
+ {"LPAREN", Const, 0},
+ {"LSS", Const, 0},
+ {"Lookup", Func, 0},
+ {"LowestPrec", Const, 0},
+ {"MAP", Const, 0},
+ {"MUL", Const, 0},
+ {"MUL_ASSIGN", Const, 0},
+ {"NEQ", Const, 0},
+ {"NOT", Const, 0},
+ {"NewFileSet", Func, 0},
+ {"NoPos", Const, 0},
+ {"OR", Const, 0},
+ {"OR_ASSIGN", Const, 0},
+ {"PACKAGE", Const, 0},
+ {"PERIOD", Const, 0},
+ {"Pos", Type, 0},
+ {"Position", Type, 0},
+ {"Position.Column", Field, 0},
+ {"Position.Filename", Field, 0},
+ {"Position.Line", Field, 0},
+ {"Position.Offset", Field, 0},
+ {"QUO", Const, 0},
+ {"QUO_ASSIGN", Const, 0},
+ {"RANGE", Const, 0},
+ {"RBRACE", Const, 0},
+ {"RBRACK", Const, 0},
+ {"REM", Const, 0},
+ {"REM_ASSIGN", Const, 0},
+ {"RETURN", Const, 0},
+ {"RPAREN", Const, 0},
+ {"SELECT", Const, 0},
+ {"SEMICOLON", Const, 0},
+ {"SHL", Const, 0},
+ {"SHL_ASSIGN", Const, 0},
+ {"SHR", Const, 0},
+ {"SHR_ASSIGN", Const, 0},
+ {"STRING", Const, 0},
+ {"STRUCT", Const, 0},
+ {"SUB", Const, 0},
+ {"SUB_ASSIGN", Const, 0},
+ {"SWITCH", Const, 0},
+ {"TILDE", Const, 18},
+ {"TYPE", Const, 0},
+ {"Token", Type, 0},
+ {"UnaryPrec", Const, 0},
+ {"VAR", Const, 0},
+ {"XOR", Const, 0},
+ {"XOR_ASSIGN", Const, 0},
+ },
+ "go/types": {
+ {"(*Alias).Obj", Method, 22},
+ {"(*Alias).Origin", Method, 23},
+ {"(*Alias).Rhs", Method, 23},
+ {"(*Alias).SetTypeParams", Method, 23},
+ {"(*Alias).String", Method, 22},
+ {"(*Alias).TypeArgs", Method, 23},
+ {"(*Alias).TypeParams", Method, 23},
+ {"(*Alias).Underlying", Method, 22},
+ {"(*ArgumentError).Error", Method, 18},
+ {"(*ArgumentError).Unwrap", Method, 18},
+ {"(*Array).Elem", Method, 5},
+ {"(*Array).Len", Method, 5},
+ {"(*Array).String", Method, 5},
+ {"(*Array).Underlying", Method, 5},
+ {"(*Basic).Info", Method, 5},
+ {"(*Basic).Kind", Method, 5},
+ {"(*Basic).Name", Method, 5},
+ {"(*Basic).String", Method, 5},
+ {"(*Basic).Underlying", Method, 5},
+ {"(*Builtin).Exported", Method, 5},
+ {"(*Builtin).Id", Method, 5},
+ {"(*Builtin).Name", Method, 5},
+ {"(*Builtin).Parent", Method, 5},
+ {"(*Builtin).Pkg", Method, 5},
+ {"(*Builtin).Pos", Method, 5},
+ {"(*Builtin).String", Method, 5},
+ {"(*Builtin).Type", Method, 5},
+ {"(*Chan).Dir", Method, 5},
+ {"(*Chan).Elem", Method, 5},
+ {"(*Chan).String", Method, 5},
+ {"(*Chan).Underlying", Method, 5},
+ {"(*Checker).Files", Method, 5},
+ {"(*Config).Check", Method, 5},
+ {"(*Const).Exported", Method, 5},
+ {"(*Const).Id", Method, 5},
+ {"(*Const).Name", Method, 5},
+ {"(*Const).Parent", Method, 5},
+ {"(*Const).Pkg", Method, 5},
+ {"(*Const).Pos", Method, 5},
+ {"(*Const).String", Method, 5},
+ {"(*Const).Type", Method, 5},
+ {"(*Const).Val", Method, 5},
+ {"(*Func).Exported", Method, 5},
+ {"(*Func).FullName", Method, 5},
+ {"(*Func).Id", Method, 5},
+ {"(*Func).Name", Method, 5},
+ {"(*Func).Origin", Method, 19},
+ {"(*Func).Parent", Method, 5},
+ {"(*Func).Pkg", Method, 5},
+ {"(*Func).Pos", Method, 5},
+ {"(*Func).Scope", Method, 5},
+ {"(*Func).Signature", Method, 23},
+ {"(*Func).String", Method, 5},
+ {"(*Func).Type", Method, 5},
+ {"(*Info).ObjectOf", Method, 5},
+ {"(*Info).PkgNameOf", Method, 22},
+ {"(*Info).TypeOf", Method, 5},
+ {"(*Initializer).String", Method, 5},
+ {"(*Interface).Complete", Method, 5},
+ {"(*Interface).Embedded", Method, 5},
+ {"(*Interface).EmbeddedType", Method, 11},
+ {"(*Interface).Empty", Method, 5},
+ {"(*Interface).ExplicitMethod", Method, 5},
+ {"(*Interface).IsComparable", Method, 18},
+ {"(*Interface).IsImplicit", Method, 18},
+ {"(*Interface).IsMethodSet", Method, 18},
+ {"(*Interface).MarkImplicit", Method, 18},
+ {"(*Interface).Method", Method, 5},
+ {"(*Interface).NumEmbeddeds", Method, 5},
+ {"(*Interface).NumExplicitMethods", Method, 5},
+ {"(*Interface).NumMethods", Method, 5},
+ {"(*Interface).String", Method, 5},
+ {"(*Interface).Underlying", Method, 5},
+ {"(*Label).Exported", Method, 5},
+ {"(*Label).Id", Method, 5},
+ {"(*Label).Name", Method, 5},
+ {"(*Label).Parent", Method, 5},
+ {"(*Label).Pkg", Method, 5},
+ {"(*Label).Pos", Method, 5},
+ {"(*Label).String", Method, 5},
+ {"(*Label).Type", Method, 5},
+ {"(*Map).Elem", Method, 5},
+ {"(*Map).Key", Method, 5},
+ {"(*Map).String", Method, 5},
+ {"(*Map).Underlying", Method, 5},
+ {"(*MethodSet).At", Method, 5},
+ {"(*MethodSet).Len", Method, 5},
+ {"(*MethodSet).Lookup", Method, 5},
+ {"(*MethodSet).String", Method, 5},
+ {"(*Named).AddMethod", Method, 5},
+ {"(*Named).Method", Method, 5},
+ {"(*Named).NumMethods", Method, 5},
+ {"(*Named).Obj", Method, 5},
+ {"(*Named).Origin", Method, 18},
+ {"(*Named).SetTypeParams", Method, 18},
+ {"(*Named).SetUnderlying", Method, 5},
+ {"(*Named).String", Method, 5},
+ {"(*Named).TypeArgs", Method, 18},
+ {"(*Named).TypeParams", Method, 18},
+ {"(*Named).Underlying", Method, 5},
+ {"(*Nil).Exported", Method, 5},
+ {"(*Nil).Id", Method, 5},
+ {"(*Nil).Name", Method, 5},
+ {"(*Nil).Parent", Method, 5},
+ {"(*Nil).Pkg", Method, 5},
+ {"(*Nil).Pos", Method, 5},
+ {"(*Nil).String", Method, 5},
+ {"(*Nil).Type", Method, 5},
+ {"(*Package).Complete", Method, 5},
+ {"(*Package).GoVersion", Method, 21},
+ {"(*Package).Imports", Method, 5},
+ {"(*Package).MarkComplete", Method, 5},
+ {"(*Package).Name", Method, 5},
+ {"(*Package).Path", Method, 5},
+ {"(*Package).Scope", Method, 5},
+ {"(*Package).SetImports", Method, 5},
+ {"(*Package).SetName", Method, 6},
+ {"(*Package).String", Method, 5},
+ {"(*PkgName).Exported", Method, 5},
+ {"(*PkgName).Id", Method, 5},
+ {"(*PkgName).Imported", Method, 5},
+ {"(*PkgName).Name", Method, 5},
+ {"(*PkgName).Parent", Method, 5},
+ {"(*PkgName).Pkg", Method, 5},
+ {"(*PkgName).Pos", Method, 5},
+ {"(*PkgName).String", Method, 5},
+ {"(*PkgName).Type", Method, 5},
+ {"(*Pointer).Elem", Method, 5},
+ {"(*Pointer).String", Method, 5},
+ {"(*Pointer).Underlying", Method, 5},
+ {"(*Scope).Child", Method, 5},
+ {"(*Scope).Contains", Method, 5},
+ {"(*Scope).End", Method, 5},
+ {"(*Scope).Innermost", Method, 5},
+ {"(*Scope).Insert", Method, 5},
+ {"(*Scope).Len", Method, 5},
+ {"(*Scope).Lookup", Method, 5},
+ {"(*Scope).LookupParent", Method, 5},
+ {"(*Scope).Names", Method, 5},
+ {"(*Scope).NumChildren", Method, 5},
+ {"(*Scope).Parent", Method, 5},
+ {"(*Scope).Pos", Method, 5},
+ {"(*Scope).String", Method, 5},
+ {"(*Scope).WriteTo", Method, 5},
+ {"(*Selection).Index", Method, 5},
+ {"(*Selection).Indirect", Method, 5},
+ {"(*Selection).Kind", Method, 5},
+ {"(*Selection).Obj", Method, 5},
+ {"(*Selection).Recv", Method, 5},
+ {"(*Selection).String", Method, 5},
+ {"(*Selection).Type", Method, 5},
+ {"(*Signature).Params", Method, 5},
+ {"(*Signature).Recv", Method, 5},
+ {"(*Signature).RecvTypeParams", Method, 18},
+ {"(*Signature).Results", Method, 5},
+ {"(*Signature).String", Method, 5},
+ {"(*Signature).TypeParams", Method, 18},
+ {"(*Signature).Underlying", Method, 5},
+ {"(*Signature).Variadic", Method, 5},
+ {"(*Slice).Elem", Method, 5},
+ {"(*Slice).String", Method, 5},
+ {"(*Slice).Underlying", Method, 5},
+ {"(*StdSizes).Alignof", Method, 5},
+ {"(*StdSizes).Offsetsof", Method, 5},
+ {"(*StdSizes).Sizeof", Method, 5},
+ {"(*Struct).Field", Method, 5},
+ {"(*Struct).NumFields", Method, 5},
+ {"(*Struct).String", Method, 5},
+ {"(*Struct).Tag", Method, 5},
+ {"(*Struct).Underlying", Method, 5},
+ {"(*Term).String", Method, 18},
+ {"(*Term).Tilde", Method, 18},
+ {"(*Term).Type", Method, 18},
+ {"(*Tuple).At", Method, 5},
+ {"(*Tuple).Len", Method, 5},
+ {"(*Tuple).String", Method, 5},
+ {"(*Tuple).Underlying", Method, 5},
+ {"(*TypeList).At", Method, 18},
+ {"(*TypeList).Len", Method, 18},
+ {"(*TypeName).Exported", Method, 5},
+ {"(*TypeName).Id", Method, 5},
+ {"(*TypeName).IsAlias", Method, 9},
+ {"(*TypeName).Name", Method, 5},
+ {"(*TypeName).Parent", Method, 5},
+ {"(*TypeName).Pkg", Method, 5},
+ {"(*TypeName).Pos", Method, 5},
+ {"(*TypeName).String", Method, 5},
+ {"(*TypeName).Type", Method, 5},
+ {"(*TypeParam).Constraint", Method, 18},
+ {"(*TypeParam).Index", Method, 18},
+ {"(*TypeParam).Obj", Method, 18},
+ {"(*TypeParam).SetConstraint", Method, 18},
+ {"(*TypeParam).String", Method, 18},
+ {"(*TypeParam).Underlying", Method, 18},
+ {"(*TypeParamList).At", Method, 18},
+ {"(*TypeParamList).Len", Method, 18},
+ {"(*Union).Len", Method, 18},
+ {"(*Union).String", Method, 18},
+ {"(*Union).Term", Method, 18},
+ {"(*Union).Underlying", Method, 18},
+ {"(*Var).Anonymous", Method, 5},
+ {"(*Var).Embedded", Method, 11},
+ {"(*Var).Exported", Method, 5},
+ {"(*Var).Id", Method, 5},
+ {"(*Var).IsField", Method, 5},
+ {"(*Var).Name", Method, 5},
+ {"(*Var).Origin", Method, 19},
+ {"(*Var).Parent", Method, 5},
+ {"(*Var).Pkg", Method, 5},
+ {"(*Var).Pos", Method, 5},
+ {"(*Var).String", Method, 5},
+ {"(*Var).Type", Method, 5},
+ {"(Checker).ObjectOf", Method, 5},
+ {"(Checker).PkgNameOf", Method, 22},
+ {"(Checker).TypeOf", Method, 5},
+ {"(Error).Error", Method, 5},
+ {"(TypeAndValue).Addressable", Method, 5},
+ {"(TypeAndValue).Assignable", Method, 5},
+ {"(TypeAndValue).HasOk", Method, 5},
+ {"(TypeAndValue).IsBuiltin", Method, 5},
+ {"(TypeAndValue).IsNil", Method, 5},
+ {"(TypeAndValue).IsType", Method, 5},
+ {"(TypeAndValue).IsValue", Method, 5},
+ {"(TypeAndValue).IsVoid", Method, 5},
+ {"Alias", Type, 22},
+ {"ArgumentError", Type, 18},
+ {"ArgumentError.Err", Field, 18},
+ {"ArgumentError.Index", Field, 18},
+ {"Array", Type, 5},
+ {"AssertableTo", Func, 5},
+ {"AssignableTo", Func, 5},
+ {"Basic", Type, 5},
+ {"BasicInfo", Type, 5},
+ {"BasicKind", Type, 5},
+ {"Bool", Const, 5},
+ {"Builtin", Type, 5},
+ {"Byte", Const, 5},
+ {"Chan", Type, 5},
+ {"ChanDir", Type, 5},
+ {"CheckExpr", Func, 13},
+ {"Checker", Type, 5},
+ {"Checker.Info", Field, 5},
+ {"Comparable", Func, 5},
+ {"Complex128", Const, 5},
+ {"Complex64", Const, 5},
+ {"Config", Type, 5},
+ {"Config.Context", Field, 18},
+ {"Config.DisableUnusedImportCheck", Field, 5},
+ {"Config.Error", Field, 5},
+ {"Config.FakeImportC", Field, 5},
+ {"Config.GoVersion", Field, 18},
+ {"Config.IgnoreFuncBodies", Field, 5},
+ {"Config.Importer", Field, 5},
+ {"Config.Sizes", Field, 5},
+ {"Const", Type, 5},
+ {"Context", Type, 18},
+ {"ConvertibleTo", Func, 5},
+ {"DefPredeclaredTestFuncs", Func, 5},
+ {"Default", Func, 8},
+ {"Error", Type, 5},
+ {"Error.Fset", Field, 5},
+ {"Error.Msg", Field, 5},
+ {"Error.Pos", Field, 5},
+ {"Error.Soft", Field, 5},
+ {"Eval", Func, 5},
+ {"ExprString", Func, 5},
+ {"FieldVal", Const, 5},
+ {"Float32", Const, 5},
+ {"Float64", Const, 5},
+ {"Func", Type, 5},
+ {"Id", Func, 5},
+ {"Identical", Func, 5},
+ {"IdenticalIgnoreTags", Func, 8},
+ {"Implements", Func, 5},
+ {"ImportMode", Type, 6},
+ {"Importer", Type, 5},
+ {"ImporterFrom", Type, 6},
+ {"Info", Type, 5},
+ {"Info.Defs", Field, 5},
+ {"Info.FileVersions", Field, 22},
+ {"Info.Implicits", Field, 5},
+ {"Info.InitOrder", Field, 5},
+ {"Info.Instances", Field, 18},
+ {"Info.Scopes", Field, 5},
+ {"Info.Selections", Field, 5},
+ {"Info.Types", Field, 5},
+ {"Info.Uses", Field, 5},
+ {"Initializer", Type, 5},
+ {"Initializer.Lhs", Field, 5},
+ {"Initializer.Rhs", Field, 5},
+ {"Instance", Type, 18},
+ {"Instance.Type", Field, 18},
+ {"Instance.TypeArgs", Field, 18},
+ {"Instantiate", Func, 18},
+ {"Int", Const, 5},
+ {"Int16", Const, 5},
+ {"Int32", Const, 5},
+ {"Int64", Const, 5},
+ {"Int8", Const, 5},
+ {"Interface", Type, 5},
+ {"Invalid", Const, 5},
+ {"IsBoolean", Const, 5},
+ {"IsComplex", Const, 5},
+ {"IsConstType", Const, 5},
+ {"IsFloat", Const, 5},
+ {"IsInteger", Const, 5},
+ {"IsInterface", Func, 5},
+ {"IsNumeric", Const, 5},
+ {"IsOrdered", Const, 5},
+ {"IsString", Const, 5},
+ {"IsUnsigned", Const, 5},
+ {"IsUntyped", Const, 5},
+ {"Label", Type, 5},
+ {"LookupFieldOrMethod", Func, 5},
+ {"Map", Type, 5},
+ {"MethodExpr", Const, 5},
+ {"MethodSet", Type, 5},
+ {"MethodVal", Const, 5},
+ {"MissingMethod", Func, 5},
+ {"Named", Type, 5},
+ {"NewAlias", Func, 22},
+ {"NewArray", Func, 5},
+ {"NewChan", Func, 5},
+ {"NewChecker", Func, 5},
+ {"NewConst", Func, 5},
+ {"NewContext", Func, 18},
+ {"NewField", Func, 5},
+ {"NewFunc", Func, 5},
+ {"NewInterface", Func, 5},
+ {"NewInterfaceType", Func, 11},
+ {"NewLabel", Func, 5},
+ {"NewMap", Func, 5},
+ {"NewMethodSet", Func, 5},
+ {"NewNamed", Func, 5},
+ {"NewPackage", Func, 5},
+ {"NewParam", Func, 5},
+ {"NewPkgName", Func, 5},
+ {"NewPointer", Func, 5},
+ {"NewScope", Func, 5},
+ {"NewSignature", Func, 5},
+ {"NewSignatureType", Func, 18},
+ {"NewSlice", Func, 5},
+ {"NewStruct", Func, 5},
+ {"NewTerm", Func, 18},
+ {"NewTuple", Func, 5},
+ {"NewTypeName", Func, 5},
+ {"NewTypeParam", Func, 18},
+ {"NewUnion", Func, 18},
+ {"NewVar", Func, 5},
+ {"Nil", Type, 5},
+ {"Object", Type, 5},
+ {"ObjectString", Func, 5},
+ {"Package", Type, 5},
+ {"PkgName", Type, 5},
+ {"Pointer", Type, 5},
+ {"Qualifier", Type, 5},
+ {"RecvOnly", Const, 5},
+ {"RelativeTo", Func, 5},
+ {"Rune", Const, 5},
+ {"Satisfies", Func, 20},
+ {"Scope", Type, 5},
+ {"Selection", Type, 5},
+ {"SelectionKind", Type, 5},
+ {"SelectionString", Func, 5},
+ {"SendOnly", Const, 5},
+ {"SendRecv", Const, 5},
+ {"Signature", Type, 5},
+ {"Sizes", Type, 5},
+ {"SizesFor", Func, 9},
+ {"Slice", Type, 5},
+ {"StdSizes", Type, 5},
+ {"StdSizes.MaxAlign", Field, 5},
+ {"StdSizes.WordSize", Field, 5},
+ {"String", Const, 5},
+ {"Struct", Type, 5},
+ {"Term", Type, 18},
+ {"Tuple", Type, 5},
+ {"Typ", Var, 5},
+ {"Type", Type, 5},
+ {"TypeAndValue", Type, 5},
+ {"TypeAndValue.Type", Field, 5},
+ {"TypeAndValue.Value", Field, 5},
+ {"TypeList", Type, 18},
+ {"TypeName", Type, 5},
+ {"TypeParam", Type, 18},
+ {"TypeParamList", Type, 18},
+ {"TypeString", Func, 5},
+ {"Uint", Const, 5},
+ {"Uint16", Const, 5},
+ {"Uint32", Const, 5},
+ {"Uint64", Const, 5},
+ {"Uint8", Const, 5},
+ {"Uintptr", Const, 5},
+ {"Unalias", Func, 22},
+ {"Union", Type, 18},
+ {"Universe", Var, 5},
+ {"Unsafe", Var, 5},
+ {"UnsafePointer", Const, 5},
+ {"UntypedBool", Const, 5},
+ {"UntypedComplex", Const, 5},
+ {"UntypedFloat", Const, 5},
+ {"UntypedInt", Const, 5},
+ {"UntypedNil", Const, 5},
+ {"UntypedRune", Const, 5},
+ {"UntypedString", Const, 5},
+ {"Var", Type, 5},
+ {"WriteExpr", Func, 5},
+ {"WriteSignature", Func, 5},
+ {"WriteType", Func, 5},
+ },
+ "go/version": {
+ {"Compare", Func, 22},
+ {"IsValid", Func, 22},
+ {"Lang", Func, 22},
+ },
+ "hash": {
+ {"Hash", Type, 0},
+ {"Hash32", Type, 0},
+ {"Hash64", Type, 0},
+ },
+ "hash/adler32": {
+ {"Checksum", Func, 0},
+ {"New", Func, 0},
+ {"Size", Const, 0},
+ },
+ "hash/crc32": {
+ {"Castagnoli", Const, 0},
+ {"Checksum", Func, 0},
+ {"ChecksumIEEE", Func, 0},
+ {"IEEE", Const, 0},
+ {"IEEETable", Var, 0},
+ {"Koopman", Const, 0},
+ {"MakeTable", Func, 0},
+ {"New", Func, 0},
+ {"NewIEEE", Func, 0},
+ {"Size", Const, 0},
+ {"Table", Type, 0},
+ {"Update", Func, 0},
+ },
+ "hash/crc64": {
+ {"Checksum", Func, 0},
+ {"ECMA", Const, 0},
+ {"ISO", Const, 0},
+ {"MakeTable", Func, 0},
+ {"New", Func, 0},
+ {"Size", Const, 0},
+ {"Table", Type, 0},
+ {"Update", Func, 0},
+ },
+ "hash/fnv": {
+ {"New128", Func, 9},
+ {"New128a", Func, 9},
+ {"New32", Func, 0},
+ {"New32a", Func, 0},
+ {"New64", Func, 0},
+ {"New64a", Func, 0},
+ },
+ "hash/maphash": {
+ {"(*Hash).BlockSize", Method, 14},
+ {"(*Hash).Reset", Method, 14},
+ {"(*Hash).Seed", Method, 14},
+ {"(*Hash).SetSeed", Method, 14},
+ {"(*Hash).Size", Method, 14},
+ {"(*Hash).Sum", Method, 14},
+ {"(*Hash).Sum64", Method, 14},
+ {"(*Hash).Write", Method, 14},
+ {"(*Hash).WriteByte", Method, 14},
+ {"(*Hash).WriteString", Method, 14},
+ {"Bytes", Func, 19},
+ {"Hash", Type, 14},
+ {"MakeSeed", Func, 14},
+ {"Seed", Type, 14},
+ {"String", Func, 19},
+ },
+ "html": {
+ {"EscapeString", Func, 0},
+ {"UnescapeString", Func, 0},
+ },
+ "html/template": {
+ {"(*Error).Error", Method, 0},
+ {"(*Template).AddParseTree", Method, 0},
+ {"(*Template).Clone", Method, 0},
+ {"(*Template).DefinedTemplates", Method, 6},
+ {"(*Template).Delims", Method, 0},
+ {"(*Template).Execute", Method, 0},
+ {"(*Template).ExecuteTemplate", Method, 0},
+ {"(*Template).Funcs", Method, 0},
+ {"(*Template).Lookup", Method, 0},
+ {"(*Template).Name", Method, 0},
+ {"(*Template).New", Method, 0},
+ {"(*Template).Option", Method, 5},
+ {"(*Template).Parse", Method, 0},
+ {"(*Template).ParseFS", Method, 16},
+ {"(*Template).ParseFiles", Method, 0},
+ {"(*Template).ParseGlob", Method, 0},
+ {"(*Template).Templates", Method, 0},
+ {"CSS", Type, 0},
+ {"ErrAmbigContext", Const, 0},
+ {"ErrBadHTML", Const, 0},
+ {"ErrBranchEnd", Const, 0},
+ {"ErrEndContext", Const, 0},
+ {"ErrJSTemplate", Const, 21},
+ {"ErrNoSuchTemplate", Const, 0},
+ {"ErrOutputContext", Const, 0},
+ {"ErrPartialCharset", Const, 0},
+ {"ErrPartialEscape", Const, 0},
+ {"ErrPredefinedEscaper", Const, 9},
+ {"ErrRangeLoopReentry", Const, 0},
+ {"ErrSlashAmbig", Const, 0},
+ {"Error", Type, 0},
+ {"Error.Description", Field, 0},
+ {"Error.ErrorCode", Field, 0},
+ {"Error.Line", Field, 0},
+ {"Error.Name", Field, 0},
+ {"Error.Node", Field, 4},
+ {"ErrorCode", Type, 0},
+ {"FuncMap", Type, 0},
+ {"HTML", Type, 0},
+ {"HTMLAttr", Type, 0},
+ {"HTMLEscape", Func, 0},
+ {"HTMLEscapeString", Func, 0},
+ {"HTMLEscaper", Func, 0},
+ {"IsTrue", Func, 6},
+ {"JS", Type, 0},
+ {"JSEscape", Func, 0},
+ {"JSEscapeString", Func, 0},
+ {"JSEscaper", Func, 0},
+ {"JSStr", Type, 0},
+ {"Must", Func, 0},
+ {"New", Func, 0},
+ {"OK", Const, 0},
+ {"ParseFS", Func, 16},
+ {"ParseFiles", Func, 0},
+ {"ParseGlob", Func, 0},
+ {"Srcset", Type, 10},
+ {"Template", Type, 0},
+ {"Template.Tree", Field, 2},
+ {"URL", Type, 0},
+ {"URLQueryEscaper", Func, 0},
+ },
+ "image": {
+ {"(*Alpha).AlphaAt", Method, 4},
+ {"(*Alpha).At", Method, 0},
+ {"(*Alpha).Bounds", Method, 0},
+ {"(*Alpha).ColorModel", Method, 0},
+ {"(*Alpha).Opaque", Method, 0},
+ {"(*Alpha).PixOffset", Method, 0},
+ {"(*Alpha).RGBA64At", Method, 17},
+ {"(*Alpha).Set", Method, 0},
+ {"(*Alpha).SetAlpha", Method, 0},
+ {"(*Alpha).SetRGBA64", Method, 17},
+ {"(*Alpha).SubImage", Method, 0},
+ {"(*Alpha16).Alpha16At", Method, 4},
+ {"(*Alpha16).At", Method, 0},
+ {"(*Alpha16).Bounds", Method, 0},
+ {"(*Alpha16).ColorModel", Method, 0},
+ {"(*Alpha16).Opaque", Method, 0},
+ {"(*Alpha16).PixOffset", Method, 0},
+ {"(*Alpha16).RGBA64At", Method, 17},
+ {"(*Alpha16).Set", Method, 0},
+ {"(*Alpha16).SetAlpha16", Method, 0},
+ {"(*Alpha16).SetRGBA64", Method, 17},
+ {"(*Alpha16).SubImage", Method, 0},
+ {"(*CMYK).At", Method, 5},
+ {"(*CMYK).Bounds", Method, 5},
+ {"(*CMYK).CMYKAt", Method, 5},
+ {"(*CMYK).ColorModel", Method, 5},
+ {"(*CMYK).Opaque", Method, 5},
+ {"(*CMYK).PixOffset", Method, 5},
+ {"(*CMYK).RGBA64At", Method, 17},
+ {"(*CMYK).Set", Method, 5},
+ {"(*CMYK).SetCMYK", Method, 5},
+ {"(*CMYK).SetRGBA64", Method, 17},
+ {"(*CMYK).SubImage", Method, 5},
+ {"(*Gray).At", Method, 0},
+ {"(*Gray).Bounds", Method, 0},
+ {"(*Gray).ColorModel", Method, 0},
+ {"(*Gray).GrayAt", Method, 4},
+ {"(*Gray).Opaque", Method, 0},
+ {"(*Gray).PixOffset", Method, 0},
+ {"(*Gray).RGBA64At", Method, 17},
+ {"(*Gray).Set", Method, 0},
+ {"(*Gray).SetGray", Method, 0},
+ {"(*Gray).SetRGBA64", Method, 17},
+ {"(*Gray).SubImage", Method, 0},
+ {"(*Gray16).At", Method, 0},
+ {"(*Gray16).Bounds", Method, 0},
+ {"(*Gray16).ColorModel", Method, 0},
+ {"(*Gray16).Gray16At", Method, 4},
+ {"(*Gray16).Opaque", Method, 0},
+ {"(*Gray16).PixOffset", Method, 0},
+ {"(*Gray16).RGBA64At", Method, 17},
+ {"(*Gray16).Set", Method, 0},
+ {"(*Gray16).SetGray16", Method, 0},
+ {"(*Gray16).SetRGBA64", Method, 17},
+ {"(*Gray16).SubImage", Method, 0},
+ {"(*NRGBA).At", Method, 0},
+ {"(*NRGBA).Bounds", Method, 0},
+ {"(*NRGBA).ColorModel", Method, 0},
+ {"(*NRGBA).NRGBAAt", Method, 4},
+ {"(*NRGBA).Opaque", Method, 0},
+ {"(*NRGBA).PixOffset", Method, 0},
+ {"(*NRGBA).RGBA64At", Method, 17},
+ {"(*NRGBA).Set", Method, 0},
+ {"(*NRGBA).SetNRGBA", Method, 0},
+ {"(*NRGBA).SetRGBA64", Method, 17},
+ {"(*NRGBA).SubImage", Method, 0},
+ {"(*NRGBA64).At", Method, 0},
+ {"(*NRGBA64).Bounds", Method, 0},
+ {"(*NRGBA64).ColorModel", Method, 0},
+ {"(*NRGBA64).NRGBA64At", Method, 4},
+ {"(*NRGBA64).Opaque", Method, 0},
+ {"(*NRGBA64).PixOffset", Method, 0},
+ {"(*NRGBA64).RGBA64At", Method, 17},
+ {"(*NRGBA64).Set", Method, 0},
+ {"(*NRGBA64).SetNRGBA64", Method, 0},
+ {"(*NRGBA64).SetRGBA64", Method, 17},
+ {"(*NRGBA64).SubImage", Method, 0},
+ {"(*NYCbCrA).AOffset", Method, 6},
+ {"(*NYCbCrA).At", Method, 6},
+ {"(*NYCbCrA).Bounds", Method, 6},
+ {"(*NYCbCrA).COffset", Method, 6},
+ {"(*NYCbCrA).ColorModel", Method, 6},
+ {"(*NYCbCrA).NYCbCrAAt", Method, 6},
+ {"(*NYCbCrA).Opaque", Method, 6},
+ {"(*NYCbCrA).RGBA64At", Method, 17},
+ {"(*NYCbCrA).SubImage", Method, 6},
+ {"(*NYCbCrA).YCbCrAt", Method, 6},
+ {"(*NYCbCrA).YOffset", Method, 6},
+ {"(*Paletted).At", Method, 0},
+ {"(*Paletted).Bounds", Method, 0},
+ {"(*Paletted).ColorIndexAt", Method, 0},
+ {"(*Paletted).ColorModel", Method, 0},
+ {"(*Paletted).Opaque", Method, 0},
+ {"(*Paletted).PixOffset", Method, 0},
+ {"(*Paletted).RGBA64At", Method, 17},
+ {"(*Paletted).Set", Method, 0},
+ {"(*Paletted).SetColorIndex", Method, 0},
+ {"(*Paletted).SetRGBA64", Method, 17},
+ {"(*Paletted).SubImage", Method, 0},
+ {"(*RGBA).At", Method, 0},
+ {"(*RGBA).Bounds", Method, 0},
+ {"(*RGBA).ColorModel", Method, 0},
+ {"(*RGBA).Opaque", Method, 0},
+ {"(*RGBA).PixOffset", Method, 0},
+ {"(*RGBA).RGBA64At", Method, 17},
+ {"(*RGBA).RGBAAt", Method, 4},
+ {"(*RGBA).Set", Method, 0},
+ {"(*RGBA).SetRGBA", Method, 0},
+ {"(*RGBA).SetRGBA64", Method, 17},
+ {"(*RGBA).SubImage", Method, 0},
+ {"(*RGBA64).At", Method, 0},
+ {"(*RGBA64).Bounds", Method, 0},
+ {"(*RGBA64).ColorModel", Method, 0},
+ {"(*RGBA64).Opaque", Method, 0},
+ {"(*RGBA64).PixOffset", Method, 0},
+ {"(*RGBA64).RGBA64At", Method, 4},
+ {"(*RGBA64).Set", Method, 0},
+ {"(*RGBA64).SetRGBA64", Method, 0},
+ {"(*RGBA64).SubImage", Method, 0},
+ {"(*Uniform).At", Method, 0},
+ {"(*Uniform).Bounds", Method, 0},
+ {"(*Uniform).ColorModel", Method, 0},
+ {"(*Uniform).Convert", Method, 0},
+ {"(*Uniform).Opaque", Method, 0},
+ {"(*Uniform).RGBA", Method, 0},
+ {"(*Uniform).RGBA64At", Method, 17},
+ {"(*YCbCr).At", Method, 0},
+ {"(*YCbCr).Bounds", Method, 0},
+ {"(*YCbCr).COffset", Method, 0},
+ {"(*YCbCr).ColorModel", Method, 0},
+ {"(*YCbCr).Opaque", Method, 0},
+ {"(*YCbCr).RGBA64At", Method, 17},
+ {"(*YCbCr).SubImage", Method, 0},
+ {"(*YCbCr).YCbCrAt", Method, 4},
+ {"(*YCbCr).YOffset", Method, 0},
+ {"(Point).Add", Method, 0},
+ {"(Point).Div", Method, 0},
+ {"(Point).Eq", Method, 0},
+ {"(Point).In", Method, 0},
+ {"(Point).Mod", Method, 0},
+ {"(Point).Mul", Method, 0},
+ {"(Point).String", Method, 0},
+ {"(Point).Sub", Method, 0},
+ {"(Rectangle).Add", Method, 0},
+ {"(Rectangle).At", Method, 5},
+ {"(Rectangle).Bounds", Method, 5},
+ {"(Rectangle).Canon", Method, 0},
+ {"(Rectangle).ColorModel", Method, 5},
+ {"(Rectangle).Dx", Method, 0},
+ {"(Rectangle).Dy", Method, 0},
+ {"(Rectangle).Empty", Method, 0},
+ {"(Rectangle).Eq", Method, 0},
+ {"(Rectangle).In", Method, 0},
+ {"(Rectangle).Inset", Method, 0},
+ {"(Rectangle).Intersect", Method, 0},
+ {"(Rectangle).Overlaps", Method, 0},
+ {"(Rectangle).RGBA64At", Method, 17},
+ {"(Rectangle).Size", Method, 0},
+ {"(Rectangle).String", Method, 0},
+ {"(Rectangle).Sub", Method, 0},
+ {"(Rectangle).Union", Method, 0},
+ {"(YCbCrSubsampleRatio).String", Method, 0},
+ {"Alpha", Type, 0},
+ {"Alpha.Pix", Field, 0},
+ {"Alpha.Rect", Field, 0},
+ {"Alpha.Stride", Field, 0},
+ {"Alpha16", Type, 0},
+ {"Alpha16.Pix", Field, 0},
+ {"Alpha16.Rect", Field, 0},
+ {"Alpha16.Stride", Field, 0},
+ {"Black", Var, 0},
+ {"CMYK", Type, 5},
+ {"CMYK.Pix", Field, 5},
+ {"CMYK.Rect", Field, 5},
+ {"CMYK.Stride", Field, 5},
+ {"Config", Type, 0},
+ {"Config.ColorModel", Field, 0},
+ {"Config.Height", Field, 0},
+ {"Config.Width", Field, 0},
+ {"Decode", Func, 0},
+ {"DecodeConfig", Func, 0},
+ {"ErrFormat", Var, 0},
+ {"Gray", Type, 0},
+ {"Gray.Pix", Field, 0},
+ {"Gray.Rect", Field, 0},
+ {"Gray.Stride", Field, 0},
+ {"Gray16", Type, 0},
+ {"Gray16.Pix", Field, 0},
+ {"Gray16.Rect", Field, 0},
+ {"Gray16.Stride", Field, 0},
+ {"Image", Type, 0},
+ {"NRGBA", Type, 0},
+ {"NRGBA.Pix", Field, 0},
+ {"NRGBA.Rect", Field, 0},
+ {"NRGBA.Stride", Field, 0},
+ {"NRGBA64", Type, 0},
+ {"NRGBA64.Pix", Field, 0},
+ {"NRGBA64.Rect", Field, 0},
+ {"NRGBA64.Stride", Field, 0},
+ {"NYCbCrA", Type, 6},
+ {"NYCbCrA.A", Field, 6},
+ {"NYCbCrA.AStride", Field, 6},
+ {"NYCbCrA.YCbCr", Field, 6},
+ {"NewAlpha", Func, 0},
+ {"NewAlpha16", Func, 0},
+ {"NewCMYK", Func, 5},
+ {"NewGray", Func, 0},
+ {"NewGray16", Func, 0},
+ {"NewNRGBA", Func, 0},
+ {"NewNRGBA64", Func, 0},
+ {"NewNYCbCrA", Func, 6},
+ {"NewPaletted", Func, 0},
+ {"NewRGBA", Func, 0},
+ {"NewRGBA64", Func, 0},
+ {"NewUniform", Func, 0},
+ {"NewYCbCr", Func, 0},
+ {"Opaque", Var, 0},
+ {"Paletted", Type, 0},
+ {"Paletted.Palette", Field, 0},
+ {"Paletted.Pix", Field, 0},
+ {"Paletted.Rect", Field, 0},
+ {"Paletted.Stride", Field, 0},
+ {"PalettedImage", Type, 0},
+ {"Point", Type, 0},
+ {"Point.X", Field, 0},
+ {"Point.Y", Field, 0},
+ {"Pt", Func, 0},
+ {"RGBA", Type, 0},
+ {"RGBA.Pix", Field, 0},
+ {"RGBA.Rect", Field, 0},
+ {"RGBA.Stride", Field, 0},
+ {"RGBA64", Type, 0},
+ {"RGBA64.Pix", Field, 0},
+ {"RGBA64.Rect", Field, 0},
+ {"RGBA64.Stride", Field, 0},
+ {"RGBA64Image", Type, 17},
+ {"Rect", Func, 0},
+ {"Rectangle", Type, 0},
+ {"Rectangle.Max", Field, 0},
+ {"Rectangle.Min", Field, 0},
+ {"RegisterFormat", Func, 0},
+ {"Transparent", Var, 0},
+ {"Uniform", Type, 0},
+ {"Uniform.C", Field, 0},
+ {"White", Var, 0},
+ {"YCbCr", Type, 0},
+ {"YCbCr.CStride", Field, 0},
+ {"YCbCr.Cb", Field, 0},
+ {"YCbCr.Cr", Field, 0},
+ {"YCbCr.Rect", Field, 0},
+ {"YCbCr.SubsampleRatio", Field, 0},
+ {"YCbCr.Y", Field, 0},
+ {"YCbCr.YStride", Field, 0},
+ {"YCbCrSubsampleRatio", Type, 0},
+ {"YCbCrSubsampleRatio410", Const, 5},
+ {"YCbCrSubsampleRatio411", Const, 5},
+ {"YCbCrSubsampleRatio420", Const, 0},
+ {"YCbCrSubsampleRatio422", Const, 0},
+ {"YCbCrSubsampleRatio440", Const, 1},
+ {"YCbCrSubsampleRatio444", Const, 0},
+ {"ZP", Var, 0},
+ {"ZR", Var, 0},
+ },
+ "image/color": {
+ {"(Alpha).RGBA", Method, 0},
+ {"(Alpha16).RGBA", Method, 0},
+ {"(CMYK).RGBA", Method, 5},
+ {"(Gray).RGBA", Method, 0},
+ {"(Gray16).RGBA", Method, 0},
+ {"(NRGBA).RGBA", Method, 0},
+ {"(NRGBA64).RGBA", Method, 0},
+ {"(NYCbCrA).RGBA", Method, 6},
+ {"(Palette).Convert", Method, 0},
+ {"(Palette).Index", Method, 0},
+ {"(RGBA).RGBA", Method, 0},
+ {"(RGBA64).RGBA", Method, 0},
+ {"(YCbCr).RGBA", Method, 0},
+ {"Alpha", Type, 0},
+ {"Alpha.A", Field, 0},
+ {"Alpha16", Type, 0},
+ {"Alpha16.A", Field, 0},
+ {"Alpha16Model", Var, 0},
+ {"AlphaModel", Var, 0},
+ {"Black", Var, 0},
+ {"CMYK", Type, 5},
+ {"CMYK.C", Field, 5},
+ {"CMYK.K", Field, 5},
+ {"CMYK.M", Field, 5},
+ {"CMYK.Y", Field, 5},
+ {"CMYKModel", Var, 5},
+ {"CMYKToRGB", Func, 5},
+ {"Color", Type, 0},
+ {"Gray", Type, 0},
+ {"Gray.Y", Field, 0},
+ {"Gray16", Type, 0},
+ {"Gray16.Y", Field, 0},
+ {"Gray16Model", Var, 0},
+ {"GrayModel", Var, 0},
+ {"Model", Type, 0},
+ {"ModelFunc", Func, 0},
+ {"NRGBA", Type, 0},
+ {"NRGBA.A", Field, 0},
+ {"NRGBA.B", Field, 0},
+ {"NRGBA.G", Field, 0},
+ {"NRGBA.R", Field, 0},
+ {"NRGBA64", Type, 0},
+ {"NRGBA64.A", Field, 0},
+ {"NRGBA64.B", Field, 0},
+ {"NRGBA64.G", Field, 0},
+ {"NRGBA64.R", Field, 0},
+ {"NRGBA64Model", Var, 0},
+ {"NRGBAModel", Var, 0},
+ {"NYCbCrA", Type, 6},
+ {"NYCbCrA.A", Field, 6},
+ {"NYCbCrA.YCbCr", Field, 6},
+ {"NYCbCrAModel", Var, 6},
+ {"Opaque", Var, 0},
+ {"Palette", Type, 0},
+ {"RGBA", Type, 0},
+ {"RGBA.A", Field, 0},
+ {"RGBA.B", Field, 0},
+ {"RGBA.G", Field, 0},
+ {"RGBA.R", Field, 0},
+ {"RGBA64", Type, 0},
+ {"RGBA64.A", Field, 0},
+ {"RGBA64.B", Field, 0},
+ {"RGBA64.G", Field, 0},
+ {"RGBA64.R", Field, 0},
+ {"RGBA64Model", Var, 0},
+ {"RGBAModel", Var, 0},
+ {"RGBToCMYK", Func, 5},
+ {"RGBToYCbCr", Func, 0},
+ {"Transparent", Var, 0},
+ {"White", Var, 0},
+ {"YCbCr", Type, 0},
+ {"YCbCr.Cb", Field, 0},
+ {"YCbCr.Cr", Field, 0},
+ {"YCbCr.Y", Field, 0},
+ {"YCbCrModel", Var, 0},
+ {"YCbCrToRGB", Func, 0},
+ },
+ "image/color/palette": {
+ {"Plan9", Var, 2},
+ {"WebSafe", Var, 2},
+ },
+ "image/draw": {
+ {"(Op).Draw", Method, 2},
+ {"Draw", Func, 0},
+ {"DrawMask", Func, 0},
+ {"Drawer", Type, 2},
+ {"FloydSteinberg", Var, 2},
+ {"Image", Type, 0},
+ {"Op", Type, 0},
+ {"Over", Const, 0},
+ {"Quantizer", Type, 2},
+ {"RGBA64Image", Type, 17},
+ {"Src", Const, 0},
+ },
+ "image/gif": {
+ {"Decode", Func, 0},
+ {"DecodeAll", Func, 0},
+ {"DecodeConfig", Func, 0},
+ {"DisposalBackground", Const, 5},
+ {"DisposalNone", Const, 5},
+ {"DisposalPrevious", Const, 5},
+ {"Encode", Func, 2},
+ {"EncodeAll", Func, 2},
+ {"GIF", Type, 0},
+ {"GIF.BackgroundIndex", Field, 5},
+ {"GIF.Config", Field, 5},
+ {"GIF.Delay", Field, 0},
+ {"GIF.Disposal", Field, 5},
+ {"GIF.Image", Field, 0},
+ {"GIF.LoopCount", Field, 0},
+ {"Options", Type, 2},
+ {"Options.Drawer", Field, 2},
+ {"Options.NumColors", Field, 2},
+ {"Options.Quantizer", Field, 2},
+ },
+ "image/jpeg": {
+ {"(FormatError).Error", Method, 0},
+ {"(UnsupportedError).Error", Method, 0},
+ {"Decode", Func, 0},
+ {"DecodeConfig", Func, 0},
+ {"DefaultQuality", Const, 0},
+ {"Encode", Func, 0},
+ {"FormatError", Type, 0},
+ {"Options", Type, 0},
+ {"Options.Quality", Field, 0},
+ {"Reader", Type, 0},
+ {"UnsupportedError", Type, 0},
+ },
+ "image/png": {
+ {"(*Encoder).Encode", Method, 4},
+ {"(FormatError).Error", Method, 0},
+ {"(UnsupportedError).Error", Method, 0},
+ {"BestCompression", Const, 4},
+ {"BestSpeed", Const, 4},
+ {"CompressionLevel", Type, 4},
+ {"Decode", Func, 0},
+ {"DecodeConfig", Func, 0},
+ {"DefaultCompression", Const, 4},
+ {"Encode", Func, 0},
+ {"Encoder", Type, 4},
+ {"Encoder.BufferPool", Field, 9},
+ {"Encoder.CompressionLevel", Field, 4},
+ {"EncoderBuffer", Type, 9},
+ {"EncoderBufferPool", Type, 9},
+ {"FormatError", Type, 0},
+ {"NoCompression", Const, 4},
+ {"UnsupportedError", Type, 0},
+ },
+ "index/suffixarray": {
+ {"(*Index).Bytes", Method, 0},
+ {"(*Index).FindAllIndex", Method, 0},
+ {"(*Index).Lookup", Method, 0},
+ {"(*Index).Read", Method, 0},
+ {"(*Index).Write", Method, 0},
+ {"Index", Type, 0},
+ {"New", Func, 0},
+ },
+ "io": {
+ {"(*LimitedReader).Read", Method, 0},
+ {"(*OffsetWriter).Seek", Method, 20},
+ {"(*OffsetWriter).Write", Method, 20},
+ {"(*OffsetWriter).WriteAt", Method, 20},
+ {"(*PipeReader).Close", Method, 0},
+ {"(*PipeReader).CloseWithError", Method, 0},
+ {"(*PipeReader).Read", Method, 0},
+ {"(*PipeWriter).Close", Method, 0},
+ {"(*PipeWriter).CloseWithError", Method, 0},
+ {"(*PipeWriter).Write", Method, 0},
+ {"(*SectionReader).Outer", Method, 22},
+ {"(*SectionReader).Read", Method, 0},
+ {"(*SectionReader).ReadAt", Method, 0},
+ {"(*SectionReader).Seek", Method, 0},
+ {"(*SectionReader).Size", Method, 0},
+ {"ByteReader", Type, 0},
+ {"ByteScanner", Type, 0},
+ {"ByteWriter", Type, 1},
+ {"Closer", Type, 0},
+ {"Copy", Func, 0},
+ {"CopyBuffer", Func, 5},
+ {"CopyN", Func, 0},
+ {"Discard", Var, 16},
+ {"EOF", Var, 0},
+ {"ErrClosedPipe", Var, 0},
+ {"ErrNoProgress", Var, 1},
+ {"ErrShortBuffer", Var, 0},
+ {"ErrShortWrite", Var, 0},
+ {"ErrUnexpectedEOF", Var, 0},
+ {"LimitReader", Func, 0},
+ {"LimitedReader", Type, 0},
+ {"LimitedReader.N", Field, 0},
+ {"LimitedReader.R", Field, 0},
+ {"MultiReader", Func, 0},
+ {"MultiWriter", Func, 0},
+ {"NewOffsetWriter", Func, 20},
+ {"NewSectionReader", Func, 0},
+ {"NopCloser", Func, 16},
+ {"OffsetWriter", Type, 20},
+ {"Pipe", Func, 0},
+ {"PipeReader", Type, 0},
+ {"PipeWriter", Type, 0},
+ {"ReadAll", Func, 16},
+ {"ReadAtLeast", Func, 0},
+ {"ReadCloser", Type, 0},
+ {"ReadFull", Func, 0},
+ {"ReadSeekCloser", Type, 16},
+ {"ReadSeeker", Type, 0},
+ {"ReadWriteCloser", Type, 0},
+ {"ReadWriteSeeker", Type, 0},
+ {"ReadWriter", Type, 0},
+ {"Reader", Type, 0},
+ {"ReaderAt", Type, 0},
+ {"ReaderFrom", Type, 0},
+ {"RuneReader", Type, 0},
+ {"RuneScanner", Type, 0},
+ {"SectionReader", Type, 0},
+ {"SeekCurrent", Const, 7},
+ {"SeekEnd", Const, 7},
+ {"SeekStart", Const, 7},
+ {"Seeker", Type, 0},
+ {"StringWriter", Type, 12},
+ {"TeeReader", Func, 0},
+ {"WriteCloser", Type, 0},
+ {"WriteSeeker", Type, 0},
+ {"WriteString", Func, 0},
+ {"Writer", Type, 0},
+ {"WriterAt", Type, 0},
+ {"WriterTo", Type, 0},
+ },
+ "io/fs": {
+ {"(*PathError).Error", Method, 16},
+ {"(*PathError).Timeout", Method, 16},
+ {"(*PathError).Unwrap", Method, 16},
+ {"(FileMode).IsDir", Method, 16},
+ {"(FileMode).IsRegular", Method, 16},
+ {"(FileMode).Perm", Method, 16},
+ {"(FileMode).String", Method, 16},
+ {"(FileMode).Type", Method, 16},
+ {"DirEntry", Type, 16},
+ {"ErrClosed", Var, 16},
+ {"ErrExist", Var, 16},
+ {"ErrInvalid", Var, 16},
+ {"ErrNotExist", Var, 16},
+ {"ErrPermission", Var, 16},
+ {"FS", Type, 16},
+ {"File", Type, 16},
+ {"FileInfo", Type, 16},
+ {"FileInfoToDirEntry", Func, 17},
+ {"FileMode", Type, 16},
+ {"FormatDirEntry", Func, 21},
+ {"FormatFileInfo", Func, 21},
+ {"Glob", Func, 16},
+ {"GlobFS", Type, 16},
+ {"ModeAppend", Const, 16},
+ {"ModeCharDevice", Const, 16},
+ {"ModeDevice", Const, 16},
+ {"ModeDir", Const, 16},
+ {"ModeExclusive", Const, 16},
+ {"ModeIrregular", Const, 16},
+ {"ModeNamedPipe", Const, 16},
+ {"ModePerm", Const, 16},
+ {"ModeSetgid", Const, 16},
+ {"ModeSetuid", Const, 16},
+ {"ModeSocket", Const, 16},
+ {"ModeSticky", Const, 16},
+ {"ModeSymlink", Const, 16},
+ {"ModeTemporary", Const, 16},
+ {"ModeType", Const, 16},
+ {"PathError", Type, 16},
+ {"PathError.Err", Field, 16},
+ {"PathError.Op", Field, 16},
+ {"PathError.Path", Field, 16},
+ {"ReadDir", Func, 16},
+ {"ReadDirFS", Type, 16},
+ {"ReadDirFile", Type, 16},
+ {"ReadFile", Func, 16},
+ {"ReadFileFS", Type, 16},
+ {"SkipAll", Var, 20},
+ {"SkipDir", Var, 16},
+ {"Stat", Func, 16},
+ {"StatFS", Type, 16},
+ {"Sub", Func, 16},
+ {"SubFS", Type, 16},
+ {"ValidPath", Func, 16},
+ {"WalkDir", Func, 16},
+ {"WalkDirFunc", Type, 16},
+ },
+ "io/ioutil": {
+ {"Discard", Var, 0},
+ {"NopCloser", Func, 0},
+ {"ReadAll", Func, 0},
+ {"ReadDir", Func, 0},
+ {"ReadFile", Func, 0},
+ {"TempDir", Func, 0},
+ {"TempFile", Func, 0},
+ {"WriteFile", Func, 0},
+ },
+ "iter": {
+ {"Pull", Func, 23},
+ {"Pull2", Func, 23},
+ {"Seq", Type, 23},
+ {"Seq2", Type, 23},
+ },
+ "log": {
+ {"(*Logger).Fatal", Method, 0},
+ {"(*Logger).Fatalf", Method, 0},
+ {"(*Logger).Fatalln", Method, 0},
+ {"(*Logger).Flags", Method, 0},
+ {"(*Logger).Output", Method, 0},
+ {"(*Logger).Panic", Method, 0},
+ {"(*Logger).Panicf", Method, 0},
+ {"(*Logger).Panicln", Method, 0},
+ {"(*Logger).Prefix", Method, 0},
+ {"(*Logger).Print", Method, 0},
+ {"(*Logger).Printf", Method, 0},
+ {"(*Logger).Println", Method, 0},
+ {"(*Logger).SetFlags", Method, 0},
+ {"(*Logger).SetOutput", Method, 5},
+ {"(*Logger).SetPrefix", Method, 0},
+ {"(*Logger).Writer", Method, 12},
+ {"Default", Func, 16},
+ {"Fatal", Func, 0},
+ {"Fatalf", Func, 0},
+ {"Fatalln", Func, 0},
+ {"Flags", Func, 0},
+ {"LUTC", Const, 5},
+ {"Ldate", Const, 0},
+ {"Llongfile", Const, 0},
+ {"Lmicroseconds", Const, 0},
+ {"Lmsgprefix", Const, 14},
+ {"Logger", Type, 0},
+ {"Lshortfile", Const, 0},
+ {"LstdFlags", Const, 0},
+ {"Ltime", Const, 0},
+ {"New", Func, 0},
+ {"Output", Func, 5},
+ {"Panic", Func, 0},
+ {"Panicf", Func, 0},
+ {"Panicln", Func, 0},
+ {"Prefix", Func, 0},
+ {"Print", Func, 0},
+ {"Printf", Func, 0},
+ {"Println", Func, 0},
+ {"SetFlags", Func, 0},
+ {"SetOutput", Func, 0},
+ {"SetPrefix", Func, 0},
+ {"Writer", Func, 13},
+ },
+ "log/slog": {
+ {"(*JSONHandler).Enabled", Method, 21},
+ {"(*JSONHandler).Handle", Method, 21},
+ {"(*JSONHandler).WithAttrs", Method, 21},
+ {"(*JSONHandler).WithGroup", Method, 21},
+ {"(*Level).UnmarshalJSON", Method, 21},
+ {"(*Level).UnmarshalText", Method, 21},
+ {"(*LevelVar).Level", Method, 21},
+ {"(*LevelVar).MarshalText", Method, 21},
+ {"(*LevelVar).Set", Method, 21},
+ {"(*LevelVar).String", Method, 21},
+ {"(*LevelVar).UnmarshalText", Method, 21},
+ {"(*Logger).Debug", Method, 21},
+ {"(*Logger).DebugContext", Method, 21},
+ {"(*Logger).Enabled", Method, 21},
+ {"(*Logger).Error", Method, 21},
+ {"(*Logger).ErrorContext", Method, 21},
+ {"(*Logger).Handler", Method, 21},
+ {"(*Logger).Info", Method, 21},
+ {"(*Logger).InfoContext", Method, 21},
+ {"(*Logger).Log", Method, 21},
+ {"(*Logger).LogAttrs", Method, 21},
+ {"(*Logger).Warn", Method, 21},
+ {"(*Logger).WarnContext", Method, 21},
+ {"(*Logger).With", Method, 21},
+ {"(*Logger).WithGroup", Method, 21},
+ {"(*Record).Add", Method, 21},
+ {"(*Record).AddAttrs", Method, 21},
+ {"(*TextHandler).Enabled", Method, 21},
+ {"(*TextHandler).Handle", Method, 21},
+ {"(*TextHandler).WithAttrs", Method, 21},
+ {"(*TextHandler).WithGroup", Method, 21},
+ {"(Attr).Equal", Method, 21},
+ {"(Attr).String", Method, 21},
+ {"(Kind).String", Method, 21},
+ {"(Level).Level", Method, 21},
+ {"(Level).MarshalJSON", Method, 21},
+ {"(Level).MarshalText", Method, 21},
+ {"(Level).String", Method, 21},
+ {"(Record).Attrs", Method, 21},
+ {"(Record).Clone", Method, 21},
+ {"(Record).NumAttrs", Method, 21},
+ {"(Value).Any", Method, 21},
+ {"(Value).Bool", Method, 21},
+ {"(Value).Duration", Method, 21},
+ {"(Value).Equal", Method, 21},
+ {"(Value).Float64", Method, 21},
+ {"(Value).Group", Method, 21},
+ {"(Value).Int64", Method, 21},
+ {"(Value).Kind", Method, 21},
+ {"(Value).LogValuer", Method, 21},
+ {"(Value).Resolve", Method, 21},
+ {"(Value).String", Method, 21},
+ {"(Value).Time", Method, 21},
+ {"(Value).Uint64", Method, 21},
+ {"Any", Func, 21},
+ {"AnyValue", Func, 21},
+ {"Attr", Type, 21},
+ {"Attr.Key", Field, 21},
+ {"Attr.Value", Field, 21},
+ {"Bool", Func, 21},
+ {"BoolValue", Func, 21},
+ {"Debug", Func, 21},
+ {"DebugContext", Func, 21},
+ {"Default", Func, 21},
+ {"Duration", Func, 21},
+ {"DurationValue", Func, 21},
+ {"Error", Func, 21},
+ {"ErrorContext", Func, 21},
+ {"Float64", Func, 21},
+ {"Float64Value", Func, 21},
+ {"Group", Func, 21},
+ {"GroupValue", Func, 21},
+ {"Handler", Type, 21},
+ {"HandlerOptions", Type, 21},
+ {"HandlerOptions.AddSource", Field, 21},
+ {"HandlerOptions.Level", Field, 21},
+ {"HandlerOptions.ReplaceAttr", Field, 21},
+ {"Info", Func, 21},
+ {"InfoContext", Func, 21},
+ {"Int", Func, 21},
+ {"Int64", Func, 21},
+ {"Int64Value", Func, 21},
+ {"IntValue", Func, 21},
+ {"JSONHandler", Type, 21},
+ {"Kind", Type, 21},
+ {"KindAny", Const, 21},
+ {"KindBool", Const, 21},
+ {"KindDuration", Const, 21},
+ {"KindFloat64", Const, 21},
+ {"KindGroup", Const, 21},
+ {"KindInt64", Const, 21},
+ {"KindLogValuer", Const, 21},
+ {"KindString", Const, 21},
+ {"KindTime", Const, 21},
+ {"KindUint64", Const, 21},
+ {"Level", Type, 21},
+ {"LevelDebug", Const, 21},
+ {"LevelError", Const, 21},
+ {"LevelInfo", Const, 21},
+ {"LevelKey", Const, 21},
+ {"LevelVar", Type, 21},
+ {"LevelWarn", Const, 21},
+ {"Leveler", Type, 21},
+ {"Log", Func, 21},
+ {"LogAttrs", Func, 21},
+ {"LogValuer", Type, 21},
+ {"Logger", Type, 21},
+ {"MessageKey", Const, 21},
+ {"New", Func, 21},
+ {"NewJSONHandler", Func, 21},
+ {"NewLogLogger", Func, 21},
+ {"NewRecord", Func, 21},
+ {"NewTextHandler", Func, 21},
+ {"Record", Type, 21},
+ {"Record.Level", Field, 21},
+ {"Record.Message", Field, 21},
+ {"Record.PC", Field, 21},
+ {"Record.Time", Field, 21},
+ {"SetDefault", Func, 21},
+ {"SetLogLoggerLevel", Func, 22},
+ {"Source", Type, 21},
+ {"Source.File", Field, 21},
+ {"Source.Function", Field, 21},
+ {"Source.Line", Field, 21},
+ {"SourceKey", Const, 21},
+ {"String", Func, 21},
+ {"StringValue", Func, 21},
+ {"TextHandler", Type, 21},
+ {"Time", Func, 21},
+ {"TimeKey", Const, 21},
+ {"TimeValue", Func, 21},
+ {"Uint64", Func, 21},
+ {"Uint64Value", Func, 21},
+ {"Value", Type, 21},
+ {"Warn", Func, 21},
+ {"WarnContext", Func, 21},
+ {"With", Func, 21},
+ },
+ "log/syslog": {
+ {"(*Writer).Alert", Method, 0},
+ {"(*Writer).Close", Method, 0},
+ {"(*Writer).Crit", Method, 0},
+ {"(*Writer).Debug", Method, 0},
+ {"(*Writer).Emerg", Method, 0},
+ {"(*Writer).Err", Method, 0},
+ {"(*Writer).Info", Method, 0},
+ {"(*Writer).Notice", Method, 0},
+ {"(*Writer).Warning", Method, 0},
+ {"(*Writer).Write", Method, 0},
+ {"Dial", Func, 0},
+ {"LOG_ALERT", Const, 0},
+ {"LOG_AUTH", Const, 1},
+ {"LOG_AUTHPRIV", Const, 1},
+ {"LOG_CRIT", Const, 0},
+ {"LOG_CRON", Const, 1},
+ {"LOG_DAEMON", Const, 1},
+ {"LOG_DEBUG", Const, 0},
+ {"LOG_EMERG", Const, 0},
+ {"LOG_ERR", Const, 0},
+ {"LOG_FTP", Const, 1},
+ {"LOG_INFO", Const, 0},
+ {"LOG_KERN", Const, 1},
+ {"LOG_LOCAL0", Const, 1},
+ {"LOG_LOCAL1", Const, 1},
+ {"LOG_LOCAL2", Const, 1},
+ {"LOG_LOCAL3", Const, 1},
+ {"LOG_LOCAL4", Const, 1},
+ {"LOG_LOCAL5", Const, 1},
+ {"LOG_LOCAL6", Const, 1},
+ {"LOG_LOCAL7", Const, 1},
+ {"LOG_LPR", Const, 1},
+ {"LOG_MAIL", Const, 1},
+ {"LOG_NEWS", Const, 1},
+ {"LOG_NOTICE", Const, 0},
+ {"LOG_SYSLOG", Const, 1},
+ {"LOG_USER", Const, 1},
+ {"LOG_UUCP", Const, 1},
+ {"LOG_WARNING", Const, 0},
+ {"New", Func, 0},
+ {"NewLogger", Func, 0},
+ {"Priority", Type, 0},
+ {"Writer", Type, 0},
+ },
+ "maps": {
+ {"All", Func, 23},
+ {"Clone", Func, 21},
+ {"Collect", Func, 23},
+ {"Copy", Func, 21},
+ {"DeleteFunc", Func, 21},
+ {"Equal", Func, 21},
+ {"EqualFunc", Func, 21},
+ {"Insert", Func, 23},
+ {"Keys", Func, 23},
+ {"Values", Func, 23},
+ },
+ "math": {
+ {"Abs", Func, 0},
+ {"Acos", Func, 0},
+ {"Acosh", Func, 0},
+ {"Asin", Func, 0},
+ {"Asinh", Func, 0},
+ {"Atan", Func, 0},
+ {"Atan2", Func, 0},
+ {"Atanh", Func, 0},
+ {"Cbrt", Func, 0},
+ {"Ceil", Func, 0},
+ {"Copysign", Func, 0},
+ {"Cos", Func, 0},
+ {"Cosh", Func, 0},
+ {"Dim", Func, 0},
+ {"E", Const, 0},
+ {"Erf", Func, 0},
+ {"Erfc", Func, 0},
+ {"Erfcinv", Func, 10},
+ {"Erfinv", Func, 10},
+ {"Exp", Func, 0},
+ {"Exp2", Func, 0},
+ {"Expm1", Func, 0},
+ {"FMA", Func, 14},
+ {"Float32bits", Func, 0},
+ {"Float32frombits", Func, 0},
+ {"Float64bits", Func, 0},
+ {"Float64frombits", Func, 0},
+ {"Floor", Func, 0},
+ {"Frexp", Func, 0},
+ {"Gamma", Func, 0},
+ {"Hypot", Func, 0},
+ {"Ilogb", Func, 0},
+ {"Inf", Func, 0},
+ {"IsInf", Func, 0},
+ {"IsNaN", Func, 0},
+ {"J0", Func, 0},
+ {"J1", Func, 0},
+ {"Jn", Func, 0},
+ {"Ldexp", Func, 0},
+ {"Lgamma", Func, 0},
+ {"Ln10", Const, 0},
+ {"Ln2", Const, 0},
+ {"Log", Func, 0},
+ {"Log10", Func, 0},
+ {"Log10E", Const, 0},
+ {"Log1p", Func, 0},
+ {"Log2", Func, 0},
+ {"Log2E", Const, 0},
+ {"Logb", Func, 0},
+ {"Max", Func, 0},
+ {"MaxFloat32", Const, 0},
+ {"MaxFloat64", Const, 0},
+ {"MaxInt", Const, 17},
+ {"MaxInt16", Const, 0},
+ {"MaxInt32", Const, 0},
+ {"MaxInt64", Const, 0},
+ {"MaxInt8", Const, 0},
+ {"MaxUint", Const, 17},
+ {"MaxUint16", Const, 0},
+ {"MaxUint32", Const, 0},
+ {"MaxUint64", Const, 0},
+ {"MaxUint8", Const, 0},
+ {"Min", Func, 0},
+ {"MinInt", Const, 17},
+ {"MinInt16", Const, 0},
+ {"MinInt32", Const, 0},
+ {"MinInt64", Const, 0},
+ {"MinInt8", Const, 0},
+ {"Mod", Func, 0},
+ {"Modf", Func, 0},
+ {"NaN", Func, 0},
+ {"Nextafter", Func, 0},
+ {"Nextafter32", Func, 4},
+ {"Phi", Const, 0},
+ {"Pi", Const, 0},
+ {"Pow", Func, 0},
+ {"Pow10", Func, 0},
+ {"Remainder", Func, 0},
+ {"Round", Func, 10},
+ {"RoundToEven", Func, 10},
+ {"Signbit", Func, 0},
+ {"Sin", Func, 0},
+ {"Sincos", Func, 0},
+ {"Sinh", Func, 0},
+ {"SmallestNonzeroFloat32", Const, 0},
+ {"SmallestNonzeroFloat64", Const, 0},
+ {"Sqrt", Func, 0},
+ {"Sqrt2", Const, 0},
+ {"SqrtE", Const, 0},
+ {"SqrtPhi", Const, 0},
+ {"SqrtPi", Const, 0},
+ {"Tan", Func, 0},
+ {"Tanh", Func, 0},
+ {"Trunc", Func, 0},
+ {"Y0", Func, 0},
+ {"Y1", Func, 0},
+ {"Yn", Func, 0},
+ },
+ "math/big": {
+ {"(*Float).Abs", Method, 5},
+ {"(*Float).Acc", Method, 5},
+ {"(*Float).Add", Method, 5},
+ {"(*Float).Append", Method, 5},
+ {"(*Float).Cmp", Method, 5},
+ {"(*Float).Copy", Method, 5},
+ {"(*Float).Float32", Method, 5},
+ {"(*Float).Float64", Method, 5},
+ {"(*Float).Format", Method, 5},
+ {"(*Float).GobDecode", Method, 7},
+ {"(*Float).GobEncode", Method, 7},
+ {"(*Float).Int", Method, 5},
+ {"(*Float).Int64", Method, 5},
+ {"(*Float).IsInf", Method, 5},
+ {"(*Float).IsInt", Method, 5},
+ {"(*Float).MantExp", Method, 5},
+ {"(*Float).MarshalText", Method, 6},
+ {"(*Float).MinPrec", Method, 5},
+ {"(*Float).Mode", Method, 5},
+ {"(*Float).Mul", Method, 5},
+ {"(*Float).Neg", Method, 5},
+ {"(*Float).Parse", Method, 5},
+ {"(*Float).Prec", Method, 5},
+ {"(*Float).Quo", Method, 5},
+ {"(*Float).Rat", Method, 5},
+ {"(*Float).Scan", Method, 8},
+ {"(*Float).Set", Method, 5},
+ {"(*Float).SetFloat64", Method, 5},
+ {"(*Float).SetInf", Method, 5},
+ {"(*Float).SetInt", Method, 5},
+ {"(*Float).SetInt64", Method, 5},
+ {"(*Float).SetMantExp", Method, 5},
+ {"(*Float).SetMode", Method, 5},
+ {"(*Float).SetPrec", Method, 5},
+ {"(*Float).SetRat", Method, 5},
+ {"(*Float).SetString", Method, 5},
+ {"(*Float).SetUint64", Method, 5},
+ {"(*Float).Sign", Method, 5},
+ {"(*Float).Signbit", Method, 5},
+ {"(*Float).Sqrt", Method, 10},
+ {"(*Float).String", Method, 5},
+ {"(*Float).Sub", Method, 5},
+ {"(*Float).Text", Method, 5},
+ {"(*Float).Uint64", Method, 5},
+ {"(*Float).UnmarshalText", Method, 6},
+ {"(*Int).Abs", Method, 0},
+ {"(*Int).Add", Method, 0},
+ {"(*Int).And", Method, 0},
+ {"(*Int).AndNot", Method, 0},
+ {"(*Int).Append", Method, 6},
+ {"(*Int).Binomial", Method, 0},
+ {"(*Int).Bit", Method, 0},
+ {"(*Int).BitLen", Method, 0},
+ {"(*Int).Bits", Method, 0},
+ {"(*Int).Bytes", Method, 0},
+ {"(*Int).Cmp", Method, 0},
+ {"(*Int).CmpAbs", Method, 10},
+ {"(*Int).Div", Method, 0},
+ {"(*Int).DivMod", Method, 0},
+ {"(*Int).Exp", Method, 0},
+ {"(*Int).FillBytes", Method, 15},
+ {"(*Int).Float64", Method, 21},
+ {"(*Int).Format", Method, 0},
+ {"(*Int).GCD", Method, 0},
+ {"(*Int).GobDecode", Method, 0},
+ {"(*Int).GobEncode", Method, 0},
+ {"(*Int).Int64", Method, 0},
+ {"(*Int).IsInt64", Method, 9},
+ {"(*Int).IsUint64", Method, 9},
+ {"(*Int).Lsh", Method, 0},
+ {"(*Int).MarshalJSON", Method, 1},
+ {"(*Int).MarshalText", Method, 3},
+ {"(*Int).Mod", Method, 0},
+ {"(*Int).ModInverse", Method, 0},
+ {"(*Int).ModSqrt", Method, 5},
+ {"(*Int).Mul", Method, 0},
+ {"(*Int).MulRange", Method, 0},
+ {"(*Int).Neg", Method, 0},
+ {"(*Int).Not", Method, 0},
+ {"(*Int).Or", Method, 0},
+ {"(*Int).ProbablyPrime", Method, 0},
+ {"(*Int).Quo", Method, 0},
+ {"(*Int).QuoRem", Method, 0},
+ {"(*Int).Rand", Method, 0},
+ {"(*Int).Rem", Method, 0},
+ {"(*Int).Rsh", Method, 0},
+ {"(*Int).Scan", Method, 0},
+ {"(*Int).Set", Method, 0},
+ {"(*Int).SetBit", Method, 0},
+ {"(*Int).SetBits", Method, 0},
+ {"(*Int).SetBytes", Method, 0},
+ {"(*Int).SetInt64", Method, 0},
+ {"(*Int).SetString", Method, 0},
+ {"(*Int).SetUint64", Method, 1},
+ {"(*Int).Sign", Method, 0},
+ {"(*Int).Sqrt", Method, 8},
+ {"(*Int).String", Method, 0},
+ {"(*Int).Sub", Method, 0},
+ {"(*Int).Text", Method, 6},
+ {"(*Int).TrailingZeroBits", Method, 13},
+ {"(*Int).Uint64", Method, 1},
+ {"(*Int).UnmarshalJSON", Method, 1},
+ {"(*Int).UnmarshalText", Method, 3},
+ {"(*Int).Xor", Method, 0},
+ {"(*Rat).Abs", Method, 0},
+ {"(*Rat).Add", Method, 0},
+ {"(*Rat).Cmp", Method, 0},
+ {"(*Rat).Denom", Method, 0},
+ {"(*Rat).Float32", Method, 4},
+ {"(*Rat).Float64", Method, 1},
+ {"(*Rat).FloatPrec", Method, 22},
+ {"(*Rat).FloatString", Method, 0},
+ {"(*Rat).GobDecode", Method, 0},
+ {"(*Rat).GobEncode", Method, 0},
+ {"(*Rat).Inv", Method, 0},
+ {"(*Rat).IsInt", Method, 0},
+ {"(*Rat).MarshalText", Method, 3},
+ {"(*Rat).Mul", Method, 0},
+ {"(*Rat).Neg", Method, 0},
+ {"(*Rat).Num", Method, 0},
+ {"(*Rat).Quo", Method, 0},
+ {"(*Rat).RatString", Method, 0},
+ {"(*Rat).Scan", Method, 0},
+ {"(*Rat).Set", Method, 0},
+ {"(*Rat).SetFloat64", Method, 1},
+ {"(*Rat).SetFrac", Method, 0},
+ {"(*Rat).SetFrac64", Method, 0},
+ {"(*Rat).SetInt", Method, 0},
+ {"(*Rat).SetInt64", Method, 0},
+ {"(*Rat).SetString", Method, 0},
+ {"(*Rat).SetUint64", Method, 13},
+ {"(*Rat).Sign", Method, 0},
+ {"(*Rat).String", Method, 0},
+ {"(*Rat).Sub", Method, 0},
+ {"(*Rat).UnmarshalText", Method, 3},
+ {"(Accuracy).String", Method, 5},
+ {"(ErrNaN).Error", Method, 5},
+ {"(RoundingMode).String", Method, 5},
+ {"Above", Const, 5},
+ {"Accuracy", Type, 5},
+ {"AwayFromZero", Const, 5},
+ {"Below", Const, 5},
+ {"ErrNaN", Type, 5},
+ {"Exact", Const, 5},
+ {"Float", Type, 5},
+ {"Int", Type, 0},
+ {"Jacobi", Func, 5},
+ {"MaxBase", Const, 0},
+ {"MaxExp", Const, 5},
+ {"MaxPrec", Const, 5},
+ {"MinExp", Const, 5},
+ {"NewFloat", Func, 5},
+ {"NewInt", Func, 0},
+ {"NewRat", Func, 0},
+ {"ParseFloat", Func, 5},
+ {"Rat", Type, 0},
+ {"RoundingMode", Type, 5},
+ {"ToNearestAway", Const, 5},
+ {"ToNearestEven", Const, 5},
+ {"ToNegativeInf", Const, 5},
+ {"ToPositiveInf", Const, 5},
+ {"ToZero", Const, 5},
+ {"Word", Type, 0},
+ },
+ "math/bits": {
+ {"Add", Func, 12},
+ {"Add32", Func, 12},
+ {"Add64", Func, 12},
+ {"Div", Func, 12},
+ {"Div32", Func, 12},
+ {"Div64", Func, 12},
+ {"LeadingZeros", Func, 9},
+ {"LeadingZeros16", Func, 9},
+ {"LeadingZeros32", Func, 9},
+ {"LeadingZeros64", Func, 9},
+ {"LeadingZeros8", Func, 9},
+ {"Len", Func, 9},
+ {"Len16", Func, 9},
+ {"Len32", Func, 9},
+ {"Len64", Func, 9},
+ {"Len8", Func, 9},
+ {"Mul", Func, 12},
+ {"Mul32", Func, 12},
+ {"Mul64", Func, 12},
+ {"OnesCount", Func, 9},
+ {"OnesCount16", Func, 9},
+ {"OnesCount32", Func, 9},
+ {"OnesCount64", Func, 9},
+ {"OnesCount8", Func, 9},
+ {"Rem", Func, 14},
+ {"Rem32", Func, 14},
+ {"Rem64", Func, 14},
+ {"Reverse", Func, 9},
+ {"Reverse16", Func, 9},
+ {"Reverse32", Func, 9},
+ {"Reverse64", Func, 9},
+ {"Reverse8", Func, 9},
+ {"ReverseBytes", Func, 9},
+ {"ReverseBytes16", Func, 9},
+ {"ReverseBytes32", Func, 9},
+ {"ReverseBytes64", Func, 9},
+ {"RotateLeft", Func, 9},
+ {"RotateLeft16", Func, 9},
+ {"RotateLeft32", Func, 9},
+ {"RotateLeft64", Func, 9},
+ {"RotateLeft8", Func, 9},
+ {"Sub", Func, 12},
+ {"Sub32", Func, 12},
+ {"Sub64", Func, 12},
+ {"TrailingZeros", Func, 9},
+ {"TrailingZeros16", Func, 9},
+ {"TrailingZeros32", Func, 9},
+ {"TrailingZeros64", Func, 9},
+ {"TrailingZeros8", Func, 9},
+ {"UintSize", Const, 9},
+ },
+ "math/cmplx": {
+ {"Abs", Func, 0},
+ {"Acos", Func, 0},
+ {"Acosh", Func, 0},
+ {"Asin", Func, 0},
+ {"Asinh", Func, 0},
+ {"Atan", Func, 0},
+ {"Atanh", Func, 0},
+ {"Conj", Func, 0},
+ {"Cos", Func, 0},
+ {"Cosh", Func, 0},
+ {"Cot", Func, 0},
+ {"Exp", Func, 0},
+ {"Inf", Func, 0},
+ {"IsInf", Func, 0},
+ {"IsNaN", Func, 0},
+ {"Log", Func, 0},
+ {"Log10", Func, 0},
+ {"NaN", Func, 0},
+ {"Phase", Func, 0},
+ {"Polar", Func, 0},
+ {"Pow", Func, 0},
+ {"Rect", Func, 0},
+ {"Sin", Func, 0},
+ {"Sinh", Func, 0},
+ {"Sqrt", Func, 0},
+ {"Tan", Func, 0},
+ {"Tanh", Func, 0},
+ },
+ "math/rand": {
+ {"(*Rand).ExpFloat64", Method, 0},
+ {"(*Rand).Float32", Method, 0},
+ {"(*Rand).Float64", Method, 0},
+ {"(*Rand).Int", Method, 0},
+ {"(*Rand).Int31", Method, 0},
+ {"(*Rand).Int31n", Method, 0},
+ {"(*Rand).Int63", Method, 0},
+ {"(*Rand).Int63n", Method, 0},
+ {"(*Rand).Intn", Method, 0},
+ {"(*Rand).NormFloat64", Method, 0},
+ {"(*Rand).Perm", Method, 0},
+ {"(*Rand).Read", Method, 6},
+ {"(*Rand).Seed", Method, 0},
+ {"(*Rand).Shuffle", Method, 10},
+ {"(*Rand).Uint32", Method, 0},
+ {"(*Rand).Uint64", Method, 8},
+ {"(*Zipf).Uint64", Method, 0},
+ {"ExpFloat64", Func, 0},
+ {"Float32", Func, 0},
+ {"Float64", Func, 0},
+ {"Int", Func, 0},
+ {"Int31", Func, 0},
+ {"Int31n", Func, 0},
+ {"Int63", Func, 0},
+ {"Int63n", Func, 0},
+ {"Intn", Func, 0},
+ {"New", Func, 0},
+ {"NewSource", Func, 0},
+ {"NewZipf", Func, 0},
+ {"NormFloat64", Func, 0},
+ {"Perm", Func, 0},
+ {"Rand", Type, 0},
+ {"Read", Func, 6},
+ {"Seed", Func, 0},
+ {"Shuffle", Func, 10},
+ {"Source", Type, 0},
+ {"Source64", Type, 8},
+ {"Uint32", Func, 0},
+ {"Uint64", Func, 8},
+ {"Zipf", Type, 0},
+ },
+ "math/rand/v2": {
+ {"(*ChaCha8).MarshalBinary", Method, 22},
+ {"(*ChaCha8).Read", Method, 23},
+ {"(*ChaCha8).Seed", Method, 22},
+ {"(*ChaCha8).Uint64", Method, 22},
+ {"(*ChaCha8).UnmarshalBinary", Method, 22},
+ {"(*PCG).MarshalBinary", Method, 22},
+ {"(*PCG).Seed", Method, 22},
+ {"(*PCG).Uint64", Method, 22},
+ {"(*PCG).UnmarshalBinary", Method, 22},
+ {"(*Rand).ExpFloat64", Method, 22},
+ {"(*Rand).Float32", Method, 22},
+ {"(*Rand).Float64", Method, 22},
+ {"(*Rand).Int", Method, 22},
+ {"(*Rand).Int32", Method, 22},
+ {"(*Rand).Int32N", Method, 22},
+ {"(*Rand).Int64", Method, 22},
+ {"(*Rand).Int64N", Method, 22},
+ {"(*Rand).IntN", Method, 22},
+ {"(*Rand).NormFloat64", Method, 22},
+ {"(*Rand).Perm", Method, 22},
+ {"(*Rand).Shuffle", Method, 22},
+ {"(*Rand).Uint", Method, 23},
+ {"(*Rand).Uint32", Method, 22},
+ {"(*Rand).Uint32N", Method, 22},
+ {"(*Rand).Uint64", Method, 22},
+ {"(*Rand).Uint64N", Method, 22},
+ {"(*Rand).UintN", Method, 22},
+ {"(*Zipf).Uint64", Method, 22},
+ {"ChaCha8", Type, 22},
+ {"ExpFloat64", Func, 22},
+ {"Float32", Func, 22},
+ {"Float64", Func, 22},
+ {"Int", Func, 22},
+ {"Int32", Func, 22},
+ {"Int32N", Func, 22},
+ {"Int64", Func, 22},
+ {"Int64N", Func, 22},
+ {"IntN", Func, 22},
+ {"N", Func, 22},
+ {"New", Func, 22},
+ {"NewChaCha8", Func, 22},
+ {"NewPCG", Func, 22},
+ {"NewZipf", Func, 22},
+ {"NormFloat64", Func, 22},
+ {"PCG", Type, 22},
+ {"Perm", Func, 22},
+ {"Rand", Type, 22},
+ {"Shuffle", Func, 22},
+ {"Source", Type, 22},
+ {"Uint", Func, 23},
+ {"Uint32", Func, 22},
+ {"Uint32N", Func, 22},
+ {"Uint64", Func, 22},
+ {"Uint64N", Func, 22},
+ {"UintN", Func, 22},
+ {"Zipf", Type, 22},
+ },
+ "mime": {
+ {"(*WordDecoder).Decode", Method, 5},
+ {"(*WordDecoder).DecodeHeader", Method, 5},
+ {"(WordEncoder).Encode", Method, 5},
+ {"AddExtensionType", Func, 0},
+ {"BEncoding", Const, 5},
+ {"ErrInvalidMediaParameter", Var, 9},
+ {"ExtensionsByType", Func, 5},
+ {"FormatMediaType", Func, 0},
+ {"ParseMediaType", Func, 0},
+ {"QEncoding", Const, 5},
+ {"TypeByExtension", Func, 0},
+ {"WordDecoder", Type, 5},
+ {"WordDecoder.CharsetReader", Field, 5},
+ {"WordEncoder", Type, 5},
+ },
+ "mime/multipart": {
+ {"(*FileHeader).Open", Method, 0},
+ {"(*Form).RemoveAll", Method, 0},
+ {"(*Part).Close", Method, 0},
+ {"(*Part).FileName", Method, 0},
+ {"(*Part).FormName", Method, 0},
+ {"(*Part).Read", Method, 0},
+ {"(*Reader).NextPart", Method, 0},
+ {"(*Reader).NextRawPart", Method, 14},
+ {"(*Reader).ReadForm", Method, 0},
+ {"(*Writer).Boundary", Method, 0},
+ {"(*Writer).Close", Method, 0},
+ {"(*Writer).CreateFormField", Method, 0},
+ {"(*Writer).CreateFormFile", Method, 0},
+ {"(*Writer).CreatePart", Method, 0},
+ {"(*Writer).FormDataContentType", Method, 0},
+ {"(*Writer).SetBoundary", Method, 1},
+ {"(*Writer).WriteField", Method, 0},
+ {"ErrMessageTooLarge", Var, 9},
+ {"File", Type, 0},
+ {"FileHeader", Type, 0},
+ {"FileHeader.Filename", Field, 0},
+ {"FileHeader.Header", Field, 0},
+ {"FileHeader.Size", Field, 9},
+ {"Form", Type, 0},
+ {"Form.File", Field, 0},
+ {"Form.Value", Field, 0},
+ {"NewReader", Func, 0},
+ {"NewWriter", Func, 0},
+ {"Part", Type, 0},
+ {"Part.Header", Field, 0},
+ {"Reader", Type, 0},
+ {"Writer", Type, 0},
+ },
+ "mime/quotedprintable": {
+ {"(*Reader).Read", Method, 5},
+ {"(*Writer).Close", Method, 5},
+ {"(*Writer).Write", Method, 5},
+ {"NewReader", Func, 5},
+ {"NewWriter", Func, 5},
+ {"Reader", Type, 5},
+ {"Writer", Type, 5},
+ {"Writer.Binary", Field, 5},
+ },
+ "net": {
+ {"(*AddrError).Error", Method, 0},
+ {"(*AddrError).Temporary", Method, 0},
+ {"(*AddrError).Timeout", Method, 0},
+ {"(*Buffers).Read", Method, 8},
+ {"(*Buffers).WriteTo", Method, 8},
+ {"(*DNSConfigError).Error", Method, 0},
+ {"(*DNSConfigError).Temporary", Method, 0},
+ {"(*DNSConfigError).Timeout", Method, 0},
+ {"(*DNSConfigError).Unwrap", Method, 13},
+ {"(*DNSError).Error", Method, 0},
+ {"(*DNSError).Temporary", Method, 0},
+ {"(*DNSError).Timeout", Method, 0},
+ {"(*DNSError).Unwrap", Method, 23},
+ {"(*Dialer).Dial", Method, 1},
+ {"(*Dialer).DialContext", Method, 7},
+ {"(*Dialer).MultipathTCP", Method, 21},
+ {"(*Dialer).SetMultipathTCP", Method, 21},
+ {"(*IP).UnmarshalText", Method, 2},
+ {"(*IPAddr).Network", Method, 0},
+ {"(*IPAddr).String", Method, 0},
+ {"(*IPConn).Close", Method, 0},
+ {"(*IPConn).File", Method, 0},
+ {"(*IPConn).LocalAddr", Method, 0},
+ {"(*IPConn).Read", Method, 0},
+ {"(*IPConn).ReadFrom", Method, 0},
+ {"(*IPConn).ReadFromIP", Method, 0},
+ {"(*IPConn).ReadMsgIP", Method, 1},
+ {"(*IPConn).RemoteAddr", Method, 0},
+ {"(*IPConn).SetDeadline", Method, 0},
+ {"(*IPConn).SetReadBuffer", Method, 0},
+ {"(*IPConn).SetReadDeadline", Method, 0},
+ {"(*IPConn).SetWriteBuffer", Method, 0},
+ {"(*IPConn).SetWriteDeadline", Method, 0},
+ {"(*IPConn).SyscallConn", Method, 9},
+ {"(*IPConn).Write", Method, 0},
+ {"(*IPConn).WriteMsgIP", Method, 1},
+ {"(*IPConn).WriteTo", Method, 0},
+ {"(*IPConn).WriteToIP", Method, 0},
+ {"(*IPNet).Contains", Method, 0},
+ {"(*IPNet).Network", Method, 0},
+ {"(*IPNet).String", Method, 0},
+ {"(*Interface).Addrs", Method, 0},
+ {"(*Interface).MulticastAddrs", Method, 0},
+ {"(*ListenConfig).Listen", Method, 11},
+ {"(*ListenConfig).ListenPacket", Method, 11},
+ {"(*ListenConfig).MultipathTCP", Method, 21},
+ {"(*ListenConfig).SetMultipathTCP", Method, 21},
+ {"(*OpError).Error", Method, 0},
+ {"(*OpError).Temporary", Method, 0},
+ {"(*OpError).Timeout", Method, 0},
+ {"(*OpError).Unwrap", Method, 13},
+ {"(*ParseError).Error", Method, 0},
+ {"(*ParseError).Temporary", Method, 17},
+ {"(*ParseError).Timeout", Method, 17},
+ {"(*Resolver).LookupAddr", Method, 8},
+ {"(*Resolver).LookupCNAME", Method, 8},
+ {"(*Resolver).LookupHost", Method, 8},
+ {"(*Resolver).LookupIP", Method, 15},
+ {"(*Resolver).LookupIPAddr", Method, 8},
+ {"(*Resolver).LookupMX", Method, 8},
+ {"(*Resolver).LookupNS", Method, 8},
+ {"(*Resolver).LookupNetIP", Method, 18},
+ {"(*Resolver).LookupPort", Method, 8},
+ {"(*Resolver).LookupSRV", Method, 8},
+ {"(*Resolver).LookupTXT", Method, 8},
+ {"(*TCPAddr).AddrPort", Method, 18},
+ {"(*TCPAddr).Network", Method, 0},
+ {"(*TCPAddr).String", Method, 0},
+ {"(*TCPConn).Close", Method, 0},
+ {"(*TCPConn).CloseRead", Method, 0},
+ {"(*TCPConn).CloseWrite", Method, 0},
+ {"(*TCPConn).File", Method, 0},
+ {"(*TCPConn).LocalAddr", Method, 0},
+ {"(*TCPConn).MultipathTCP", Method, 21},
+ {"(*TCPConn).Read", Method, 0},
+ {"(*TCPConn).ReadFrom", Method, 0},
+ {"(*TCPConn).RemoteAddr", Method, 0},
+ {"(*TCPConn).SetDeadline", Method, 0},
+ {"(*TCPConn).SetKeepAlive", Method, 0},
+ {"(*TCPConn).SetKeepAliveConfig", Method, 23},
+ {"(*TCPConn).SetKeepAlivePeriod", Method, 2},
+ {"(*TCPConn).SetLinger", Method, 0},
+ {"(*TCPConn).SetNoDelay", Method, 0},
+ {"(*TCPConn).SetReadBuffer", Method, 0},
+ {"(*TCPConn).SetReadDeadline", Method, 0},
+ {"(*TCPConn).SetWriteBuffer", Method, 0},
+ {"(*TCPConn).SetWriteDeadline", Method, 0},
+ {"(*TCPConn).SyscallConn", Method, 9},
+ {"(*TCPConn).Write", Method, 0},
+ {"(*TCPConn).WriteTo", Method, 22},
+ {"(*TCPListener).Accept", Method, 0},
+ {"(*TCPListener).AcceptTCP", Method, 0},
+ {"(*TCPListener).Addr", Method, 0},
+ {"(*TCPListener).Close", Method, 0},
+ {"(*TCPListener).File", Method, 0},
+ {"(*TCPListener).SetDeadline", Method, 0},
+ {"(*TCPListener).SyscallConn", Method, 10},
+ {"(*UDPAddr).AddrPort", Method, 18},
+ {"(*UDPAddr).Network", Method, 0},
+ {"(*UDPAddr).String", Method, 0},
+ {"(*UDPConn).Close", Method, 0},
+ {"(*UDPConn).File", Method, 0},
+ {"(*UDPConn).LocalAddr", Method, 0},
+ {"(*UDPConn).Read", Method, 0},
+ {"(*UDPConn).ReadFrom", Method, 0},
+ {"(*UDPConn).ReadFromUDP", Method, 0},
+ {"(*UDPConn).ReadFromUDPAddrPort", Method, 18},
+ {"(*UDPConn).ReadMsgUDP", Method, 1},
+ {"(*UDPConn).ReadMsgUDPAddrPort", Method, 18},
+ {"(*UDPConn).RemoteAddr", Method, 0},
+ {"(*UDPConn).SetDeadline", Method, 0},
+ {"(*UDPConn).SetReadBuffer", Method, 0},
+ {"(*UDPConn).SetReadDeadline", Method, 0},
+ {"(*UDPConn).SetWriteBuffer", Method, 0},
+ {"(*UDPConn).SetWriteDeadline", Method, 0},
+ {"(*UDPConn).SyscallConn", Method, 9},
+ {"(*UDPConn).Write", Method, 0},
+ {"(*UDPConn).WriteMsgUDP", Method, 1},
+ {"(*UDPConn).WriteMsgUDPAddrPort", Method, 18},
+ {"(*UDPConn).WriteTo", Method, 0},
+ {"(*UDPConn).WriteToUDP", Method, 0},
+ {"(*UDPConn).WriteToUDPAddrPort", Method, 18},
+ {"(*UnixAddr).Network", Method, 0},
+ {"(*UnixAddr).String", Method, 0},
+ {"(*UnixConn).Close", Method, 0},
+ {"(*UnixConn).CloseRead", Method, 1},
+ {"(*UnixConn).CloseWrite", Method, 1},
+ {"(*UnixConn).File", Method, 0},
+ {"(*UnixConn).LocalAddr", Method, 0},
+ {"(*UnixConn).Read", Method, 0},
+ {"(*UnixConn).ReadFrom", Method, 0},
+ {"(*UnixConn).ReadFromUnix", Method, 0},
+ {"(*UnixConn).ReadMsgUnix", Method, 0},
+ {"(*UnixConn).RemoteAddr", Method, 0},
+ {"(*UnixConn).SetDeadline", Method, 0},
+ {"(*UnixConn).SetReadBuffer", Method, 0},
+ {"(*UnixConn).SetReadDeadline", Method, 0},
+ {"(*UnixConn).SetWriteBuffer", Method, 0},
+ {"(*UnixConn).SetWriteDeadline", Method, 0},
+ {"(*UnixConn).SyscallConn", Method, 9},
+ {"(*UnixConn).Write", Method, 0},
+ {"(*UnixConn).WriteMsgUnix", Method, 0},
+ {"(*UnixConn).WriteTo", Method, 0},
+ {"(*UnixConn).WriteToUnix", Method, 0},
+ {"(*UnixListener).Accept", Method, 0},
+ {"(*UnixListener).AcceptUnix", Method, 0},
+ {"(*UnixListener).Addr", Method, 0},
+ {"(*UnixListener).Close", Method, 0},
+ {"(*UnixListener).File", Method, 0},
+ {"(*UnixListener).SetDeadline", Method, 0},
+ {"(*UnixListener).SetUnlinkOnClose", Method, 8},
+ {"(*UnixListener).SyscallConn", Method, 10},
+ {"(Flags).String", Method, 0},
+ {"(HardwareAddr).String", Method, 0},
+ {"(IP).DefaultMask", Method, 0},
+ {"(IP).Equal", Method, 0},
+ {"(IP).IsGlobalUnicast", Method, 0},
+ {"(IP).IsInterfaceLocalMulticast", Method, 0},
+ {"(IP).IsLinkLocalMulticast", Method, 0},
+ {"(IP).IsLinkLocalUnicast", Method, 0},
+ {"(IP).IsLoopback", Method, 0},
+ {"(IP).IsMulticast", Method, 0},
+ {"(IP).IsPrivate", Method, 17},
+ {"(IP).IsUnspecified", Method, 0},
+ {"(IP).MarshalText", Method, 2},
+ {"(IP).Mask", Method, 0},
+ {"(IP).String", Method, 0},
+ {"(IP).To16", Method, 0},
+ {"(IP).To4", Method, 0},
+ {"(IPMask).Size", Method, 0},
+ {"(IPMask).String", Method, 0},
+ {"(InvalidAddrError).Error", Method, 0},
+ {"(InvalidAddrError).Temporary", Method, 0},
+ {"(InvalidAddrError).Timeout", Method, 0},
+ {"(UnknownNetworkError).Error", Method, 0},
+ {"(UnknownNetworkError).Temporary", Method, 0},
+ {"(UnknownNetworkError).Timeout", Method, 0},
+ {"Addr", Type, 0},
+ {"AddrError", Type, 0},
+ {"AddrError.Addr", Field, 0},
+ {"AddrError.Err", Field, 0},
+ {"Buffers", Type, 8},
+ {"CIDRMask", Func, 0},
+ {"Conn", Type, 0},
+ {"DNSConfigError", Type, 0},
+ {"DNSConfigError.Err", Field, 0},
+ {"DNSError", Type, 0},
+ {"DNSError.Err", Field, 0},
+ {"DNSError.IsNotFound", Field, 13},
+ {"DNSError.IsTemporary", Field, 6},
+ {"DNSError.IsTimeout", Field, 0},
+ {"DNSError.Name", Field, 0},
+ {"DNSError.Server", Field, 0},
+ {"DNSError.UnwrapErr", Field, 23},
+ {"DefaultResolver", Var, 8},
+ {"Dial", Func, 0},
+ {"DialIP", Func, 0},
+ {"DialTCP", Func, 0},
+ {"DialTimeout", Func, 0},
+ {"DialUDP", Func, 0},
+ {"DialUnix", Func, 0},
+ {"Dialer", Type, 1},
+ {"Dialer.Cancel", Field, 6},
+ {"Dialer.Control", Field, 11},
+ {"Dialer.ControlContext", Field, 20},
+ {"Dialer.Deadline", Field, 1},
+ {"Dialer.DualStack", Field, 2},
+ {"Dialer.FallbackDelay", Field, 5},
+ {"Dialer.KeepAlive", Field, 3},
+ {"Dialer.KeepAliveConfig", Field, 23},
+ {"Dialer.LocalAddr", Field, 1},
+ {"Dialer.Resolver", Field, 8},
+ {"Dialer.Timeout", Field, 1},
+ {"ErrClosed", Var, 16},
+ {"ErrWriteToConnected", Var, 0},
+ {"Error", Type, 0},
+ {"FileConn", Func, 0},
+ {"FileListener", Func, 0},
+ {"FilePacketConn", Func, 0},
+ {"FlagBroadcast", Const, 0},
+ {"FlagLoopback", Const, 0},
+ {"FlagMulticast", Const, 0},
+ {"FlagPointToPoint", Const, 0},
+ {"FlagRunning", Const, 20},
+ {"FlagUp", Const, 0},
+ {"Flags", Type, 0},
+ {"HardwareAddr", Type, 0},
+ {"IP", Type, 0},
+ {"IPAddr", Type, 0},
+ {"IPAddr.IP", Field, 0},
+ {"IPAddr.Zone", Field, 1},
+ {"IPConn", Type, 0},
+ {"IPMask", Type, 0},
+ {"IPNet", Type, 0},
+ {"IPNet.IP", Field, 0},
+ {"IPNet.Mask", Field, 0},
+ {"IPv4", Func, 0},
+ {"IPv4Mask", Func, 0},
+ {"IPv4allrouter", Var, 0},
+ {"IPv4allsys", Var, 0},
+ {"IPv4bcast", Var, 0},
+ {"IPv4len", Const, 0},
+ {"IPv4zero", Var, 0},
+ {"IPv6interfacelocalallnodes", Var, 0},
+ {"IPv6len", Const, 0},
+ {"IPv6linklocalallnodes", Var, 0},
+ {"IPv6linklocalallrouters", Var, 0},
+ {"IPv6loopback", Var, 0},
+ {"IPv6unspecified", Var, 0},
+ {"IPv6zero", Var, 0},
+ {"Interface", Type, 0},
+ {"Interface.Flags", Field, 0},
+ {"Interface.HardwareAddr", Field, 0},
+ {"Interface.Index", Field, 0},
+ {"Interface.MTU", Field, 0},
+ {"Interface.Name", Field, 0},
+ {"InterfaceAddrs", Func, 0},
+ {"InterfaceByIndex", Func, 0},
+ {"InterfaceByName", Func, 0},
+ {"Interfaces", Func, 0},
+ {"InvalidAddrError", Type, 0},
+ {"JoinHostPort", Func, 0},
+ {"KeepAliveConfig", Type, 23},
+ {"KeepAliveConfig.Count", Field, 23},
+ {"KeepAliveConfig.Enable", Field, 23},
+ {"KeepAliveConfig.Idle", Field, 23},
+ {"KeepAliveConfig.Interval", Field, 23},
+ {"Listen", Func, 0},
+ {"ListenConfig", Type, 11},
+ {"ListenConfig.Control", Field, 11},
+ {"ListenConfig.KeepAlive", Field, 13},
+ {"ListenConfig.KeepAliveConfig", Field, 23},
+ {"ListenIP", Func, 0},
+ {"ListenMulticastUDP", Func, 0},
+ {"ListenPacket", Func, 0},
+ {"ListenTCP", Func, 0},
+ {"ListenUDP", Func, 0},
+ {"ListenUnix", Func, 0},
+ {"ListenUnixgram", Func, 0},
+ {"Listener", Type, 0},
+ {"LookupAddr", Func, 0},
+ {"LookupCNAME", Func, 0},
+ {"LookupHost", Func, 0},
+ {"LookupIP", Func, 0},
+ {"LookupMX", Func, 0},
+ {"LookupNS", Func, 1},
+ {"LookupPort", Func, 0},
+ {"LookupSRV", Func, 0},
+ {"LookupTXT", Func, 0},
+ {"MX", Type, 0},
+ {"MX.Host", Field, 0},
+ {"MX.Pref", Field, 0},
+ {"NS", Type, 1},
+ {"NS.Host", Field, 1},
+ {"OpError", Type, 0},
+ {"OpError.Addr", Field, 0},
+ {"OpError.Err", Field, 0},
+ {"OpError.Net", Field, 0},
+ {"OpError.Op", Field, 0},
+ {"OpError.Source", Field, 5},
+ {"PacketConn", Type, 0},
+ {"ParseCIDR", Func, 0},
+ {"ParseError", Type, 0},
+ {"ParseError.Text", Field, 0},
+ {"ParseError.Type", Field, 0},
+ {"ParseIP", Func, 0},
+ {"ParseMAC", Func, 0},
+ {"Pipe", Func, 0},
+ {"ResolveIPAddr", Func, 0},
+ {"ResolveTCPAddr", Func, 0},
+ {"ResolveUDPAddr", Func, 0},
+ {"ResolveUnixAddr", Func, 0},
+ {"Resolver", Type, 8},
+ {"Resolver.Dial", Field, 9},
+ {"Resolver.PreferGo", Field, 8},
+ {"Resolver.StrictErrors", Field, 9},
+ {"SRV", Type, 0},
+ {"SRV.Port", Field, 0},
+ {"SRV.Priority", Field, 0},
+ {"SRV.Target", Field, 0},
+ {"SRV.Weight", Field, 0},
+ {"SplitHostPort", Func, 0},
+ {"TCPAddr", Type, 0},
+ {"TCPAddr.IP", Field, 0},
+ {"TCPAddr.Port", Field, 0},
+ {"TCPAddr.Zone", Field, 1},
+ {"TCPAddrFromAddrPort", Func, 18},
+ {"TCPConn", Type, 0},
+ {"TCPListener", Type, 0},
+ {"UDPAddr", Type, 0},
+ {"UDPAddr.IP", Field, 0},
+ {"UDPAddr.Port", Field, 0},
+ {"UDPAddr.Zone", Field, 1},
+ {"UDPAddrFromAddrPort", Func, 18},
+ {"UDPConn", Type, 0},
+ {"UnixAddr", Type, 0},
+ {"UnixAddr.Name", Field, 0},
+ {"UnixAddr.Net", Field, 0},
+ {"UnixConn", Type, 0},
+ {"UnixListener", Type, 0},
+ {"UnknownNetworkError", Type, 0},
+ },
+ "net/http": {
+ {"(*Client).CloseIdleConnections", Method, 12},
+ {"(*Client).Do", Method, 0},
+ {"(*Client).Get", Method, 0},
+ {"(*Client).Head", Method, 0},
+ {"(*Client).Post", Method, 0},
+ {"(*Client).PostForm", Method, 0},
+ {"(*Cookie).String", Method, 0},
+ {"(*Cookie).Valid", Method, 18},
+ {"(*MaxBytesError).Error", Method, 19},
+ {"(*ProtocolError).Error", Method, 0},
+ {"(*ProtocolError).Is", Method, 21},
+ {"(*Request).AddCookie", Method, 0},
+ {"(*Request).BasicAuth", Method, 4},
+ {"(*Request).Clone", Method, 13},
+ {"(*Request).Context", Method, 7},
+ {"(*Request).Cookie", Method, 0},
+ {"(*Request).Cookies", Method, 0},
+ {"(*Request).CookiesNamed", Method, 23},
+ {"(*Request).FormFile", Method, 0},
+ {"(*Request).FormValue", Method, 0},
+ {"(*Request).MultipartReader", Method, 0},
+ {"(*Request).ParseForm", Method, 0},
+ {"(*Request).ParseMultipartForm", Method, 0},
+ {"(*Request).PathValue", Method, 22},
+ {"(*Request).PostFormValue", Method, 1},
+ {"(*Request).ProtoAtLeast", Method, 0},
+ {"(*Request).Referer", Method, 0},
+ {"(*Request).SetBasicAuth", Method, 0},
+ {"(*Request).SetPathValue", Method, 22},
+ {"(*Request).UserAgent", Method, 0},
+ {"(*Request).WithContext", Method, 7},
+ {"(*Request).Write", Method, 0},
+ {"(*Request).WriteProxy", Method, 0},
+ {"(*Response).Cookies", Method, 0},
+ {"(*Response).Location", Method, 0},
+ {"(*Response).ProtoAtLeast", Method, 0},
+ {"(*Response).Write", Method, 0},
+ {"(*ResponseController).EnableFullDuplex", Method, 21},
+ {"(*ResponseController).Flush", Method, 20},
+ {"(*ResponseController).Hijack", Method, 20},
+ {"(*ResponseController).SetReadDeadline", Method, 20},
+ {"(*ResponseController).SetWriteDeadline", Method, 20},
+ {"(*ServeMux).Handle", Method, 0},
+ {"(*ServeMux).HandleFunc", Method, 0},
+ {"(*ServeMux).Handler", Method, 1},
+ {"(*ServeMux).ServeHTTP", Method, 0},
+ {"(*Server).Close", Method, 8},
+ {"(*Server).ListenAndServe", Method, 0},
+ {"(*Server).ListenAndServeTLS", Method, 0},
+ {"(*Server).RegisterOnShutdown", Method, 9},
+ {"(*Server).Serve", Method, 0},
+ {"(*Server).ServeTLS", Method, 9},
+ {"(*Server).SetKeepAlivesEnabled", Method, 3},
+ {"(*Server).Shutdown", Method, 8},
+ {"(*Transport).CancelRequest", Method, 1},
+ {"(*Transport).Clone", Method, 13},
+ {"(*Transport).CloseIdleConnections", Method, 0},
+ {"(*Transport).RegisterProtocol", Method, 0},
+ {"(*Transport).RoundTrip", Method, 0},
+ {"(ConnState).String", Method, 3},
+ {"(Dir).Open", Method, 0},
+ {"(HandlerFunc).ServeHTTP", Method, 0},
+ {"(Header).Add", Method, 0},
+ {"(Header).Clone", Method, 13},
+ {"(Header).Del", Method, 0},
+ {"(Header).Get", Method, 0},
+ {"(Header).Set", Method, 0},
+ {"(Header).Values", Method, 14},
+ {"(Header).Write", Method, 0},
+ {"(Header).WriteSubset", Method, 0},
+ {"AllowQuerySemicolons", Func, 17},
+ {"CanonicalHeaderKey", Func, 0},
+ {"Client", Type, 0},
+ {"Client.CheckRedirect", Field, 0},
+ {"Client.Jar", Field, 0},
+ {"Client.Timeout", Field, 3},
+ {"Client.Transport", Field, 0},
+ {"CloseNotifier", Type, 1},
+ {"ConnState", Type, 3},
+ {"Cookie", Type, 0},
+ {"Cookie.Domain", Field, 0},
+ {"Cookie.Expires", Field, 0},
+ {"Cookie.HttpOnly", Field, 0},
+ {"Cookie.MaxAge", Field, 0},
+ {"Cookie.Name", Field, 0},
+ {"Cookie.Partitioned", Field, 23},
+ {"Cookie.Path", Field, 0},
+ {"Cookie.Quoted", Field, 23},
+ {"Cookie.Raw", Field, 0},
+ {"Cookie.RawExpires", Field, 0},
+ {"Cookie.SameSite", Field, 11},
+ {"Cookie.Secure", Field, 0},
+ {"Cookie.Unparsed", Field, 0},
+ {"Cookie.Value", Field, 0},
+ {"CookieJar", Type, 0},
+ {"DefaultClient", Var, 0},
+ {"DefaultMaxHeaderBytes", Const, 0},
+ {"DefaultMaxIdleConnsPerHost", Const, 0},
+ {"DefaultServeMux", Var, 0},
+ {"DefaultTransport", Var, 0},
+ {"DetectContentType", Func, 0},
+ {"Dir", Type, 0},
+ {"ErrAbortHandler", Var, 8},
+ {"ErrBodyNotAllowed", Var, 0},
+ {"ErrBodyReadAfterClose", Var, 0},
+ {"ErrContentLength", Var, 0},
+ {"ErrHandlerTimeout", Var, 0},
+ {"ErrHeaderTooLong", Var, 0},
+ {"ErrHijacked", Var, 0},
+ {"ErrLineTooLong", Var, 0},
+ {"ErrMissingBoundary", Var, 0},
+ {"ErrMissingContentLength", Var, 0},
+ {"ErrMissingFile", Var, 0},
+ {"ErrNoCookie", Var, 0},
+ {"ErrNoLocation", Var, 0},
+ {"ErrNotMultipart", Var, 0},
+ {"ErrNotSupported", Var, 0},
+ {"ErrSchemeMismatch", Var, 21},
+ {"ErrServerClosed", Var, 8},
+ {"ErrShortBody", Var, 0},
+ {"ErrSkipAltProtocol", Var, 6},
+ {"ErrUnexpectedTrailer", Var, 0},
+ {"ErrUseLastResponse", Var, 7},
+ {"ErrWriteAfterFlush", Var, 0},
+ {"Error", Func, 0},
+ {"FS", Func, 16},
+ {"File", Type, 0},
+ {"FileServer", Func, 0},
+ {"FileServerFS", Func, 22},
+ {"FileSystem", Type, 0},
+ {"Flusher", Type, 0},
+ {"Get", Func, 0},
+ {"Handle", Func, 0},
+ {"HandleFunc", Func, 0},
+ {"Handler", Type, 0},
+ {"HandlerFunc", Type, 0},
+ {"Head", Func, 0},
+ {"Header", Type, 0},
+ {"Hijacker", Type, 0},
+ {"ListenAndServe", Func, 0},
+ {"ListenAndServeTLS", Func, 0},
+ {"LocalAddrContextKey", Var, 7},
+ {"MaxBytesError", Type, 19},
+ {"MaxBytesError.Limit", Field, 19},
+ {"MaxBytesHandler", Func, 18},
+ {"MaxBytesReader", Func, 0},
+ {"MethodConnect", Const, 6},
+ {"MethodDelete", Const, 6},
+ {"MethodGet", Const, 6},
+ {"MethodHead", Const, 6},
+ {"MethodOptions", Const, 6},
+ {"MethodPatch", Const, 6},
+ {"MethodPost", Const, 6},
+ {"MethodPut", Const, 6},
+ {"MethodTrace", Const, 6},
+ {"NewFileTransport", Func, 0},
+ {"NewFileTransportFS", Func, 22},
+ {"NewRequest", Func, 0},
+ {"NewRequestWithContext", Func, 13},
+ {"NewResponseController", Func, 20},
+ {"NewServeMux", Func, 0},
+ {"NoBody", Var, 8},
+ {"NotFound", Func, 0},
+ {"NotFoundHandler", Func, 0},
+ {"ParseCookie", Func, 23},
+ {"ParseHTTPVersion", Func, 0},
+ {"ParseSetCookie", Func, 23},
+ {"ParseTime", Func, 1},
+ {"Post", Func, 0},
+ {"PostForm", Func, 0},
+ {"ProtocolError", Type, 0},
+ {"ProtocolError.ErrorString", Field, 0},
+ {"ProxyFromEnvironment", Func, 0},
+ {"ProxyURL", Func, 0},
+ {"PushOptions", Type, 8},
+ {"PushOptions.Header", Field, 8},
+ {"PushOptions.Method", Field, 8},
+ {"Pusher", Type, 8},
+ {"ReadRequest", Func, 0},
+ {"ReadResponse", Func, 0},
+ {"Redirect", Func, 0},
+ {"RedirectHandler", Func, 0},
+ {"Request", Type, 0},
+ {"Request.Body", Field, 0},
+ {"Request.Cancel", Field, 5},
+ {"Request.Close", Field, 0},
+ {"Request.ContentLength", Field, 0},
+ {"Request.Form", Field, 0},
+ {"Request.GetBody", Field, 8},
+ {"Request.Header", Field, 0},
+ {"Request.Host", Field, 0},
+ {"Request.Method", Field, 0},
+ {"Request.MultipartForm", Field, 0},
+ {"Request.Pattern", Field, 23},
+ {"Request.PostForm", Field, 1},
+ {"Request.Proto", Field, 0},
+ {"Request.ProtoMajor", Field, 0},
+ {"Request.ProtoMinor", Field, 0},
+ {"Request.RemoteAddr", Field, 0},
+ {"Request.RequestURI", Field, 0},
+ {"Request.Response", Field, 7},
+ {"Request.TLS", Field, 0},
+ {"Request.Trailer", Field, 0},
+ {"Request.TransferEncoding", Field, 0},
+ {"Request.URL", Field, 0},
+ {"Response", Type, 0},
+ {"Response.Body", Field, 0},
+ {"Response.Close", Field, 0},
+ {"Response.ContentLength", Field, 0},
+ {"Response.Header", Field, 0},
+ {"Response.Proto", Field, 0},
+ {"Response.ProtoMajor", Field, 0},
+ {"Response.ProtoMinor", Field, 0},
+ {"Response.Request", Field, 0},
+ {"Response.Status", Field, 0},
+ {"Response.StatusCode", Field, 0},
+ {"Response.TLS", Field, 3},
+ {"Response.Trailer", Field, 0},
+ {"Response.TransferEncoding", Field, 0},
+ {"Response.Uncompressed", Field, 7},
+ {"ResponseController", Type, 20},
+ {"ResponseWriter", Type, 0},
+ {"RoundTripper", Type, 0},
+ {"SameSite", Type, 11},
+ {"SameSiteDefaultMode", Const, 11},
+ {"SameSiteLaxMode", Const, 11},
+ {"SameSiteNoneMode", Const, 13},
+ {"SameSiteStrictMode", Const, 11},
+ {"Serve", Func, 0},
+ {"ServeContent", Func, 0},
+ {"ServeFile", Func, 0},
+ {"ServeFileFS", Func, 22},
+ {"ServeMux", Type, 0},
+ {"ServeTLS", Func, 9},
+ {"Server", Type, 0},
+ {"Server.Addr", Field, 0},
+ {"Server.BaseContext", Field, 13},
+ {"Server.ConnContext", Field, 13},
+ {"Server.ConnState", Field, 3},
+ {"Server.DisableGeneralOptionsHandler", Field, 20},
+ {"Server.ErrorLog", Field, 3},
+ {"Server.Handler", Field, 0},
+ {"Server.IdleTimeout", Field, 8},
+ {"Server.MaxHeaderBytes", Field, 0},
+ {"Server.ReadHeaderTimeout", Field, 8},
+ {"Server.ReadTimeout", Field, 0},
+ {"Server.TLSConfig", Field, 0},
+ {"Server.TLSNextProto", Field, 1},
+ {"Server.WriteTimeout", Field, 0},
+ {"ServerContextKey", Var, 7},
+ {"SetCookie", Func, 0},
+ {"StateActive", Const, 3},
+ {"StateClosed", Const, 3},
+ {"StateHijacked", Const, 3},
+ {"StateIdle", Const, 3},
+ {"StateNew", Const, 3},
+ {"StatusAccepted", Const, 0},
+ {"StatusAlreadyReported", Const, 7},
+ {"StatusBadGateway", Const, 0},
+ {"StatusBadRequest", Const, 0},
+ {"StatusConflict", Const, 0},
+ {"StatusContinue", Const, 0},
+ {"StatusCreated", Const, 0},
+ {"StatusEarlyHints", Const, 13},
+ {"StatusExpectationFailed", Const, 0},
+ {"StatusFailedDependency", Const, 7},
+ {"StatusForbidden", Const, 0},
+ {"StatusFound", Const, 0},
+ {"StatusGatewayTimeout", Const, 0},
+ {"StatusGone", Const, 0},
+ {"StatusHTTPVersionNotSupported", Const, 0},
+ {"StatusIMUsed", Const, 7},
+ {"StatusInsufficientStorage", Const, 7},
+ {"StatusInternalServerError", Const, 0},
+ {"StatusLengthRequired", Const, 0},
+ {"StatusLocked", Const, 7},
+ {"StatusLoopDetected", Const, 7},
+ {"StatusMethodNotAllowed", Const, 0},
+ {"StatusMisdirectedRequest", Const, 11},
+ {"StatusMovedPermanently", Const, 0},
+ {"StatusMultiStatus", Const, 7},
+ {"StatusMultipleChoices", Const, 0},
+ {"StatusNetworkAuthenticationRequired", Const, 6},
+ {"StatusNoContent", Const, 0},
+ {"StatusNonAuthoritativeInfo", Const, 0},
+ {"StatusNotAcceptable", Const, 0},
+ {"StatusNotExtended", Const, 7},
+ {"StatusNotFound", Const, 0},
+ {"StatusNotImplemented", Const, 0},
+ {"StatusNotModified", Const, 0},
+ {"StatusOK", Const, 0},
+ {"StatusPartialContent", Const, 0},
+ {"StatusPaymentRequired", Const, 0},
+ {"StatusPermanentRedirect", Const, 7},
+ {"StatusPreconditionFailed", Const, 0},
+ {"StatusPreconditionRequired", Const, 6},
+ {"StatusProcessing", Const, 7},
+ {"StatusProxyAuthRequired", Const, 0},
+ {"StatusRequestEntityTooLarge", Const, 0},
+ {"StatusRequestHeaderFieldsTooLarge", Const, 6},
+ {"StatusRequestTimeout", Const, 0},
+ {"StatusRequestURITooLong", Const, 0},
+ {"StatusRequestedRangeNotSatisfiable", Const, 0},
+ {"StatusResetContent", Const, 0},
+ {"StatusSeeOther", Const, 0},
+ {"StatusServiceUnavailable", Const, 0},
+ {"StatusSwitchingProtocols", Const, 0},
+ {"StatusTeapot", Const, 0},
+ {"StatusTemporaryRedirect", Const, 0},
+ {"StatusText", Func, 0},
+ {"StatusTooEarly", Const, 12},
+ {"StatusTooManyRequests", Const, 6},
+ {"StatusUnauthorized", Const, 0},
+ {"StatusUnavailableForLegalReasons", Const, 6},
+ {"StatusUnprocessableEntity", Const, 7},
+ {"StatusUnsupportedMediaType", Const, 0},
+ {"StatusUpgradeRequired", Const, 7},
+ {"StatusUseProxy", Const, 0},
+ {"StatusVariantAlsoNegotiates", Const, 7},
+ {"StripPrefix", Func, 0},
+ {"TimeFormat", Const, 0},
+ {"TimeoutHandler", Func, 0},
+ {"TrailerPrefix", Const, 8},
+ {"Transport", Type, 0},
+ {"Transport.Dial", Field, 0},
+ {"Transport.DialContext", Field, 7},
+ {"Transport.DialTLS", Field, 4},
+ {"Transport.DialTLSContext", Field, 14},
+ {"Transport.DisableCompression", Field, 0},
+ {"Transport.DisableKeepAlives", Field, 0},
+ {"Transport.ExpectContinueTimeout", Field, 6},
+ {"Transport.ForceAttemptHTTP2", Field, 13},
+ {"Transport.GetProxyConnectHeader", Field, 16},
+ {"Transport.IdleConnTimeout", Field, 7},
+ {"Transport.MaxConnsPerHost", Field, 11},
+ {"Transport.MaxIdleConns", Field, 7},
+ {"Transport.MaxIdleConnsPerHost", Field, 0},
+ {"Transport.MaxResponseHeaderBytes", Field, 7},
+ {"Transport.OnProxyConnectResponse", Field, 20},
+ {"Transport.Proxy", Field, 0},
+ {"Transport.ProxyConnectHeader", Field, 8},
+ {"Transport.ReadBufferSize", Field, 13},
+ {"Transport.ResponseHeaderTimeout", Field, 1},
+ {"Transport.TLSClientConfig", Field, 0},
+ {"Transport.TLSHandshakeTimeout", Field, 3},
+ {"Transport.TLSNextProto", Field, 6},
+ {"Transport.WriteBufferSize", Field, 13},
+ },
+ "net/http/cgi": {
+ {"(*Handler).ServeHTTP", Method, 0},
+ {"Handler", Type, 0},
+ {"Handler.Args", Field, 0},
+ {"Handler.Dir", Field, 0},
+ {"Handler.Env", Field, 0},
+ {"Handler.InheritEnv", Field, 0},
+ {"Handler.Logger", Field, 0},
+ {"Handler.Path", Field, 0},
+ {"Handler.PathLocationHandler", Field, 0},
+ {"Handler.Root", Field, 0},
+ {"Handler.Stderr", Field, 7},
+ {"Request", Func, 0},
+ {"RequestFromMap", Func, 0},
+ {"Serve", Func, 0},
+ },
+ "net/http/cookiejar": {
+ {"(*Jar).Cookies", Method, 1},
+ {"(*Jar).SetCookies", Method, 1},
+ {"Jar", Type, 1},
+ {"New", Func, 1},
+ {"Options", Type, 1},
+ {"Options.PublicSuffixList", Field, 1},
+ {"PublicSuffixList", Type, 1},
+ },
+ "net/http/fcgi": {
+ {"ErrConnClosed", Var, 5},
+ {"ErrRequestAborted", Var, 5},
+ {"ProcessEnv", Func, 9},
+ {"Serve", Func, 0},
+ },
+ "net/http/httptest": {
+ {"(*ResponseRecorder).Flush", Method, 0},
+ {"(*ResponseRecorder).Header", Method, 0},
+ {"(*ResponseRecorder).Result", Method, 7},
+ {"(*ResponseRecorder).Write", Method, 0},
+ {"(*ResponseRecorder).WriteHeader", Method, 0},
+ {"(*ResponseRecorder).WriteString", Method, 6},
+ {"(*Server).Certificate", Method, 9},
+ {"(*Server).Client", Method, 9},
+ {"(*Server).Close", Method, 0},
+ {"(*Server).CloseClientConnections", Method, 0},
+ {"(*Server).Start", Method, 0},
+ {"(*Server).StartTLS", Method, 0},
+ {"DefaultRemoteAddr", Const, 0},
+ {"NewRecorder", Func, 0},
+ {"NewRequest", Func, 7},
+ {"NewRequestWithContext", Func, 23},
+ {"NewServer", Func, 0},
+ {"NewTLSServer", Func, 0},
+ {"NewUnstartedServer", Func, 0},
+ {"ResponseRecorder", Type, 0},
+ {"ResponseRecorder.Body", Field, 0},
+ {"ResponseRecorder.Code", Field, 0},
+ {"ResponseRecorder.Flushed", Field, 0},
+ {"ResponseRecorder.HeaderMap", Field, 0},
+ {"Server", Type, 0},
+ {"Server.Config", Field, 0},
+ {"Server.EnableHTTP2", Field, 14},
+ {"Server.Listener", Field, 0},
+ {"Server.TLS", Field, 0},
+ {"Server.URL", Field, 0},
+ },
+ "net/http/httptrace": {
+ {"ClientTrace", Type, 7},
+ {"ClientTrace.ConnectDone", Field, 7},
+ {"ClientTrace.ConnectStart", Field, 7},
+ {"ClientTrace.DNSDone", Field, 7},
+ {"ClientTrace.DNSStart", Field, 7},
+ {"ClientTrace.GetConn", Field, 7},
+ {"ClientTrace.Got100Continue", Field, 7},
+ {"ClientTrace.Got1xxResponse", Field, 11},
+ {"ClientTrace.GotConn", Field, 7},
+ {"ClientTrace.GotFirstResponseByte", Field, 7},
+ {"ClientTrace.PutIdleConn", Field, 7},
+ {"ClientTrace.TLSHandshakeDone", Field, 8},
+ {"ClientTrace.TLSHandshakeStart", Field, 8},
+ {"ClientTrace.Wait100Continue", Field, 7},
+ {"ClientTrace.WroteHeaderField", Field, 11},
+ {"ClientTrace.WroteHeaders", Field, 7},
+ {"ClientTrace.WroteRequest", Field, 7},
+ {"ContextClientTrace", Func, 7},
+ {"DNSDoneInfo", Type, 7},
+ {"DNSDoneInfo.Addrs", Field, 7},
+ {"DNSDoneInfo.Coalesced", Field, 7},
+ {"DNSDoneInfo.Err", Field, 7},
+ {"DNSStartInfo", Type, 7},
+ {"DNSStartInfo.Host", Field, 7},
+ {"GotConnInfo", Type, 7},
+ {"GotConnInfo.Conn", Field, 7},
+ {"GotConnInfo.IdleTime", Field, 7},
+ {"GotConnInfo.Reused", Field, 7},
+ {"GotConnInfo.WasIdle", Field, 7},
+ {"WithClientTrace", Func, 7},
+ {"WroteRequestInfo", Type, 7},
+ {"WroteRequestInfo.Err", Field, 7},
+ },
+ "net/http/httputil": {
+ {"(*ClientConn).Close", Method, 0},
+ {"(*ClientConn).Do", Method, 0},
+ {"(*ClientConn).Hijack", Method, 0},
+ {"(*ClientConn).Pending", Method, 0},
+ {"(*ClientConn).Read", Method, 0},
+ {"(*ClientConn).Write", Method, 0},
+ {"(*ProxyRequest).SetURL", Method, 20},
+ {"(*ProxyRequest).SetXForwarded", Method, 20},
+ {"(*ReverseProxy).ServeHTTP", Method, 0},
+ {"(*ServerConn).Close", Method, 0},
+ {"(*ServerConn).Hijack", Method, 0},
+ {"(*ServerConn).Pending", Method, 0},
+ {"(*ServerConn).Read", Method, 0},
+ {"(*ServerConn).Write", Method, 0},
+ {"BufferPool", Type, 6},
+ {"ClientConn", Type, 0},
+ {"DumpRequest", Func, 0},
+ {"DumpRequestOut", Func, 0},
+ {"DumpResponse", Func, 0},
+ {"ErrClosed", Var, 0},
+ {"ErrLineTooLong", Var, 0},
+ {"ErrPersistEOF", Var, 0},
+ {"ErrPipeline", Var, 0},
+ {"NewChunkedReader", Func, 0},
+ {"NewChunkedWriter", Func, 0},
+ {"NewClientConn", Func, 0},
+ {"NewProxyClientConn", Func, 0},
+ {"NewServerConn", Func, 0},
+ {"NewSingleHostReverseProxy", Func, 0},
+ {"ProxyRequest", Type, 20},
+ {"ProxyRequest.In", Field, 20},
+ {"ProxyRequest.Out", Field, 20},
+ {"ReverseProxy", Type, 0},
+ {"ReverseProxy.BufferPool", Field, 6},
+ {"ReverseProxy.Director", Field, 0},
+ {"ReverseProxy.ErrorHandler", Field, 11},
+ {"ReverseProxy.ErrorLog", Field, 4},
+ {"ReverseProxy.FlushInterval", Field, 0},
+ {"ReverseProxy.ModifyResponse", Field, 8},
+ {"ReverseProxy.Rewrite", Field, 20},
+ {"ReverseProxy.Transport", Field, 0},
+ {"ServerConn", Type, 0},
+ },
+ "net/http/pprof": {
+ {"Cmdline", Func, 0},
+ {"Handler", Func, 0},
+ {"Index", Func, 0},
+ {"Profile", Func, 0},
+ {"Symbol", Func, 0},
+ {"Trace", Func, 5},
+ },
+ "net/mail": {
+ {"(*Address).String", Method, 0},
+ {"(*AddressParser).Parse", Method, 5},
+ {"(*AddressParser).ParseList", Method, 5},
+ {"(Header).AddressList", Method, 0},
+ {"(Header).Date", Method, 0},
+ {"(Header).Get", Method, 0},
+ {"Address", Type, 0},
+ {"Address.Address", Field, 0},
+ {"Address.Name", Field, 0},
+ {"AddressParser", Type, 5},
+ {"AddressParser.WordDecoder", Field, 5},
+ {"ErrHeaderNotPresent", Var, 0},
+ {"Header", Type, 0},
+ {"Message", Type, 0},
+ {"Message.Body", Field, 0},
+ {"Message.Header", Field, 0},
+ {"ParseAddress", Func, 1},
+ {"ParseAddressList", Func, 1},
+ {"ParseDate", Func, 8},
+ {"ReadMessage", Func, 0},
+ },
+ "net/netip": {
+ {"(*Addr).UnmarshalBinary", Method, 18},
+ {"(*Addr).UnmarshalText", Method, 18},
+ {"(*AddrPort).UnmarshalBinary", Method, 18},
+ {"(*AddrPort).UnmarshalText", Method, 18},
+ {"(*Prefix).UnmarshalBinary", Method, 18},
+ {"(*Prefix).UnmarshalText", Method, 18},
+ {"(Addr).AppendTo", Method, 18},
+ {"(Addr).As16", Method, 18},
+ {"(Addr).As4", Method, 18},
+ {"(Addr).AsSlice", Method, 18},
+ {"(Addr).BitLen", Method, 18},
+ {"(Addr).Compare", Method, 18},
+ {"(Addr).Is4", Method, 18},
+ {"(Addr).Is4In6", Method, 18},
+ {"(Addr).Is6", Method, 18},
+ {"(Addr).IsGlobalUnicast", Method, 18},
+ {"(Addr).IsInterfaceLocalMulticast", Method, 18},
+ {"(Addr).IsLinkLocalMulticast", Method, 18},
+ {"(Addr).IsLinkLocalUnicast", Method, 18},
+ {"(Addr).IsLoopback", Method, 18},
+ {"(Addr).IsMulticast", Method, 18},
+ {"(Addr).IsPrivate", Method, 18},
+ {"(Addr).IsUnspecified", Method, 18},
+ {"(Addr).IsValid", Method, 18},
+ {"(Addr).Less", Method, 18},
+ {"(Addr).MarshalBinary", Method, 18},
+ {"(Addr).MarshalText", Method, 18},
+ {"(Addr).Next", Method, 18},
+ {"(Addr).Prefix", Method, 18},
+ {"(Addr).Prev", Method, 18},
+ {"(Addr).String", Method, 18},
+ {"(Addr).StringExpanded", Method, 18},
+ {"(Addr).Unmap", Method, 18},
+ {"(Addr).WithZone", Method, 18},
+ {"(Addr).Zone", Method, 18},
+ {"(AddrPort).Addr", Method, 18},
+ {"(AddrPort).AppendTo", Method, 18},
+ {"(AddrPort).Compare", Method, 22},
+ {"(AddrPort).IsValid", Method, 18},
+ {"(AddrPort).MarshalBinary", Method, 18},
+ {"(AddrPort).MarshalText", Method, 18},
+ {"(AddrPort).Port", Method, 18},
+ {"(AddrPort).String", Method, 18},
+ {"(Prefix).Addr", Method, 18},
+ {"(Prefix).AppendTo", Method, 18},
+ {"(Prefix).Bits", Method, 18},
+ {"(Prefix).Contains", Method, 18},
+ {"(Prefix).IsSingleIP", Method, 18},
+ {"(Prefix).IsValid", Method, 18},
+ {"(Prefix).MarshalBinary", Method, 18},
+ {"(Prefix).MarshalText", Method, 18},
+ {"(Prefix).Masked", Method, 18},
+ {"(Prefix).Overlaps", Method, 18},
+ {"(Prefix).String", Method, 18},
+ {"Addr", Type, 18},
+ {"AddrFrom16", Func, 18},
+ {"AddrFrom4", Func, 18},
+ {"AddrFromSlice", Func, 18},
+ {"AddrPort", Type, 18},
+ {"AddrPortFrom", Func, 18},
+ {"IPv4Unspecified", Func, 18},
+ {"IPv6LinkLocalAllNodes", Func, 18},
+ {"IPv6LinkLocalAllRouters", Func, 20},
+ {"IPv6Loopback", Func, 20},
+ {"IPv6Unspecified", Func, 18},
+ {"MustParseAddr", Func, 18},
+ {"MustParseAddrPort", Func, 18},
+ {"MustParsePrefix", Func, 18},
+ {"ParseAddr", Func, 18},
+ {"ParseAddrPort", Func, 18},
+ {"ParsePrefix", Func, 18},
+ {"Prefix", Type, 18},
+ {"PrefixFrom", Func, 18},
+ },
+ "net/rpc": {
+ {"(*Client).Call", Method, 0},
+ {"(*Client).Close", Method, 0},
+ {"(*Client).Go", Method, 0},
+ {"(*Server).Accept", Method, 0},
+ {"(*Server).HandleHTTP", Method, 0},
+ {"(*Server).Register", Method, 0},
+ {"(*Server).RegisterName", Method, 0},
+ {"(*Server).ServeCodec", Method, 0},
+ {"(*Server).ServeConn", Method, 0},
+ {"(*Server).ServeHTTP", Method, 0},
+ {"(*Server).ServeRequest", Method, 0},
+ {"(ServerError).Error", Method, 0},
+ {"Accept", Func, 0},
+ {"Call", Type, 0},
+ {"Call.Args", Field, 0},
+ {"Call.Done", Field, 0},
+ {"Call.Error", Field, 0},
+ {"Call.Reply", Field, 0},
+ {"Call.ServiceMethod", Field, 0},
+ {"Client", Type, 0},
+ {"ClientCodec", Type, 0},
+ {"DefaultDebugPath", Const, 0},
+ {"DefaultRPCPath", Const, 0},
+ {"DefaultServer", Var, 0},
+ {"Dial", Func, 0},
+ {"DialHTTP", Func, 0},
+ {"DialHTTPPath", Func, 0},
+ {"ErrShutdown", Var, 0},
+ {"HandleHTTP", Func, 0},
+ {"NewClient", Func, 0},
+ {"NewClientWithCodec", Func, 0},
+ {"NewServer", Func, 0},
+ {"Register", Func, 0},
+ {"RegisterName", Func, 0},
+ {"Request", Type, 0},
+ {"Request.Seq", Field, 0},
+ {"Request.ServiceMethod", Field, 0},
+ {"Response", Type, 0},
+ {"Response.Error", Field, 0},
+ {"Response.Seq", Field, 0},
+ {"Response.ServiceMethod", Field, 0},
+ {"ServeCodec", Func, 0},
+ {"ServeConn", Func, 0},
+ {"ServeRequest", Func, 0},
+ {"Server", Type, 0},
+ {"ServerCodec", Type, 0},
+ {"ServerError", Type, 0},
+ },
+ "net/rpc/jsonrpc": {
+ {"Dial", Func, 0},
+ {"NewClient", Func, 0},
+ {"NewClientCodec", Func, 0},
+ {"NewServerCodec", Func, 0},
+ {"ServeConn", Func, 0},
+ },
+ "net/smtp": {
+ {"(*Client).Auth", Method, 0},
+ {"(*Client).Close", Method, 2},
+ {"(*Client).Data", Method, 0},
+ {"(*Client).Extension", Method, 0},
+ {"(*Client).Hello", Method, 1},
+ {"(*Client).Mail", Method, 0},
+ {"(*Client).Noop", Method, 10},
+ {"(*Client).Quit", Method, 0},
+ {"(*Client).Rcpt", Method, 0},
+ {"(*Client).Reset", Method, 0},
+ {"(*Client).StartTLS", Method, 0},
+ {"(*Client).TLSConnectionState", Method, 5},
+ {"(*Client).Verify", Method, 0},
+ {"Auth", Type, 0},
+ {"CRAMMD5Auth", Func, 0},
+ {"Client", Type, 0},
+ {"Client.Text", Field, 0},
+ {"Dial", Func, 0},
+ {"NewClient", Func, 0},
+ {"PlainAuth", Func, 0},
+ {"SendMail", Func, 0},
+ {"ServerInfo", Type, 0},
+ {"ServerInfo.Auth", Field, 0},
+ {"ServerInfo.Name", Field, 0},
+ {"ServerInfo.TLS", Field, 0},
+ },
+ "net/textproto": {
+ {"(*Conn).Close", Method, 0},
+ {"(*Conn).Cmd", Method, 0},
+ {"(*Conn).DotReader", Method, 0},
+ {"(*Conn).DotWriter", Method, 0},
+ {"(*Conn).EndRequest", Method, 0},
+ {"(*Conn).EndResponse", Method, 0},
+ {"(*Conn).Next", Method, 0},
+ {"(*Conn).PrintfLine", Method, 0},
+ {"(*Conn).ReadCodeLine", Method, 0},
+ {"(*Conn).ReadContinuedLine", Method, 0},
+ {"(*Conn).ReadContinuedLineBytes", Method, 0},
+ {"(*Conn).ReadDotBytes", Method, 0},
+ {"(*Conn).ReadDotLines", Method, 0},
+ {"(*Conn).ReadLine", Method, 0},
+ {"(*Conn).ReadLineBytes", Method, 0},
+ {"(*Conn).ReadMIMEHeader", Method, 0},
+ {"(*Conn).ReadResponse", Method, 0},
+ {"(*Conn).StartRequest", Method, 0},
+ {"(*Conn).StartResponse", Method, 0},
+ {"(*Error).Error", Method, 0},
+ {"(*Pipeline).EndRequest", Method, 0},
+ {"(*Pipeline).EndResponse", Method, 0},
+ {"(*Pipeline).Next", Method, 0},
+ {"(*Pipeline).StartRequest", Method, 0},
+ {"(*Pipeline).StartResponse", Method, 0},
+ {"(*Reader).DotReader", Method, 0},
+ {"(*Reader).ReadCodeLine", Method, 0},
+ {"(*Reader).ReadContinuedLine", Method, 0},
+ {"(*Reader).ReadContinuedLineBytes", Method, 0},
+ {"(*Reader).ReadDotBytes", Method, 0},
+ {"(*Reader).ReadDotLines", Method, 0},
+ {"(*Reader).ReadLine", Method, 0},
+ {"(*Reader).ReadLineBytes", Method, 0},
+ {"(*Reader).ReadMIMEHeader", Method, 0},
+ {"(*Reader).ReadResponse", Method, 0},
+ {"(*Writer).DotWriter", Method, 0},
+ {"(*Writer).PrintfLine", Method, 0},
+ {"(MIMEHeader).Add", Method, 0},
+ {"(MIMEHeader).Del", Method, 0},
+ {"(MIMEHeader).Get", Method, 0},
+ {"(MIMEHeader).Set", Method, 0},
+ {"(MIMEHeader).Values", Method, 14},
+ {"(ProtocolError).Error", Method, 0},
+ {"CanonicalMIMEHeaderKey", Func, 0},
+ {"Conn", Type, 0},
+ {"Conn.Pipeline", Field, 0},
+ {"Conn.Reader", Field, 0},
+ {"Conn.Writer", Field, 0},
+ {"Dial", Func, 0},
+ {"Error", Type, 0},
+ {"Error.Code", Field, 0},
+ {"Error.Msg", Field, 0},
+ {"MIMEHeader", Type, 0},
+ {"NewConn", Func, 0},
+ {"NewReader", Func, 0},
+ {"NewWriter", Func, 0},
+ {"Pipeline", Type, 0},
+ {"ProtocolError", Type, 0},
+ {"Reader", Type, 0},
+ {"Reader.R", Field, 0},
+ {"TrimBytes", Func, 1},
+ {"TrimString", Func, 1},
+ {"Writer", Type, 0},
+ {"Writer.W", Field, 0},
+ },
+ "net/url": {
+ {"(*Error).Error", Method, 0},
+ {"(*Error).Temporary", Method, 6},
+ {"(*Error).Timeout", Method, 6},
+ {"(*Error).Unwrap", Method, 13},
+ {"(*URL).EscapedFragment", Method, 15},
+ {"(*URL).EscapedPath", Method, 5},
+ {"(*URL).Hostname", Method, 8},
+ {"(*URL).IsAbs", Method, 0},
+ {"(*URL).JoinPath", Method, 19},
+ {"(*URL).MarshalBinary", Method, 8},
+ {"(*URL).Parse", Method, 0},
+ {"(*URL).Port", Method, 8},
+ {"(*URL).Query", Method, 0},
+ {"(*URL).Redacted", Method, 15},
+ {"(*URL).RequestURI", Method, 0},
+ {"(*URL).ResolveReference", Method, 0},
+ {"(*URL).String", Method, 0},
+ {"(*URL).UnmarshalBinary", Method, 8},
+ {"(*Userinfo).Password", Method, 0},
+ {"(*Userinfo).String", Method, 0},
+ {"(*Userinfo).Username", Method, 0},
+ {"(EscapeError).Error", Method, 0},
+ {"(InvalidHostError).Error", Method, 6},
+ {"(Values).Add", Method, 0},
+ {"(Values).Del", Method, 0},
+ {"(Values).Encode", Method, 0},
+ {"(Values).Get", Method, 0},
+ {"(Values).Has", Method, 17},
+ {"(Values).Set", Method, 0},
+ {"Error", Type, 0},
+ {"Error.Err", Field, 0},
+ {"Error.Op", Field, 0},
+ {"Error.URL", Field, 0},
+ {"EscapeError", Type, 0},
+ {"InvalidHostError", Type, 6},
+ {"JoinPath", Func, 19},
+ {"Parse", Func, 0},
+ {"ParseQuery", Func, 0},
+ {"ParseRequestURI", Func, 0},
+ {"PathEscape", Func, 8},
+ {"PathUnescape", Func, 8},
+ {"QueryEscape", Func, 0},
+ {"QueryUnescape", Func, 0},
+ {"URL", Type, 0},
+ {"URL.ForceQuery", Field, 7},
+ {"URL.Fragment", Field, 0},
+ {"URL.Host", Field, 0},
+ {"URL.OmitHost", Field, 19},
+ {"URL.Opaque", Field, 0},
+ {"URL.Path", Field, 0},
+ {"URL.RawFragment", Field, 15},
+ {"URL.RawPath", Field, 5},
+ {"URL.RawQuery", Field, 0},
+ {"URL.Scheme", Field, 0},
+ {"URL.User", Field, 0},
+ {"User", Func, 0},
+ {"UserPassword", Func, 0},
+ {"Userinfo", Type, 0},
+ {"Values", Type, 0},
+ },
+ "os": {
+ {"(*File).Chdir", Method, 0},
+ {"(*File).Chmod", Method, 0},
+ {"(*File).Chown", Method, 0},
+ {"(*File).Close", Method, 0},
+ {"(*File).Fd", Method, 0},
+ {"(*File).Name", Method, 0},
+ {"(*File).Read", Method, 0},
+ {"(*File).ReadAt", Method, 0},
+ {"(*File).ReadDir", Method, 16},
+ {"(*File).ReadFrom", Method, 15},
+ {"(*File).Readdir", Method, 0},
+ {"(*File).Readdirnames", Method, 0},
+ {"(*File).Seek", Method, 0},
+ {"(*File).SetDeadline", Method, 10},
+ {"(*File).SetReadDeadline", Method, 10},
+ {"(*File).SetWriteDeadline", Method, 10},
+ {"(*File).Stat", Method, 0},
+ {"(*File).Sync", Method, 0},
+ {"(*File).SyscallConn", Method, 12},
+ {"(*File).Truncate", Method, 0},
+ {"(*File).Write", Method, 0},
+ {"(*File).WriteAt", Method, 0},
+ {"(*File).WriteString", Method, 0},
+ {"(*File).WriteTo", Method, 22},
+ {"(*LinkError).Error", Method, 0},
+ {"(*LinkError).Unwrap", Method, 13},
+ {"(*PathError).Error", Method, 0},
+ {"(*PathError).Timeout", Method, 10},
+ {"(*PathError).Unwrap", Method, 13},
+ {"(*Process).Kill", Method, 0},
+ {"(*Process).Release", Method, 0},
+ {"(*Process).Signal", Method, 0},
+ {"(*Process).Wait", Method, 0},
+ {"(*ProcessState).ExitCode", Method, 12},
+ {"(*ProcessState).Exited", Method, 0},
+ {"(*ProcessState).Pid", Method, 0},
+ {"(*ProcessState).String", Method, 0},
+ {"(*ProcessState).Success", Method, 0},
+ {"(*ProcessState).Sys", Method, 0},
+ {"(*ProcessState).SysUsage", Method, 0},
+ {"(*ProcessState).SystemTime", Method, 0},
+ {"(*ProcessState).UserTime", Method, 0},
+ {"(*SyscallError).Error", Method, 0},
+ {"(*SyscallError).Timeout", Method, 10},
+ {"(*SyscallError).Unwrap", Method, 13},
+ {"(FileMode).IsDir", Method, 0},
+ {"(FileMode).IsRegular", Method, 1},
+ {"(FileMode).Perm", Method, 0},
+ {"(FileMode).String", Method, 0},
+ {"Args", Var, 0},
+ {"Chdir", Func, 0},
+ {"Chmod", Func, 0},
+ {"Chown", Func, 0},
+ {"Chtimes", Func, 0},
+ {"Clearenv", Func, 0},
+ {"CopyFS", Func, 23},
+ {"Create", Func, 0},
+ {"CreateTemp", Func, 16},
+ {"DevNull", Const, 0},
+ {"DirEntry", Type, 16},
+ {"DirFS", Func, 16},
+ {"Environ", Func, 0},
+ {"ErrClosed", Var, 8},
+ {"ErrDeadlineExceeded", Var, 15},
+ {"ErrExist", Var, 0},
+ {"ErrInvalid", Var, 0},
+ {"ErrNoDeadline", Var, 10},
+ {"ErrNotExist", Var, 0},
+ {"ErrPermission", Var, 0},
+ {"ErrProcessDone", Var, 16},
+ {"Executable", Func, 8},
+ {"Exit", Func, 0},
+ {"Expand", Func, 0},
+ {"ExpandEnv", Func, 0},
+ {"File", Type, 0},
+ {"FileInfo", Type, 0},
+ {"FileMode", Type, 0},
+ {"FindProcess", Func, 0},
+ {"Getegid", Func, 0},
+ {"Getenv", Func, 0},
+ {"Geteuid", Func, 0},
+ {"Getgid", Func, 0},
+ {"Getgroups", Func, 0},
+ {"Getpagesize", Func, 0},
+ {"Getpid", Func, 0},
+ {"Getppid", Func, 0},
+ {"Getuid", Func, 0},
+ {"Getwd", Func, 0},
+ {"Hostname", Func, 0},
+ {"Interrupt", Var, 0},
+ {"IsExist", Func, 0},
+ {"IsNotExist", Func, 0},
+ {"IsPathSeparator", Func, 0},
+ {"IsPermission", Func, 0},
+ {"IsTimeout", Func, 10},
+ {"Kill", Var, 0},
+ {"Lchown", Func, 0},
+ {"Link", Func, 0},
+ {"LinkError", Type, 0},
+ {"LinkError.Err", Field, 0},
+ {"LinkError.New", Field, 0},
+ {"LinkError.Old", Field, 0},
+ {"LinkError.Op", Field, 0},
+ {"LookupEnv", Func, 5},
+ {"Lstat", Func, 0},
+ {"Mkdir", Func, 0},
+ {"MkdirAll", Func, 0},
+ {"MkdirTemp", Func, 16},
+ {"ModeAppend", Const, 0},
+ {"ModeCharDevice", Const, 0},
+ {"ModeDevice", Const, 0},
+ {"ModeDir", Const, 0},
+ {"ModeExclusive", Const, 0},
+ {"ModeIrregular", Const, 11},
+ {"ModeNamedPipe", Const, 0},
+ {"ModePerm", Const, 0},
+ {"ModeSetgid", Const, 0},
+ {"ModeSetuid", Const, 0},
+ {"ModeSocket", Const, 0},
+ {"ModeSticky", Const, 0},
+ {"ModeSymlink", Const, 0},
+ {"ModeTemporary", Const, 0},
+ {"ModeType", Const, 0},
+ {"NewFile", Func, 0},
+ {"NewSyscallError", Func, 0},
+ {"O_APPEND", Const, 0},
+ {"O_CREATE", Const, 0},
+ {"O_EXCL", Const, 0},
+ {"O_RDONLY", Const, 0},
+ {"O_RDWR", Const, 0},
+ {"O_SYNC", Const, 0},
+ {"O_TRUNC", Const, 0},
+ {"O_WRONLY", Const, 0},
+ {"Open", Func, 0},
+ {"OpenFile", Func, 0},
+ {"PathError", Type, 0},
+ {"PathError.Err", Field, 0},
+ {"PathError.Op", Field, 0},
+ {"PathError.Path", Field, 0},
+ {"PathListSeparator", Const, 0},
+ {"PathSeparator", Const, 0},
+ {"Pipe", Func, 0},
+ {"ProcAttr", Type, 0},
+ {"ProcAttr.Dir", Field, 0},
+ {"ProcAttr.Env", Field, 0},
+ {"ProcAttr.Files", Field, 0},
+ {"ProcAttr.Sys", Field, 0},
+ {"Process", Type, 0},
+ {"Process.Pid", Field, 0},
+ {"ProcessState", Type, 0},
+ {"ReadDir", Func, 16},
+ {"ReadFile", Func, 16},
+ {"Readlink", Func, 0},
+ {"Remove", Func, 0},
+ {"RemoveAll", Func, 0},
+ {"Rename", Func, 0},
+ {"SEEK_CUR", Const, 0},
+ {"SEEK_END", Const, 0},
+ {"SEEK_SET", Const, 0},
+ {"SameFile", Func, 0},
+ {"Setenv", Func, 0},
+ {"Signal", Type, 0},
+ {"StartProcess", Func, 0},
+ {"Stat", Func, 0},
+ {"Stderr", Var, 0},
+ {"Stdin", Var, 0},
+ {"Stdout", Var, 0},
+ {"Symlink", Func, 0},
+ {"SyscallError", Type, 0},
+ {"SyscallError.Err", Field, 0},
+ {"SyscallError.Syscall", Field, 0},
+ {"TempDir", Func, 0},
+ {"Truncate", Func, 0},
+ {"Unsetenv", Func, 4},
+ {"UserCacheDir", Func, 11},
+ {"UserConfigDir", Func, 13},
+ {"UserHomeDir", Func, 12},
+ {"WriteFile", Func, 16},
+ },
+ "os/exec": {
+ {"(*Cmd).CombinedOutput", Method, 0},
+ {"(*Cmd).Environ", Method, 19},
+ {"(*Cmd).Output", Method, 0},
+ {"(*Cmd).Run", Method, 0},
+ {"(*Cmd).Start", Method, 0},
+ {"(*Cmd).StderrPipe", Method, 0},
+ {"(*Cmd).StdinPipe", Method, 0},
+ {"(*Cmd).StdoutPipe", Method, 0},
+ {"(*Cmd).String", Method, 13},
+ {"(*Cmd).Wait", Method, 0},
+ {"(*Error).Error", Method, 0},
+ {"(*Error).Unwrap", Method, 13},
+ {"(*ExitError).Error", Method, 0},
+ {"(ExitError).ExitCode", Method, 12},
+ {"(ExitError).Exited", Method, 0},
+ {"(ExitError).Pid", Method, 0},
+ {"(ExitError).String", Method, 0},
+ {"(ExitError).Success", Method, 0},
+ {"(ExitError).Sys", Method, 0},
+ {"(ExitError).SysUsage", Method, 0},
+ {"(ExitError).SystemTime", Method, 0},
+ {"(ExitError).UserTime", Method, 0},
+ {"Cmd", Type, 0},
+ {"Cmd.Args", Field, 0},
+ {"Cmd.Cancel", Field, 20},
+ {"Cmd.Dir", Field, 0},
+ {"Cmd.Env", Field, 0},
+ {"Cmd.Err", Field, 19},
+ {"Cmd.ExtraFiles", Field, 0},
+ {"Cmd.Path", Field, 0},
+ {"Cmd.Process", Field, 0},
+ {"Cmd.ProcessState", Field, 0},
+ {"Cmd.Stderr", Field, 0},
+ {"Cmd.Stdin", Field, 0},
+ {"Cmd.Stdout", Field, 0},
+ {"Cmd.SysProcAttr", Field, 0},
+ {"Cmd.WaitDelay", Field, 20},
+ {"Command", Func, 0},
+ {"CommandContext", Func, 7},
+ {"ErrDot", Var, 19},
+ {"ErrNotFound", Var, 0},
+ {"ErrWaitDelay", Var, 20},
+ {"Error", Type, 0},
+ {"Error.Err", Field, 0},
+ {"Error.Name", Field, 0},
+ {"ExitError", Type, 0},
+ {"ExitError.ProcessState", Field, 0},
+ {"ExitError.Stderr", Field, 6},
+ {"LookPath", Func, 0},
+ },
+ "os/signal": {
+ {"Ignore", Func, 5},
+ {"Ignored", Func, 11},
+ {"Notify", Func, 0},
+ {"NotifyContext", Func, 16},
+ {"Reset", Func, 5},
+ {"Stop", Func, 1},
+ },
+ "os/user": {
+ {"(*User).GroupIds", Method, 7},
+ {"(UnknownGroupError).Error", Method, 7},
+ {"(UnknownGroupIdError).Error", Method, 7},
+ {"(UnknownUserError).Error", Method, 0},
+ {"(UnknownUserIdError).Error", Method, 0},
+ {"Current", Func, 0},
+ {"Group", Type, 7},
+ {"Group.Gid", Field, 7},
+ {"Group.Name", Field, 7},
+ {"Lookup", Func, 0},
+ {"LookupGroup", Func, 7},
+ {"LookupGroupId", Func, 7},
+ {"LookupId", Func, 0},
+ {"UnknownGroupError", Type, 7},
+ {"UnknownGroupIdError", Type, 7},
+ {"UnknownUserError", Type, 0},
+ {"UnknownUserIdError", Type, 0},
+ {"User", Type, 0},
+ {"User.Gid", Field, 0},
+ {"User.HomeDir", Field, 0},
+ {"User.Name", Field, 0},
+ {"User.Uid", Field, 0},
+ {"User.Username", Field, 0},
+ },
+ "path": {
+ {"Base", Func, 0},
+ {"Clean", Func, 0},
+ {"Dir", Func, 0},
+ {"ErrBadPattern", Var, 0},
+ {"Ext", Func, 0},
+ {"IsAbs", Func, 0},
+ {"Join", Func, 0},
+ {"Match", Func, 0},
+ {"Split", Func, 0},
+ },
+ "path/filepath": {
+ {"Abs", Func, 0},
+ {"Base", Func, 0},
+ {"Clean", Func, 0},
+ {"Dir", Func, 0},
+ {"ErrBadPattern", Var, 0},
+ {"EvalSymlinks", Func, 0},
+ {"Ext", Func, 0},
+ {"FromSlash", Func, 0},
+ {"Glob", Func, 0},
+ {"HasPrefix", Func, 0},
+ {"IsAbs", Func, 0},
+ {"IsLocal", Func, 20},
+ {"Join", Func, 0},
+ {"ListSeparator", Const, 0},
+ {"Localize", Func, 23},
+ {"Match", Func, 0},
+ {"Rel", Func, 0},
+ {"Separator", Const, 0},
+ {"SkipAll", Var, 20},
+ {"SkipDir", Var, 0},
+ {"Split", Func, 0},
+ {"SplitList", Func, 0},
+ {"ToSlash", Func, 0},
+ {"VolumeName", Func, 0},
+ {"Walk", Func, 0},
+ {"WalkDir", Func, 16},
+ {"WalkFunc", Type, 0},
+ },
+ "plugin": {
+ {"(*Plugin).Lookup", Method, 8},
+ {"Open", Func, 8},
+ {"Plugin", Type, 8},
+ {"Symbol", Type, 8},
+ },
+ "reflect": {
+ {"(*MapIter).Key", Method, 12},
+ {"(*MapIter).Next", Method, 12},
+ {"(*MapIter).Reset", Method, 18},
+ {"(*MapIter).Value", Method, 12},
+ {"(*ValueError).Error", Method, 0},
+ {"(ChanDir).String", Method, 0},
+ {"(Kind).String", Method, 0},
+ {"(Method).IsExported", Method, 17},
+ {"(StructField).IsExported", Method, 17},
+ {"(StructTag).Get", Method, 0},
+ {"(StructTag).Lookup", Method, 7},
+ {"(Value).Addr", Method, 0},
+ {"(Value).Bool", Method, 0},
+ {"(Value).Bytes", Method, 0},
+ {"(Value).Call", Method, 0},
+ {"(Value).CallSlice", Method, 0},
+ {"(Value).CanAddr", Method, 0},
+ {"(Value).CanComplex", Method, 18},
+ {"(Value).CanConvert", Method, 17},
+ {"(Value).CanFloat", Method, 18},
+ {"(Value).CanInt", Method, 18},
+ {"(Value).CanInterface", Method, 0},
+ {"(Value).CanSet", Method, 0},
+ {"(Value).CanUint", Method, 18},
+ {"(Value).Cap", Method, 0},
+ {"(Value).Clear", Method, 21},
+ {"(Value).Close", Method, 0},
+ {"(Value).Comparable", Method, 20},
+ {"(Value).Complex", Method, 0},
+ {"(Value).Convert", Method, 1},
+ {"(Value).Elem", Method, 0},
+ {"(Value).Equal", Method, 20},
+ {"(Value).Field", Method, 0},
+ {"(Value).FieldByIndex", Method, 0},
+ {"(Value).FieldByIndexErr", Method, 18},
+ {"(Value).FieldByName", Method, 0},
+ {"(Value).FieldByNameFunc", Method, 0},
+ {"(Value).Float", Method, 0},
+ {"(Value).Grow", Method, 20},
+ {"(Value).Index", Method, 0},
+ {"(Value).Int", Method, 0},
+ {"(Value).Interface", Method, 0},
+ {"(Value).InterfaceData", Method, 0},
+ {"(Value).IsNil", Method, 0},
+ {"(Value).IsValid", Method, 0},
+ {"(Value).IsZero", Method, 13},
+ {"(Value).Kind", Method, 0},
+ {"(Value).Len", Method, 0},
+ {"(Value).MapIndex", Method, 0},
+ {"(Value).MapKeys", Method, 0},
+ {"(Value).MapRange", Method, 12},
+ {"(Value).Method", Method, 0},
+ {"(Value).MethodByName", Method, 0},
+ {"(Value).NumField", Method, 0},
+ {"(Value).NumMethod", Method, 0},
+ {"(Value).OverflowComplex", Method, 0},
+ {"(Value).OverflowFloat", Method, 0},
+ {"(Value).OverflowInt", Method, 0},
+ {"(Value).OverflowUint", Method, 0},
+ {"(Value).Pointer", Method, 0},
+ {"(Value).Recv", Method, 0},
+ {"(Value).Send", Method, 0},
+ {"(Value).Seq", Method, 23},
+ {"(Value).Seq2", Method, 23},
+ {"(Value).Set", Method, 0},
+ {"(Value).SetBool", Method, 0},
+ {"(Value).SetBytes", Method, 0},
+ {"(Value).SetCap", Method, 2},
+ {"(Value).SetComplex", Method, 0},
+ {"(Value).SetFloat", Method, 0},
+ {"(Value).SetInt", Method, 0},
+ {"(Value).SetIterKey", Method, 18},
+ {"(Value).SetIterValue", Method, 18},
+ {"(Value).SetLen", Method, 0},
+ {"(Value).SetMapIndex", Method, 0},
+ {"(Value).SetPointer", Method, 0},
+ {"(Value).SetString", Method, 0},
+ {"(Value).SetUint", Method, 0},
+ {"(Value).SetZero", Method, 20},
+ {"(Value).Slice", Method, 0},
+ {"(Value).Slice3", Method, 2},
+ {"(Value).String", Method, 0},
+ {"(Value).TryRecv", Method, 0},
+ {"(Value).TrySend", Method, 0},
+ {"(Value).Type", Method, 0},
+ {"(Value).Uint", Method, 0},
+ {"(Value).UnsafeAddr", Method, 0},
+ {"(Value).UnsafePointer", Method, 18},
+ {"Append", Func, 0},
+ {"AppendSlice", Func, 0},
+ {"Array", Const, 0},
+ {"ArrayOf", Func, 5},
+ {"Bool", Const, 0},
+ {"BothDir", Const, 0},
+ {"Chan", Const, 0},
+ {"ChanDir", Type, 0},
+ {"ChanOf", Func, 1},
+ {"Complex128", Const, 0},
+ {"Complex64", Const, 0},
+ {"Copy", Func, 0},
+ {"DeepEqual", Func, 0},
+ {"Float32", Const, 0},
+ {"Float64", Const, 0},
+ {"Func", Const, 0},
+ {"FuncOf", Func, 5},
+ {"Indirect", Func, 0},
+ {"Int", Const, 0},
+ {"Int16", Const, 0},
+ {"Int32", Const, 0},
+ {"Int64", Const, 0},
+ {"Int8", Const, 0},
+ {"Interface", Const, 0},
+ {"Invalid", Const, 0},
+ {"Kind", Type, 0},
+ {"MakeChan", Func, 0},
+ {"MakeFunc", Func, 1},
+ {"MakeMap", Func, 0},
+ {"MakeMapWithSize", Func, 9},
+ {"MakeSlice", Func, 0},
+ {"Map", Const, 0},
+ {"MapIter", Type, 12},
+ {"MapOf", Func, 1},
+ {"Method", Type, 0},
+ {"Method.Func", Field, 0},
+ {"Method.Index", Field, 0},
+ {"Method.Name", Field, 0},
+ {"Method.PkgPath", Field, 0},
+ {"Method.Type", Field, 0},
+ {"New", Func, 0},
+ {"NewAt", Func, 0},
+ {"Pointer", Const, 18},
+ {"PointerTo", Func, 18},
+ {"Ptr", Const, 0},
+ {"PtrTo", Func, 0},
+ {"RecvDir", Const, 0},
+ {"Select", Func, 1},
+ {"SelectCase", Type, 1},
+ {"SelectCase.Chan", Field, 1},
+ {"SelectCase.Dir", Field, 1},
+ {"SelectCase.Send", Field, 1},
+ {"SelectDefault", Const, 1},
+ {"SelectDir", Type, 1},
+ {"SelectRecv", Const, 1},
+ {"SelectSend", Const, 1},
+ {"SendDir", Const, 0},
+ {"Slice", Const, 0},
+ {"SliceAt", Func, 23},
+ {"SliceHeader", Type, 0},
+ {"SliceHeader.Cap", Field, 0},
+ {"SliceHeader.Data", Field, 0},
+ {"SliceHeader.Len", Field, 0},
+ {"SliceOf", Func, 1},
+ {"String", Const, 0},
+ {"StringHeader", Type, 0},
+ {"StringHeader.Data", Field, 0},
+ {"StringHeader.Len", Field, 0},
+ {"Struct", Const, 0},
+ {"StructField", Type, 0},
+ {"StructField.Anonymous", Field, 0},
+ {"StructField.Index", Field, 0},
+ {"StructField.Name", Field, 0},
+ {"StructField.Offset", Field, 0},
+ {"StructField.PkgPath", Field, 0},
+ {"StructField.Tag", Field, 0},
+ {"StructField.Type", Field, 0},
+ {"StructOf", Func, 7},
+ {"StructTag", Type, 0},
+ {"Swapper", Func, 8},
+ {"Type", Type, 0},
+ {"TypeFor", Func, 22},
+ {"TypeOf", Func, 0},
+ {"Uint", Const, 0},
+ {"Uint16", Const, 0},
+ {"Uint32", Const, 0},
+ {"Uint64", Const, 0},
+ {"Uint8", Const, 0},
+ {"Uintptr", Const, 0},
+ {"UnsafePointer", Const, 0},
+ {"Value", Type, 0},
+ {"ValueError", Type, 0},
+ {"ValueError.Kind", Field, 0},
+ {"ValueError.Method", Field, 0},
+ {"ValueOf", Func, 0},
+ {"VisibleFields", Func, 17},
+ {"Zero", Func, 0},
+ },
+ "regexp": {
+ {"(*Regexp).Copy", Method, 6},
+ {"(*Regexp).Expand", Method, 0},
+ {"(*Regexp).ExpandString", Method, 0},
+ {"(*Regexp).Find", Method, 0},
+ {"(*Regexp).FindAll", Method, 0},
+ {"(*Regexp).FindAllIndex", Method, 0},
+ {"(*Regexp).FindAllString", Method, 0},
+ {"(*Regexp).FindAllStringIndex", Method, 0},
+ {"(*Regexp).FindAllStringSubmatch", Method, 0},
+ {"(*Regexp).FindAllStringSubmatchIndex", Method, 0},
+ {"(*Regexp).FindAllSubmatch", Method, 0},
+ {"(*Regexp).FindAllSubmatchIndex", Method, 0},
+ {"(*Regexp).FindIndex", Method, 0},
+ {"(*Regexp).FindReaderIndex", Method, 0},
+ {"(*Regexp).FindReaderSubmatchIndex", Method, 0},
+ {"(*Regexp).FindString", Method, 0},
+ {"(*Regexp).FindStringIndex", Method, 0},
+ {"(*Regexp).FindStringSubmatch", Method, 0},
+ {"(*Regexp).FindStringSubmatchIndex", Method, 0},
+ {"(*Regexp).FindSubmatch", Method, 0},
+ {"(*Regexp).FindSubmatchIndex", Method, 0},
+ {"(*Regexp).LiteralPrefix", Method, 0},
+ {"(*Regexp).Longest", Method, 1},
+ {"(*Regexp).MarshalText", Method, 21},
+ {"(*Regexp).Match", Method, 0},
+ {"(*Regexp).MatchReader", Method, 0},
+ {"(*Regexp).MatchString", Method, 0},
+ {"(*Regexp).NumSubexp", Method, 0},
+ {"(*Regexp).ReplaceAll", Method, 0},
+ {"(*Regexp).ReplaceAllFunc", Method, 0},
+ {"(*Regexp).ReplaceAllLiteral", Method, 0},
+ {"(*Regexp).ReplaceAllLiteralString", Method, 0},
+ {"(*Regexp).ReplaceAllString", Method, 0},
+ {"(*Regexp).ReplaceAllStringFunc", Method, 0},
+ {"(*Regexp).Split", Method, 1},
+ {"(*Regexp).String", Method, 0},
+ {"(*Regexp).SubexpIndex", Method, 15},
+ {"(*Regexp).SubexpNames", Method, 0},
+ {"(*Regexp).UnmarshalText", Method, 21},
+ {"Compile", Func, 0},
+ {"CompilePOSIX", Func, 0},
+ {"Match", Func, 0},
+ {"MatchReader", Func, 0},
+ {"MatchString", Func, 0},
+ {"MustCompile", Func, 0},
+ {"MustCompilePOSIX", Func, 0},
+ {"QuoteMeta", Func, 0},
+ {"Regexp", Type, 0},
+ },
+ "regexp/syntax": {
+ {"(*Error).Error", Method, 0},
+ {"(*Inst).MatchEmptyWidth", Method, 0},
+ {"(*Inst).MatchRune", Method, 0},
+ {"(*Inst).MatchRunePos", Method, 3},
+ {"(*Inst).String", Method, 0},
+ {"(*Prog).Prefix", Method, 0},
+ {"(*Prog).StartCond", Method, 0},
+ {"(*Prog).String", Method, 0},
+ {"(*Regexp).CapNames", Method, 0},
+ {"(*Regexp).Equal", Method, 0},
+ {"(*Regexp).MaxCap", Method, 0},
+ {"(*Regexp).Simplify", Method, 0},
+ {"(*Regexp).String", Method, 0},
+ {"(ErrorCode).String", Method, 0},
+ {"(InstOp).String", Method, 3},
+ {"(Op).String", Method, 11},
+ {"ClassNL", Const, 0},
+ {"Compile", Func, 0},
+ {"DotNL", Const, 0},
+ {"EmptyBeginLine", Const, 0},
+ {"EmptyBeginText", Const, 0},
+ {"EmptyEndLine", Const, 0},
+ {"EmptyEndText", Const, 0},
+ {"EmptyNoWordBoundary", Const, 0},
+ {"EmptyOp", Type, 0},
+ {"EmptyOpContext", Func, 0},
+ {"EmptyWordBoundary", Const, 0},
+ {"ErrInternalError", Const, 0},
+ {"ErrInvalidCharClass", Const, 0},
+ {"ErrInvalidCharRange", Const, 0},
+ {"ErrInvalidEscape", Const, 0},
+ {"ErrInvalidNamedCapture", Const, 0},
+ {"ErrInvalidPerlOp", Const, 0},
+ {"ErrInvalidRepeatOp", Const, 0},
+ {"ErrInvalidRepeatSize", Const, 0},
+ {"ErrInvalidUTF8", Const, 0},
+ {"ErrLarge", Const, 20},
+ {"ErrMissingBracket", Const, 0},
+ {"ErrMissingParen", Const, 0},
+ {"ErrMissingRepeatArgument", Const, 0},
+ {"ErrNestingDepth", Const, 19},
+ {"ErrTrailingBackslash", Const, 0},
+ {"ErrUnexpectedParen", Const, 1},
+ {"Error", Type, 0},
+ {"Error.Code", Field, 0},
+ {"Error.Expr", Field, 0},
+ {"ErrorCode", Type, 0},
+ {"Flags", Type, 0},
+ {"FoldCase", Const, 0},
+ {"Inst", Type, 0},
+ {"Inst.Arg", Field, 0},
+ {"Inst.Op", Field, 0},
+ {"Inst.Out", Field, 0},
+ {"Inst.Rune", Field, 0},
+ {"InstAlt", Const, 0},
+ {"InstAltMatch", Const, 0},
+ {"InstCapture", Const, 0},
+ {"InstEmptyWidth", Const, 0},
+ {"InstFail", Const, 0},
+ {"InstMatch", Const, 0},
+ {"InstNop", Const, 0},
+ {"InstOp", Type, 0},
+ {"InstRune", Const, 0},
+ {"InstRune1", Const, 0},
+ {"InstRuneAny", Const, 0},
+ {"InstRuneAnyNotNL", Const, 0},
+ {"IsWordChar", Func, 0},
+ {"Literal", Const, 0},
+ {"MatchNL", Const, 0},
+ {"NonGreedy", Const, 0},
+ {"OneLine", Const, 0},
+ {"Op", Type, 0},
+ {"OpAlternate", Const, 0},
+ {"OpAnyChar", Const, 0},
+ {"OpAnyCharNotNL", Const, 0},
+ {"OpBeginLine", Const, 0},
+ {"OpBeginText", Const, 0},
+ {"OpCapture", Const, 0},
+ {"OpCharClass", Const, 0},
+ {"OpConcat", Const, 0},
+ {"OpEmptyMatch", Const, 0},
+ {"OpEndLine", Const, 0},
+ {"OpEndText", Const, 0},
+ {"OpLiteral", Const, 0},
+ {"OpNoMatch", Const, 0},
+ {"OpNoWordBoundary", Const, 0},
+ {"OpPlus", Const, 0},
+ {"OpQuest", Const, 0},
+ {"OpRepeat", Const, 0},
+ {"OpStar", Const, 0},
+ {"OpWordBoundary", Const, 0},
+ {"POSIX", Const, 0},
+ {"Parse", Func, 0},
+ {"Perl", Const, 0},
+ {"PerlX", Const, 0},
+ {"Prog", Type, 0},
+ {"Prog.Inst", Field, 0},
+ {"Prog.NumCap", Field, 0},
+ {"Prog.Start", Field, 0},
+ {"Regexp", Type, 0},
+ {"Regexp.Cap", Field, 0},
+ {"Regexp.Flags", Field, 0},
+ {"Regexp.Max", Field, 0},
+ {"Regexp.Min", Field, 0},
+ {"Regexp.Name", Field, 0},
+ {"Regexp.Op", Field, 0},
+ {"Regexp.Rune", Field, 0},
+ {"Regexp.Rune0", Field, 0},
+ {"Regexp.Sub", Field, 0},
+ {"Regexp.Sub0", Field, 0},
+ {"Simple", Const, 0},
+ {"UnicodeGroups", Const, 0},
+ {"WasDollar", Const, 0},
+ },
+ "runtime": {
+ {"(*BlockProfileRecord).Stack", Method, 1},
+ {"(*Frames).Next", Method, 7},
+ {"(*Func).Entry", Method, 0},
+ {"(*Func).FileLine", Method, 0},
+ {"(*Func).Name", Method, 0},
+ {"(*MemProfileRecord).InUseBytes", Method, 0},
+ {"(*MemProfileRecord).InUseObjects", Method, 0},
+ {"(*MemProfileRecord).Stack", Method, 0},
+ {"(*PanicNilError).Error", Method, 21},
+ {"(*PanicNilError).RuntimeError", Method, 21},
+ {"(*Pinner).Pin", Method, 21},
+ {"(*Pinner).Unpin", Method, 21},
+ {"(*StackRecord).Stack", Method, 0},
+ {"(*TypeAssertionError).Error", Method, 0},
+ {"(*TypeAssertionError).RuntimeError", Method, 0},
+ {"BlockProfile", Func, 1},
+ {"BlockProfileRecord", Type, 1},
+ {"BlockProfileRecord.Count", Field, 1},
+ {"BlockProfileRecord.Cycles", Field, 1},
+ {"BlockProfileRecord.StackRecord", Field, 1},
+ {"Breakpoint", Func, 0},
+ {"CPUProfile", Func, 0},
+ {"Caller", Func, 0},
+ {"Callers", Func, 0},
+ {"CallersFrames", Func, 7},
+ {"Compiler", Const, 0},
+ {"Error", Type, 0},
+ {"Frame", Type, 7},
+ {"Frame.Entry", Field, 7},
+ {"Frame.File", Field, 7},
+ {"Frame.Func", Field, 7},
+ {"Frame.Function", Field, 7},
+ {"Frame.Line", Field, 7},
+ {"Frame.PC", Field, 7},
+ {"Frames", Type, 7},
+ {"Func", Type, 0},
+ {"FuncForPC", Func, 0},
+ {"GC", Func, 0},
+ {"GOARCH", Const, 0},
+ {"GOMAXPROCS", Func, 0},
+ {"GOOS", Const, 0},
+ {"GOROOT", Func, 0},
+ {"Goexit", Func, 0},
+ {"GoroutineProfile", Func, 0},
+ {"Gosched", Func, 0},
+ {"KeepAlive", Func, 7},
+ {"LockOSThread", Func, 0},
+ {"MemProfile", Func, 0},
+ {"MemProfileRate", Var, 0},
+ {"MemProfileRecord", Type, 0},
+ {"MemProfileRecord.AllocBytes", Field, 0},
+ {"MemProfileRecord.AllocObjects", Field, 0},
+ {"MemProfileRecord.FreeBytes", Field, 0},
+ {"MemProfileRecord.FreeObjects", Field, 0},
+ {"MemProfileRecord.Stack0", Field, 0},
+ {"MemStats", Type, 0},
+ {"MemStats.Alloc", Field, 0},
+ {"MemStats.BuckHashSys", Field, 0},
+ {"MemStats.BySize", Field, 0},
+ {"MemStats.DebugGC", Field, 0},
+ {"MemStats.EnableGC", Field, 0},
+ {"MemStats.Frees", Field, 0},
+ {"MemStats.GCCPUFraction", Field, 5},
+ {"MemStats.GCSys", Field, 2},
+ {"MemStats.HeapAlloc", Field, 0},
+ {"MemStats.HeapIdle", Field, 0},
+ {"MemStats.HeapInuse", Field, 0},
+ {"MemStats.HeapObjects", Field, 0},
+ {"MemStats.HeapReleased", Field, 0},
+ {"MemStats.HeapSys", Field, 0},
+ {"MemStats.LastGC", Field, 0},
+ {"MemStats.Lookups", Field, 0},
+ {"MemStats.MCacheInuse", Field, 0},
+ {"MemStats.MCacheSys", Field, 0},
+ {"MemStats.MSpanInuse", Field, 0},
+ {"MemStats.MSpanSys", Field, 0},
+ {"MemStats.Mallocs", Field, 0},
+ {"MemStats.NextGC", Field, 0},
+ {"MemStats.NumForcedGC", Field, 8},
+ {"MemStats.NumGC", Field, 0},
+ {"MemStats.OtherSys", Field, 2},
+ {"MemStats.PauseEnd", Field, 4},
+ {"MemStats.PauseNs", Field, 0},
+ {"MemStats.PauseTotalNs", Field, 0},
+ {"MemStats.StackInuse", Field, 0},
+ {"MemStats.StackSys", Field, 0},
+ {"MemStats.Sys", Field, 0},
+ {"MemStats.TotalAlloc", Field, 0},
+ {"MutexProfile", Func, 8},
+ {"NumCPU", Func, 0},
+ {"NumCgoCall", Func, 0},
+ {"NumGoroutine", Func, 0},
+ {"PanicNilError", Type, 21},
+ {"Pinner", Type, 21},
+ {"ReadMemStats", Func, 0},
+ {"ReadTrace", Func, 5},
+ {"SetBlockProfileRate", Func, 1},
+ {"SetCPUProfileRate", Func, 0},
+ {"SetCgoTraceback", Func, 7},
+ {"SetFinalizer", Func, 0},
+ {"SetMutexProfileFraction", Func, 8},
+ {"Stack", Func, 0},
+ {"StackRecord", Type, 0},
+ {"StackRecord.Stack0", Field, 0},
+ {"StartTrace", Func, 5},
+ {"StopTrace", Func, 5},
+ {"ThreadCreateProfile", Func, 0},
+ {"TypeAssertionError", Type, 0},
+ {"UnlockOSThread", Func, 0},
+ {"Version", Func, 0},
+ },
+ "runtime/cgo": {
+ {"(Handle).Delete", Method, 17},
+ {"(Handle).Value", Method, 17},
+ {"Handle", Type, 17},
+ {"Incomplete", Type, 20},
+ {"NewHandle", Func, 17},
+ },
+ "runtime/coverage": {
+ {"ClearCounters", Func, 20},
+ {"WriteCounters", Func, 20},
+ {"WriteCountersDir", Func, 20},
+ {"WriteMeta", Func, 20},
+ {"WriteMetaDir", Func, 20},
+ },
+ "runtime/debug": {
+ {"(*BuildInfo).String", Method, 18},
+ {"BuildInfo", Type, 12},
+ {"BuildInfo.Deps", Field, 12},
+ {"BuildInfo.GoVersion", Field, 18},
+ {"BuildInfo.Main", Field, 12},
+ {"BuildInfo.Path", Field, 12},
+ {"BuildInfo.Settings", Field, 18},
+ {"BuildSetting", Type, 18},
+ {"BuildSetting.Key", Field, 18},
+ {"BuildSetting.Value", Field, 18},
+ {"CrashOptions", Type, 23},
+ {"FreeOSMemory", Func, 1},
+ {"GCStats", Type, 1},
+ {"GCStats.LastGC", Field, 1},
+ {"GCStats.NumGC", Field, 1},
+ {"GCStats.Pause", Field, 1},
+ {"GCStats.PauseEnd", Field, 4},
+ {"GCStats.PauseQuantiles", Field, 1},
+ {"GCStats.PauseTotal", Field, 1},
+ {"Module", Type, 12},
+ {"Module.Path", Field, 12},
+ {"Module.Replace", Field, 12},
+ {"Module.Sum", Field, 12},
+ {"Module.Version", Field, 12},
+ {"ParseBuildInfo", Func, 18},
+ {"PrintStack", Func, 0},
+ {"ReadBuildInfo", Func, 12},
+ {"ReadGCStats", Func, 1},
+ {"SetCrashOutput", Func, 23},
+ {"SetGCPercent", Func, 1},
+ {"SetMaxStack", Func, 2},
+ {"SetMaxThreads", Func, 2},
+ {"SetMemoryLimit", Func, 19},
+ {"SetPanicOnFault", Func, 3},
+ {"SetTraceback", Func, 6},
+ {"Stack", Func, 0},
+ {"WriteHeapDump", Func, 3},
+ },
+ "runtime/metrics": {
+ {"(Value).Float64", Method, 16},
+ {"(Value).Float64Histogram", Method, 16},
+ {"(Value).Kind", Method, 16},
+ {"(Value).Uint64", Method, 16},
+ {"All", Func, 16},
+ {"Description", Type, 16},
+ {"Description.Cumulative", Field, 16},
+ {"Description.Description", Field, 16},
+ {"Description.Kind", Field, 16},
+ {"Description.Name", Field, 16},
+ {"Float64Histogram", Type, 16},
+ {"Float64Histogram.Buckets", Field, 16},
+ {"Float64Histogram.Counts", Field, 16},
+ {"KindBad", Const, 16},
+ {"KindFloat64", Const, 16},
+ {"KindFloat64Histogram", Const, 16},
+ {"KindUint64", Const, 16},
+ {"Read", Func, 16},
+ {"Sample", Type, 16},
+ {"Sample.Name", Field, 16},
+ {"Sample.Value", Field, 16},
+ {"Value", Type, 16},
+ {"ValueKind", Type, 16},
+ },
+ "runtime/pprof": {
+ {"(*Profile).Add", Method, 0},
+ {"(*Profile).Count", Method, 0},
+ {"(*Profile).Name", Method, 0},
+ {"(*Profile).Remove", Method, 0},
+ {"(*Profile).WriteTo", Method, 0},
+ {"Do", Func, 9},
+ {"ForLabels", Func, 9},
+ {"Label", Func, 9},
+ {"LabelSet", Type, 9},
+ {"Labels", Func, 9},
+ {"Lookup", Func, 0},
+ {"NewProfile", Func, 0},
+ {"Profile", Type, 0},
+ {"Profiles", Func, 0},
+ {"SetGoroutineLabels", Func, 9},
+ {"StartCPUProfile", Func, 0},
+ {"StopCPUProfile", Func, 0},
+ {"WithLabels", Func, 9},
+ {"WriteHeapProfile", Func, 0},
+ },
+ "runtime/trace": {
+ {"(*Region).End", Method, 11},
+ {"(*Task).End", Method, 11},
+ {"IsEnabled", Func, 11},
+ {"Log", Func, 11},
+ {"Logf", Func, 11},
+ {"NewTask", Func, 11},
+ {"Region", Type, 11},
+ {"Start", Func, 5},
+ {"StartRegion", Func, 11},
+ {"Stop", Func, 5},
+ {"Task", Type, 11},
+ {"WithRegion", Func, 11},
+ },
+ "slices": {
+ {"All", Func, 23},
+ {"AppendSeq", Func, 23},
+ {"Backward", Func, 23},
+ {"BinarySearch", Func, 21},
+ {"BinarySearchFunc", Func, 21},
+ {"Chunk", Func, 23},
+ {"Clip", Func, 21},
+ {"Clone", Func, 21},
+ {"Collect", Func, 23},
+ {"Compact", Func, 21},
+ {"CompactFunc", Func, 21},
+ {"Compare", Func, 21},
+ {"CompareFunc", Func, 21},
+ {"Concat", Func, 22},
+ {"Contains", Func, 21},
+ {"ContainsFunc", Func, 21},
+ {"Delete", Func, 21},
+ {"DeleteFunc", Func, 21},
+ {"Equal", Func, 21},
+ {"EqualFunc", Func, 21},
+ {"Grow", Func, 21},
+ {"Index", Func, 21},
+ {"IndexFunc", Func, 21},
+ {"Insert", Func, 21},
+ {"IsSorted", Func, 21},
+ {"IsSortedFunc", Func, 21},
+ {"Max", Func, 21},
+ {"MaxFunc", Func, 21},
+ {"Min", Func, 21},
+ {"MinFunc", Func, 21},
+ {"Repeat", Func, 23},
+ {"Replace", Func, 21},
+ {"Reverse", Func, 21},
+ {"Sort", Func, 21},
+ {"SortFunc", Func, 21},
+ {"SortStableFunc", Func, 21},
+ {"Sorted", Func, 23},
+ {"SortedFunc", Func, 23},
+ {"SortedStableFunc", Func, 23},
+ {"Values", Func, 23},
+ },
+ "sort": {
+ {"(Float64Slice).Len", Method, 0},
+ {"(Float64Slice).Less", Method, 0},
+ {"(Float64Slice).Search", Method, 0},
+ {"(Float64Slice).Sort", Method, 0},
+ {"(Float64Slice).Swap", Method, 0},
+ {"(IntSlice).Len", Method, 0},
+ {"(IntSlice).Less", Method, 0},
+ {"(IntSlice).Search", Method, 0},
+ {"(IntSlice).Sort", Method, 0},
+ {"(IntSlice).Swap", Method, 0},
+ {"(StringSlice).Len", Method, 0},
+ {"(StringSlice).Less", Method, 0},
+ {"(StringSlice).Search", Method, 0},
+ {"(StringSlice).Sort", Method, 0},
+ {"(StringSlice).Swap", Method, 0},
+ {"Find", Func, 19},
+ {"Float64Slice", Type, 0},
+ {"Float64s", Func, 0},
+ {"Float64sAreSorted", Func, 0},
+ {"IntSlice", Type, 0},
+ {"Interface", Type, 0},
+ {"Ints", Func, 0},
+ {"IntsAreSorted", Func, 0},
+ {"IsSorted", Func, 0},
+ {"Reverse", Func, 1},
+ {"Search", Func, 0},
+ {"SearchFloat64s", Func, 0},
+ {"SearchInts", Func, 0},
+ {"SearchStrings", Func, 0},
+ {"Slice", Func, 8},
+ {"SliceIsSorted", Func, 8},
+ {"SliceStable", Func, 8},
+ {"Sort", Func, 0},
+ {"Stable", Func, 2},
+ {"StringSlice", Type, 0},
+ {"Strings", Func, 0},
+ {"StringsAreSorted", Func, 0},
+ },
+ "strconv": {
+ {"(*NumError).Error", Method, 0},
+ {"(*NumError).Unwrap", Method, 14},
+ {"AppendBool", Func, 0},
+ {"AppendFloat", Func, 0},
+ {"AppendInt", Func, 0},
+ {"AppendQuote", Func, 0},
+ {"AppendQuoteRune", Func, 0},
+ {"AppendQuoteRuneToASCII", Func, 0},
+ {"AppendQuoteRuneToGraphic", Func, 6},
+ {"AppendQuoteToASCII", Func, 0},
+ {"AppendQuoteToGraphic", Func, 6},
+ {"AppendUint", Func, 0},
+ {"Atoi", Func, 0},
+ {"CanBackquote", Func, 0},
+ {"ErrRange", Var, 0},
+ {"ErrSyntax", Var, 0},
+ {"FormatBool", Func, 0},
+ {"FormatComplex", Func, 15},
+ {"FormatFloat", Func, 0},
+ {"FormatInt", Func, 0},
+ {"FormatUint", Func, 0},
+ {"IntSize", Const, 0},
+ {"IsGraphic", Func, 6},
+ {"IsPrint", Func, 0},
+ {"Itoa", Func, 0},
+ {"NumError", Type, 0},
+ {"NumError.Err", Field, 0},
+ {"NumError.Func", Field, 0},
+ {"NumError.Num", Field, 0},
+ {"ParseBool", Func, 0},
+ {"ParseComplex", Func, 15},
+ {"ParseFloat", Func, 0},
+ {"ParseInt", Func, 0},
+ {"ParseUint", Func, 0},
+ {"Quote", Func, 0},
+ {"QuoteRune", Func, 0},
+ {"QuoteRuneToASCII", Func, 0},
+ {"QuoteRuneToGraphic", Func, 6},
+ {"QuoteToASCII", Func, 0},
+ {"QuoteToGraphic", Func, 6},
+ {"QuotedPrefix", Func, 17},
+ {"Unquote", Func, 0},
+ {"UnquoteChar", Func, 0},
+ },
+ "strings": {
+ {"(*Builder).Cap", Method, 12},
+ {"(*Builder).Grow", Method, 10},
+ {"(*Builder).Len", Method, 10},
+ {"(*Builder).Reset", Method, 10},
+ {"(*Builder).String", Method, 10},
+ {"(*Builder).Write", Method, 10},
+ {"(*Builder).WriteByte", Method, 10},
+ {"(*Builder).WriteRune", Method, 10},
+ {"(*Builder).WriteString", Method, 10},
+ {"(*Reader).Len", Method, 0},
+ {"(*Reader).Read", Method, 0},
+ {"(*Reader).ReadAt", Method, 0},
+ {"(*Reader).ReadByte", Method, 0},
+ {"(*Reader).ReadRune", Method, 0},
+ {"(*Reader).Reset", Method, 7},
+ {"(*Reader).Seek", Method, 0},
+ {"(*Reader).Size", Method, 5},
+ {"(*Reader).UnreadByte", Method, 0},
+ {"(*Reader).UnreadRune", Method, 0},
+ {"(*Reader).WriteTo", Method, 1},
+ {"(*Replacer).Replace", Method, 0},
+ {"(*Replacer).WriteString", Method, 0},
+ {"Builder", Type, 10},
+ {"Clone", Func, 18},
+ {"Compare", Func, 5},
+ {"Contains", Func, 0},
+ {"ContainsAny", Func, 0},
+ {"ContainsFunc", Func, 21},
+ {"ContainsRune", Func, 0},
+ {"Count", Func, 0},
+ {"Cut", Func, 18},
+ {"CutPrefix", Func, 20},
+ {"CutSuffix", Func, 20},
+ {"EqualFold", Func, 0},
+ {"Fields", Func, 0},
+ {"FieldsFunc", Func, 0},
+ {"HasPrefix", Func, 0},
+ {"HasSuffix", Func, 0},
+ {"Index", Func, 0},
+ {"IndexAny", Func, 0},
+ {"IndexByte", Func, 2},
+ {"IndexFunc", Func, 0},
+ {"IndexRune", Func, 0},
+ {"Join", Func, 0},
+ {"LastIndex", Func, 0},
+ {"LastIndexAny", Func, 0},
+ {"LastIndexByte", Func, 5},
+ {"LastIndexFunc", Func, 0},
+ {"Map", Func, 0},
+ {"NewReader", Func, 0},
+ {"NewReplacer", Func, 0},
+ {"Reader", Type, 0},
+ {"Repeat", Func, 0},
+ {"Replace", Func, 0},
+ {"ReplaceAll", Func, 12},
+ {"Replacer", Type, 0},
+ {"Split", Func, 0},
+ {"SplitAfter", Func, 0},
+ {"SplitAfterN", Func, 0},
+ {"SplitN", Func, 0},
+ {"Title", Func, 0},
+ {"ToLower", Func, 0},
+ {"ToLowerSpecial", Func, 0},
+ {"ToTitle", Func, 0},
+ {"ToTitleSpecial", Func, 0},
+ {"ToUpper", Func, 0},
+ {"ToUpperSpecial", Func, 0},
+ {"ToValidUTF8", Func, 13},
+ {"Trim", Func, 0},
+ {"TrimFunc", Func, 0},
+ {"TrimLeft", Func, 0},
+ {"TrimLeftFunc", Func, 0},
+ {"TrimPrefix", Func, 1},
+ {"TrimRight", Func, 0},
+ {"TrimRightFunc", Func, 0},
+ {"TrimSpace", Func, 0},
+ {"TrimSuffix", Func, 1},
+ },
+ "structs": {
+ {"HostLayout", Type, 23},
+ },
+ "sync": {
+ {"(*Cond).Broadcast", Method, 0},
+ {"(*Cond).Signal", Method, 0},
+ {"(*Cond).Wait", Method, 0},
+ {"(*Map).Clear", Method, 23},
+ {"(*Map).CompareAndDelete", Method, 20},
+ {"(*Map).CompareAndSwap", Method, 20},
+ {"(*Map).Delete", Method, 9},
+ {"(*Map).Load", Method, 9},
+ {"(*Map).LoadAndDelete", Method, 15},
+ {"(*Map).LoadOrStore", Method, 9},
+ {"(*Map).Range", Method, 9},
+ {"(*Map).Store", Method, 9},
+ {"(*Map).Swap", Method, 20},
+ {"(*Mutex).Lock", Method, 0},
+ {"(*Mutex).TryLock", Method, 18},
+ {"(*Mutex).Unlock", Method, 0},
+ {"(*Once).Do", Method, 0},
+ {"(*Pool).Get", Method, 3},
+ {"(*Pool).Put", Method, 3},
+ {"(*RWMutex).Lock", Method, 0},
+ {"(*RWMutex).RLock", Method, 0},
+ {"(*RWMutex).RLocker", Method, 0},
+ {"(*RWMutex).RUnlock", Method, 0},
+ {"(*RWMutex).TryLock", Method, 18},
+ {"(*RWMutex).TryRLock", Method, 18},
+ {"(*RWMutex).Unlock", Method, 0},
+ {"(*WaitGroup).Add", Method, 0},
+ {"(*WaitGroup).Done", Method, 0},
+ {"(*WaitGroup).Wait", Method, 0},
+ {"Cond", Type, 0},
+ {"Cond.L", Field, 0},
+ {"Locker", Type, 0},
+ {"Map", Type, 9},
+ {"Mutex", Type, 0},
+ {"NewCond", Func, 0},
+ {"Once", Type, 0},
+ {"OnceFunc", Func, 21},
+ {"OnceValue", Func, 21},
+ {"OnceValues", Func, 21},
+ {"Pool", Type, 3},
+ {"Pool.New", Field, 3},
+ {"RWMutex", Type, 0},
+ {"WaitGroup", Type, 0},
+ },
+ "sync/atomic": {
+ {"(*Bool).CompareAndSwap", Method, 19},
+ {"(*Bool).Load", Method, 19},
+ {"(*Bool).Store", Method, 19},
+ {"(*Bool).Swap", Method, 19},
+ {"(*Int32).Add", Method, 19},
+ {"(*Int32).And", Method, 23},
+ {"(*Int32).CompareAndSwap", Method, 19},
+ {"(*Int32).Load", Method, 19},
+ {"(*Int32).Or", Method, 23},
+ {"(*Int32).Store", Method, 19},
+ {"(*Int32).Swap", Method, 19},
+ {"(*Int64).Add", Method, 19},
+ {"(*Int64).And", Method, 23},
+ {"(*Int64).CompareAndSwap", Method, 19},
+ {"(*Int64).Load", Method, 19},
+ {"(*Int64).Or", Method, 23},
+ {"(*Int64).Store", Method, 19},
+ {"(*Int64).Swap", Method, 19},
+ {"(*Pointer).CompareAndSwap", Method, 19},
+ {"(*Pointer).Load", Method, 19},
+ {"(*Pointer).Store", Method, 19},
+ {"(*Pointer).Swap", Method, 19},
+ {"(*Uint32).Add", Method, 19},
+ {"(*Uint32).And", Method, 23},
+ {"(*Uint32).CompareAndSwap", Method, 19},
+ {"(*Uint32).Load", Method, 19},
+ {"(*Uint32).Or", Method, 23},
+ {"(*Uint32).Store", Method, 19},
+ {"(*Uint32).Swap", Method, 19},
+ {"(*Uint64).Add", Method, 19},
+ {"(*Uint64).And", Method, 23},
+ {"(*Uint64).CompareAndSwap", Method, 19},
+ {"(*Uint64).Load", Method, 19},
+ {"(*Uint64).Or", Method, 23},
+ {"(*Uint64).Store", Method, 19},
+ {"(*Uint64).Swap", Method, 19},
+ {"(*Uintptr).Add", Method, 19},
+ {"(*Uintptr).And", Method, 23},
+ {"(*Uintptr).CompareAndSwap", Method, 19},
+ {"(*Uintptr).Load", Method, 19},
+ {"(*Uintptr).Or", Method, 23},
+ {"(*Uintptr).Store", Method, 19},
+ {"(*Uintptr).Swap", Method, 19},
+ {"(*Value).CompareAndSwap", Method, 17},
+ {"(*Value).Load", Method, 4},
+ {"(*Value).Store", Method, 4},
+ {"(*Value).Swap", Method, 17},
+ {"AddInt32", Func, 0},
+ {"AddInt64", Func, 0},
+ {"AddUint32", Func, 0},
+ {"AddUint64", Func, 0},
+ {"AddUintptr", Func, 0},
+ {"AndInt32", Func, 23},
+ {"AndInt64", Func, 23},
+ {"AndUint32", Func, 23},
+ {"AndUint64", Func, 23},
+ {"AndUintptr", Func, 23},
+ {"Bool", Type, 19},
+ {"CompareAndSwapInt32", Func, 0},
+ {"CompareAndSwapInt64", Func, 0},
+ {"CompareAndSwapPointer", Func, 0},
+ {"CompareAndSwapUint32", Func, 0},
+ {"CompareAndSwapUint64", Func, 0},
+ {"CompareAndSwapUintptr", Func, 0},
+ {"Int32", Type, 19},
+ {"Int64", Type, 19},
+ {"LoadInt32", Func, 0},
+ {"LoadInt64", Func, 0},
+ {"LoadPointer", Func, 0},
+ {"LoadUint32", Func, 0},
+ {"LoadUint64", Func, 0},
+ {"LoadUintptr", Func, 0},
+ {"OrInt32", Func, 23},
+ {"OrInt64", Func, 23},
+ {"OrUint32", Func, 23},
+ {"OrUint64", Func, 23},
+ {"OrUintptr", Func, 23},
+ {"Pointer", Type, 19},
+ {"StoreInt32", Func, 0},
+ {"StoreInt64", Func, 0},
+ {"StorePointer", Func, 0},
+ {"StoreUint32", Func, 0},
+ {"StoreUint64", Func, 0},
+ {"StoreUintptr", Func, 0},
+ {"SwapInt32", Func, 2},
+ {"SwapInt64", Func, 2},
+ {"SwapPointer", Func, 2},
+ {"SwapUint32", Func, 2},
+ {"SwapUint64", Func, 2},
+ {"SwapUintptr", Func, 2},
+ {"Uint32", Type, 19},
+ {"Uint64", Type, 19},
+ {"Uintptr", Type, 19},
+ {"Value", Type, 4},
+ },
+ "syscall": {
+ {"(*Cmsghdr).SetLen", Method, 0},
+ {"(*DLL).FindProc", Method, 0},
+ {"(*DLL).MustFindProc", Method, 0},
+ {"(*DLL).Release", Method, 0},
+ {"(*DLLError).Error", Method, 0},
+ {"(*DLLError).Unwrap", Method, 16},
+ {"(*Filetime).Nanoseconds", Method, 0},
+ {"(*Iovec).SetLen", Method, 0},
+ {"(*LazyDLL).Handle", Method, 0},
+ {"(*LazyDLL).Load", Method, 0},
+ {"(*LazyDLL).NewProc", Method, 0},
+ {"(*LazyProc).Addr", Method, 0},
+ {"(*LazyProc).Call", Method, 0},
+ {"(*LazyProc).Find", Method, 0},
+ {"(*Msghdr).SetControllen", Method, 0},
+ {"(*Proc).Addr", Method, 0},
+ {"(*Proc).Call", Method, 0},
+ {"(*PtraceRegs).PC", Method, 0},
+ {"(*PtraceRegs).SetPC", Method, 0},
+ {"(*RawSockaddrAny).Sockaddr", Method, 0},
+ {"(*SID).Copy", Method, 0},
+ {"(*SID).Len", Method, 0},
+ {"(*SID).LookupAccount", Method, 0},
+ {"(*SID).String", Method, 0},
+ {"(*Timespec).Nano", Method, 0},
+ {"(*Timespec).Unix", Method, 0},
+ {"(*Timeval).Nano", Method, 0},
+ {"(*Timeval).Nanoseconds", Method, 0},
+ {"(*Timeval).Unix", Method, 0},
+ {"(Errno).Error", Method, 0},
+ {"(Errno).Is", Method, 13},
+ {"(Errno).Temporary", Method, 0},
+ {"(Errno).Timeout", Method, 0},
+ {"(Signal).Signal", Method, 0},
+ {"(Signal).String", Method, 0},
+ {"(Token).Close", Method, 0},
+ {"(Token).GetTokenPrimaryGroup", Method, 0},
+ {"(Token).GetTokenUser", Method, 0},
+ {"(Token).GetUserProfileDirectory", Method, 0},
+ {"(WaitStatus).Continued", Method, 0},
+ {"(WaitStatus).CoreDump", Method, 0},
+ {"(WaitStatus).ExitStatus", Method, 0},
+ {"(WaitStatus).Exited", Method, 0},
+ {"(WaitStatus).Signal", Method, 0},
+ {"(WaitStatus).Signaled", Method, 0},
+ {"(WaitStatus).StopSignal", Method, 0},
+ {"(WaitStatus).Stopped", Method, 0},
+ {"(WaitStatus).TrapCause", Method, 0},
+ {"AF_ALG", Const, 0},
+ {"AF_APPLETALK", Const, 0},
+ {"AF_ARP", Const, 0},
+ {"AF_ASH", Const, 0},
+ {"AF_ATM", Const, 0},
+ {"AF_ATMPVC", Const, 0},
+ {"AF_ATMSVC", Const, 0},
+ {"AF_AX25", Const, 0},
+ {"AF_BLUETOOTH", Const, 0},
+ {"AF_BRIDGE", Const, 0},
+ {"AF_CAIF", Const, 0},
+ {"AF_CAN", Const, 0},
+ {"AF_CCITT", Const, 0},
+ {"AF_CHAOS", Const, 0},
+ {"AF_CNT", Const, 0},
+ {"AF_COIP", Const, 0},
+ {"AF_DATAKIT", Const, 0},
+ {"AF_DECnet", Const, 0},
+ {"AF_DLI", Const, 0},
+ {"AF_E164", Const, 0},
+ {"AF_ECMA", Const, 0},
+ {"AF_ECONET", Const, 0},
+ {"AF_ENCAP", Const, 1},
+ {"AF_FILE", Const, 0},
+ {"AF_HYLINK", Const, 0},
+ {"AF_IEEE80211", Const, 0},
+ {"AF_IEEE802154", Const, 0},
+ {"AF_IMPLINK", Const, 0},
+ {"AF_INET", Const, 0},
+ {"AF_INET6", Const, 0},
+ {"AF_INET6_SDP", Const, 3},
+ {"AF_INET_SDP", Const, 3},
+ {"AF_IPX", Const, 0},
+ {"AF_IRDA", Const, 0},
+ {"AF_ISDN", Const, 0},
+ {"AF_ISO", Const, 0},
+ {"AF_IUCV", Const, 0},
+ {"AF_KEY", Const, 0},
+ {"AF_LAT", Const, 0},
+ {"AF_LINK", Const, 0},
+ {"AF_LLC", Const, 0},
+ {"AF_LOCAL", Const, 0},
+ {"AF_MAX", Const, 0},
+ {"AF_MPLS", Const, 1},
+ {"AF_NATM", Const, 0},
+ {"AF_NDRV", Const, 0},
+ {"AF_NETBEUI", Const, 0},
+ {"AF_NETBIOS", Const, 0},
+ {"AF_NETGRAPH", Const, 0},
+ {"AF_NETLINK", Const, 0},
+ {"AF_NETROM", Const, 0},
+ {"AF_NS", Const, 0},
+ {"AF_OROUTE", Const, 1},
+ {"AF_OSI", Const, 0},
+ {"AF_PACKET", Const, 0},
+ {"AF_PHONET", Const, 0},
+ {"AF_PPP", Const, 0},
+ {"AF_PPPOX", Const, 0},
+ {"AF_PUP", Const, 0},
+ {"AF_RDS", Const, 0},
+ {"AF_RESERVED_36", Const, 0},
+ {"AF_ROSE", Const, 0},
+ {"AF_ROUTE", Const, 0},
+ {"AF_RXRPC", Const, 0},
+ {"AF_SCLUSTER", Const, 0},
+ {"AF_SECURITY", Const, 0},
+ {"AF_SIP", Const, 0},
+ {"AF_SLOW", Const, 0},
+ {"AF_SNA", Const, 0},
+ {"AF_SYSTEM", Const, 0},
+ {"AF_TIPC", Const, 0},
+ {"AF_UNIX", Const, 0},
+ {"AF_UNSPEC", Const, 0},
+ {"AF_UTUN", Const, 16},
+ {"AF_VENDOR00", Const, 0},
+ {"AF_VENDOR01", Const, 0},
+ {"AF_VENDOR02", Const, 0},
+ {"AF_VENDOR03", Const, 0},
+ {"AF_VENDOR04", Const, 0},
+ {"AF_VENDOR05", Const, 0},
+ {"AF_VENDOR06", Const, 0},
+ {"AF_VENDOR07", Const, 0},
+ {"AF_VENDOR08", Const, 0},
+ {"AF_VENDOR09", Const, 0},
+ {"AF_VENDOR10", Const, 0},
+ {"AF_VENDOR11", Const, 0},
+ {"AF_VENDOR12", Const, 0},
+ {"AF_VENDOR13", Const, 0},
+ {"AF_VENDOR14", Const, 0},
+ {"AF_VENDOR15", Const, 0},
+ {"AF_VENDOR16", Const, 0},
+ {"AF_VENDOR17", Const, 0},
+ {"AF_VENDOR18", Const, 0},
+ {"AF_VENDOR19", Const, 0},
+ {"AF_VENDOR20", Const, 0},
+ {"AF_VENDOR21", Const, 0},
+ {"AF_VENDOR22", Const, 0},
+ {"AF_VENDOR23", Const, 0},
+ {"AF_VENDOR24", Const, 0},
+ {"AF_VENDOR25", Const, 0},
+ {"AF_VENDOR26", Const, 0},
+ {"AF_VENDOR27", Const, 0},
+ {"AF_VENDOR28", Const, 0},
+ {"AF_VENDOR29", Const, 0},
+ {"AF_VENDOR30", Const, 0},
+ {"AF_VENDOR31", Const, 0},
+ {"AF_VENDOR32", Const, 0},
+ {"AF_VENDOR33", Const, 0},
+ {"AF_VENDOR34", Const, 0},
+ {"AF_VENDOR35", Const, 0},
+ {"AF_VENDOR36", Const, 0},
+ {"AF_VENDOR37", Const, 0},
+ {"AF_VENDOR38", Const, 0},
+ {"AF_VENDOR39", Const, 0},
+ {"AF_VENDOR40", Const, 0},
+ {"AF_VENDOR41", Const, 0},
+ {"AF_VENDOR42", Const, 0},
+ {"AF_VENDOR43", Const, 0},
+ {"AF_VENDOR44", Const, 0},
+ {"AF_VENDOR45", Const, 0},
+ {"AF_VENDOR46", Const, 0},
+ {"AF_VENDOR47", Const, 0},
+ {"AF_WANPIPE", Const, 0},
+ {"AF_X25", Const, 0},
+ {"AI_CANONNAME", Const, 1},
+ {"AI_NUMERICHOST", Const, 1},
+ {"AI_PASSIVE", Const, 1},
+ {"APPLICATION_ERROR", Const, 0},
+ {"ARPHRD_ADAPT", Const, 0},
+ {"ARPHRD_APPLETLK", Const, 0},
+ {"ARPHRD_ARCNET", Const, 0},
+ {"ARPHRD_ASH", Const, 0},
+ {"ARPHRD_ATM", Const, 0},
+ {"ARPHRD_AX25", Const, 0},
+ {"ARPHRD_BIF", Const, 0},
+ {"ARPHRD_CHAOS", Const, 0},
+ {"ARPHRD_CISCO", Const, 0},
+ {"ARPHRD_CSLIP", Const, 0},
+ {"ARPHRD_CSLIP6", Const, 0},
+ {"ARPHRD_DDCMP", Const, 0},
+ {"ARPHRD_DLCI", Const, 0},
+ {"ARPHRD_ECONET", Const, 0},
+ {"ARPHRD_EETHER", Const, 0},
+ {"ARPHRD_ETHER", Const, 0},
+ {"ARPHRD_EUI64", Const, 0},
+ {"ARPHRD_FCAL", Const, 0},
+ {"ARPHRD_FCFABRIC", Const, 0},
+ {"ARPHRD_FCPL", Const, 0},
+ {"ARPHRD_FCPP", Const, 0},
+ {"ARPHRD_FDDI", Const, 0},
+ {"ARPHRD_FRAD", Const, 0},
+ {"ARPHRD_FRELAY", Const, 1},
+ {"ARPHRD_HDLC", Const, 0},
+ {"ARPHRD_HIPPI", Const, 0},
+ {"ARPHRD_HWX25", Const, 0},
+ {"ARPHRD_IEEE1394", Const, 0},
+ {"ARPHRD_IEEE802", Const, 0},
+ {"ARPHRD_IEEE80211", Const, 0},
+ {"ARPHRD_IEEE80211_PRISM", Const, 0},
+ {"ARPHRD_IEEE80211_RADIOTAP", Const, 0},
+ {"ARPHRD_IEEE802154", Const, 0},
+ {"ARPHRD_IEEE802154_PHY", Const, 0},
+ {"ARPHRD_IEEE802_TR", Const, 0},
+ {"ARPHRD_INFINIBAND", Const, 0},
+ {"ARPHRD_IPDDP", Const, 0},
+ {"ARPHRD_IPGRE", Const, 0},
+ {"ARPHRD_IRDA", Const, 0},
+ {"ARPHRD_LAPB", Const, 0},
+ {"ARPHRD_LOCALTLK", Const, 0},
+ {"ARPHRD_LOOPBACK", Const, 0},
+ {"ARPHRD_METRICOM", Const, 0},
+ {"ARPHRD_NETROM", Const, 0},
+ {"ARPHRD_NONE", Const, 0},
+ {"ARPHRD_PIMREG", Const, 0},
+ {"ARPHRD_PPP", Const, 0},
+ {"ARPHRD_PRONET", Const, 0},
+ {"ARPHRD_RAWHDLC", Const, 0},
+ {"ARPHRD_ROSE", Const, 0},
+ {"ARPHRD_RSRVD", Const, 0},
+ {"ARPHRD_SIT", Const, 0},
+ {"ARPHRD_SKIP", Const, 0},
+ {"ARPHRD_SLIP", Const, 0},
+ {"ARPHRD_SLIP6", Const, 0},
+ {"ARPHRD_STRIP", Const, 1},
+ {"ARPHRD_TUNNEL", Const, 0},
+ {"ARPHRD_TUNNEL6", Const, 0},
+ {"ARPHRD_VOID", Const, 0},
+ {"ARPHRD_X25", Const, 0},
+ {"AUTHTYPE_CLIENT", Const, 0},
+ {"AUTHTYPE_SERVER", Const, 0},
+ {"Accept", Func, 0},
+ {"Accept4", Func, 1},
+ {"AcceptEx", Func, 0},
+ {"Access", Func, 0},
+ {"Acct", Func, 0},
+ {"AddrinfoW", Type, 1},
+ {"AddrinfoW.Addr", Field, 1},
+ {"AddrinfoW.Addrlen", Field, 1},
+ {"AddrinfoW.Canonname", Field, 1},
+ {"AddrinfoW.Family", Field, 1},
+ {"AddrinfoW.Flags", Field, 1},
+ {"AddrinfoW.Next", Field, 1},
+ {"AddrinfoW.Protocol", Field, 1},
+ {"AddrinfoW.Socktype", Field, 1},
+ {"Adjtime", Func, 0},
+ {"Adjtimex", Func, 0},
+ {"AllThreadsSyscall", Func, 16},
+ {"AllThreadsSyscall6", Func, 16},
+ {"AttachLsf", Func, 0},
+ {"B0", Const, 0},
+ {"B1000000", Const, 0},
+ {"B110", Const, 0},
+ {"B115200", Const, 0},
+ {"B1152000", Const, 0},
+ {"B1200", Const, 0},
+ {"B134", Const, 0},
+ {"B14400", Const, 1},
+ {"B150", Const, 0},
+ {"B1500000", Const, 0},
+ {"B1800", Const, 0},
+ {"B19200", Const, 0},
+ {"B200", Const, 0},
+ {"B2000000", Const, 0},
+ {"B230400", Const, 0},
+ {"B2400", Const, 0},
+ {"B2500000", Const, 0},
+ {"B28800", Const, 1},
+ {"B300", Const, 0},
+ {"B3000000", Const, 0},
+ {"B3500000", Const, 0},
+ {"B38400", Const, 0},
+ {"B4000000", Const, 0},
+ {"B460800", Const, 0},
+ {"B4800", Const, 0},
+ {"B50", Const, 0},
+ {"B500000", Const, 0},
+ {"B57600", Const, 0},
+ {"B576000", Const, 0},
+ {"B600", Const, 0},
+ {"B7200", Const, 1},
+ {"B75", Const, 0},
+ {"B76800", Const, 1},
+ {"B921600", Const, 0},
+ {"B9600", Const, 0},
+ {"BASE_PROTOCOL", Const, 2},
+ {"BIOCFEEDBACK", Const, 0},
+ {"BIOCFLUSH", Const, 0},
+ {"BIOCGBLEN", Const, 0},
+ {"BIOCGDIRECTION", Const, 0},
+ {"BIOCGDIRFILT", Const, 1},
+ {"BIOCGDLT", Const, 0},
+ {"BIOCGDLTLIST", Const, 0},
+ {"BIOCGETBUFMODE", Const, 0},
+ {"BIOCGETIF", Const, 0},
+ {"BIOCGETZMAX", Const, 0},
+ {"BIOCGFEEDBACK", Const, 1},
+ {"BIOCGFILDROP", Const, 1},
+ {"BIOCGHDRCMPLT", Const, 0},
+ {"BIOCGRSIG", Const, 0},
+ {"BIOCGRTIMEOUT", Const, 0},
+ {"BIOCGSEESENT", Const, 0},
+ {"BIOCGSTATS", Const, 0},
+ {"BIOCGSTATSOLD", Const, 1},
+ {"BIOCGTSTAMP", Const, 1},
+ {"BIOCIMMEDIATE", Const, 0},
+ {"BIOCLOCK", Const, 0},
+ {"BIOCPROMISC", Const, 0},
+ {"BIOCROTZBUF", Const, 0},
+ {"BIOCSBLEN", Const, 0},
+ {"BIOCSDIRECTION", Const, 0},
+ {"BIOCSDIRFILT", Const, 1},
+ {"BIOCSDLT", Const, 0},
+ {"BIOCSETBUFMODE", Const, 0},
+ {"BIOCSETF", Const, 0},
+ {"BIOCSETFNR", Const, 0},
+ {"BIOCSETIF", Const, 0},
+ {"BIOCSETWF", Const, 0},
+ {"BIOCSETZBUF", Const, 0},
+ {"BIOCSFEEDBACK", Const, 1},
+ {"BIOCSFILDROP", Const, 1},
+ {"BIOCSHDRCMPLT", Const, 0},
+ {"BIOCSRSIG", Const, 0},
+ {"BIOCSRTIMEOUT", Const, 0},
+ {"BIOCSSEESENT", Const, 0},
+ {"BIOCSTCPF", Const, 1},
+ {"BIOCSTSTAMP", Const, 1},
+ {"BIOCSUDPF", Const, 1},
+ {"BIOCVERSION", Const, 0},
+ {"BPF_A", Const, 0},
+ {"BPF_ABS", Const, 0},
+ {"BPF_ADD", Const, 0},
+ {"BPF_ALIGNMENT", Const, 0},
+ {"BPF_ALIGNMENT32", Const, 1},
+ {"BPF_ALU", Const, 0},
+ {"BPF_AND", Const, 0},
+ {"BPF_B", Const, 0},
+ {"BPF_BUFMODE_BUFFER", Const, 0},
+ {"BPF_BUFMODE_ZBUF", Const, 0},
+ {"BPF_DFLTBUFSIZE", Const, 1},
+ {"BPF_DIRECTION_IN", Const, 1},
+ {"BPF_DIRECTION_OUT", Const, 1},
+ {"BPF_DIV", Const, 0},
+ {"BPF_H", Const, 0},
+ {"BPF_IMM", Const, 0},
+ {"BPF_IND", Const, 0},
+ {"BPF_JA", Const, 0},
+ {"BPF_JEQ", Const, 0},
+ {"BPF_JGE", Const, 0},
+ {"BPF_JGT", Const, 0},
+ {"BPF_JMP", Const, 0},
+ {"BPF_JSET", Const, 0},
+ {"BPF_K", Const, 0},
+ {"BPF_LD", Const, 0},
+ {"BPF_LDX", Const, 0},
+ {"BPF_LEN", Const, 0},
+ {"BPF_LSH", Const, 0},
+ {"BPF_MAJOR_VERSION", Const, 0},
+ {"BPF_MAXBUFSIZE", Const, 0},
+ {"BPF_MAXINSNS", Const, 0},
+ {"BPF_MEM", Const, 0},
+ {"BPF_MEMWORDS", Const, 0},
+ {"BPF_MINBUFSIZE", Const, 0},
+ {"BPF_MINOR_VERSION", Const, 0},
+ {"BPF_MISC", Const, 0},
+ {"BPF_MSH", Const, 0},
+ {"BPF_MUL", Const, 0},
+ {"BPF_NEG", Const, 0},
+ {"BPF_OR", Const, 0},
+ {"BPF_RELEASE", Const, 0},
+ {"BPF_RET", Const, 0},
+ {"BPF_RSH", Const, 0},
+ {"BPF_ST", Const, 0},
+ {"BPF_STX", Const, 0},
+ {"BPF_SUB", Const, 0},
+ {"BPF_TAX", Const, 0},
+ {"BPF_TXA", Const, 0},
+ {"BPF_T_BINTIME", Const, 1},
+ {"BPF_T_BINTIME_FAST", Const, 1},
+ {"BPF_T_BINTIME_MONOTONIC", Const, 1},
+ {"BPF_T_BINTIME_MONOTONIC_FAST", Const, 1},
+ {"BPF_T_FAST", Const, 1},
+ {"BPF_T_FLAG_MASK", Const, 1},
+ {"BPF_T_FORMAT_MASK", Const, 1},
+ {"BPF_T_MICROTIME", Const, 1},
+ {"BPF_T_MICROTIME_FAST", Const, 1},
+ {"BPF_T_MICROTIME_MONOTONIC", Const, 1},
+ {"BPF_T_MICROTIME_MONOTONIC_FAST", Const, 1},
+ {"BPF_T_MONOTONIC", Const, 1},
+ {"BPF_T_MONOTONIC_FAST", Const, 1},
+ {"BPF_T_NANOTIME", Const, 1},
+ {"BPF_T_NANOTIME_FAST", Const, 1},
+ {"BPF_T_NANOTIME_MONOTONIC", Const, 1},
+ {"BPF_T_NANOTIME_MONOTONIC_FAST", Const, 1},
+ {"BPF_T_NONE", Const, 1},
+ {"BPF_T_NORMAL", Const, 1},
+ {"BPF_W", Const, 0},
+ {"BPF_X", Const, 0},
+ {"BRKINT", Const, 0},
+ {"Bind", Func, 0},
+ {"BindToDevice", Func, 0},
+ {"BpfBuflen", Func, 0},
+ {"BpfDatalink", Func, 0},
+ {"BpfHdr", Type, 0},
+ {"BpfHdr.Caplen", Field, 0},
+ {"BpfHdr.Datalen", Field, 0},
+ {"BpfHdr.Hdrlen", Field, 0},
+ {"BpfHdr.Pad_cgo_0", Field, 0},
+ {"BpfHdr.Tstamp", Field, 0},
+ {"BpfHeadercmpl", Func, 0},
+ {"BpfInsn", Type, 0},
+ {"BpfInsn.Code", Field, 0},
+ {"BpfInsn.Jf", Field, 0},
+ {"BpfInsn.Jt", Field, 0},
+ {"BpfInsn.K", Field, 0},
+ {"BpfInterface", Func, 0},
+ {"BpfJump", Func, 0},
+ {"BpfProgram", Type, 0},
+ {"BpfProgram.Insns", Field, 0},
+ {"BpfProgram.Len", Field, 0},
+ {"BpfProgram.Pad_cgo_0", Field, 0},
+ {"BpfStat", Type, 0},
+ {"BpfStat.Capt", Field, 2},
+ {"BpfStat.Drop", Field, 0},
+ {"BpfStat.Padding", Field, 2},
+ {"BpfStat.Recv", Field, 0},
+ {"BpfStats", Func, 0},
+ {"BpfStmt", Func, 0},
+ {"BpfTimeout", Func, 0},
+ {"BpfTimeval", Type, 2},
+ {"BpfTimeval.Sec", Field, 2},
+ {"BpfTimeval.Usec", Field, 2},
+ {"BpfVersion", Type, 0},
+ {"BpfVersion.Major", Field, 0},
+ {"BpfVersion.Minor", Field, 0},
+ {"BpfZbuf", Type, 0},
+ {"BpfZbuf.Bufa", Field, 0},
+ {"BpfZbuf.Bufb", Field, 0},
+ {"BpfZbuf.Buflen", Field, 0},
+ {"BpfZbufHeader", Type, 0},
+ {"BpfZbufHeader.Kernel_gen", Field, 0},
+ {"BpfZbufHeader.Kernel_len", Field, 0},
+ {"BpfZbufHeader.User_gen", Field, 0},
+ {"BpfZbufHeader.X_bzh_pad", Field, 0},
+ {"ByHandleFileInformation", Type, 0},
+ {"ByHandleFileInformation.CreationTime", Field, 0},
+ {"ByHandleFileInformation.FileAttributes", Field, 0},
+ {"ByHandleFileInformation.FileIndexHigh", Field, 0},
+ {"ByHandleFileInformation.FileIndexLow", Field, 0},
+ {"ByHandleFileInformation.FileSizeHigh", Field, 0},
+ {"ByHandleFileInformation.FileSizeLow", Field, 0},
+ {"ByHandleFileInformation.LastAccessTime", Field, 0},
+ {"ByHandleFileInformation.LastWriteTime", Field, 0},
+ {"ByHandleFileInformation.NumberOfLinks", Field, 0},
+ {"ByHandleFileInformation.VolumeSerialNumber", Field, 0},
+ {"BytePtrFromString", Func, 1},
+ {"ByteSliceFromString", Func, 1},
+ {"CCR0_FLUSH", Const, 1},
+ {"CERT_CHAIN_POLICY_AUTHENTICODE", Const, 0},
+ {"CERT_CHAIN_POLICY_AUTHENTICODE_TS", Const, 0},
+ {"CERT_CHAIN_POLICY_BASE", Const, 0},
+ {"CERT_CHAIN_POLICY_BASIC_CONSTRAINTS", Const, 0},
+ {"CERT_CHAIN_POLICY_EV", Const, 0},
+ {"CERT_CHAIN_POLICY_MICROSOFT_ROOT", Const, 0},
+ {"CERT_CHAIN_POLICY_NT_AUTH", Const, 0},
+ {"CERT_CHAIN_POLICY_SSL", Const, 0},
+ {"CERT_E_CN_NO_MATCH", Const, 0},
+ {"CERT_E_EXPIRED", Const, 0},
+ {"CERT_E_PURPOSE", Const, 0},
+ {"CERT_E_ROLE", Const, 0},
+ {"CERT_E_UNTRUSTEDROOT", Const, 0},
+ {"CERT_STORE_ADD_ALWAYS", Const, 0},
+ {"CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG", Const, 0},
+ {"CERT_STORE_PROV_MEMORY", Const, 0},
+ {"CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT", Const, 0},
+ {"CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT", Const, 0},
+ {"CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT", Const, 0},
+ {"CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT", Const, 0},
+ {"CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT", Const, 0},
+ {"CERT_TRUST_INVALID_BASIC_CONSTRAINTS", Const, 0},
+ {"CERT_TRUST_INVALID_EXTENSION", Const, 0},
+ {"CERT_TRUST_INVALID_NAME_CONSTRAINTS", Const, 0},
+ {"CERT_TRUST_INVALID_POLICY_CONSTRAINTS", Const, 0},
+ {"CERT_TRUST_IS_CYCLIC", Const, 0},
+ {"CERT_TRUST_IS_EXPLICIT_DISTRUST", Const, 0},
+ {"CERT_TRUST_IS_NOT_SIGNATURE_VALID", Const, 0},
+ {"CERT_TRUST_IS_NOT_TIME_VALID", Const, 0},
+ {"CERT_TRUST_IS_NOT_VALID_FOR_USAGE", Const, 0},
+ {"CERT_TRUST_IS_OFFLINE_REVOCATION", Const, 0},
+ {"CERT_TRUST_IS_REVOKED", Const, 0},
+ {"CERT_TRUST_IS_UNTRUSTED_ROOT", Const, 0},
+ {"CERT_TRUST_NO_ERROR", Const, 0},
+ {"CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY", Const, 0},
+ {"CERT_TRUST_REVOCATION_STATUS_UNKNOWN", Const, 0},
+ {"CFLUSH", Const, 1},
+ {"CLOCAL", Const, 0},
+ {"CLONE_CHILD_CLEARTID", Const, 2},
+ {"CLONE_CHILD_SETTID", Const, 2},
+ {"CLONE_CLEAR_SIGHAND", Const, 20},
+ {"CLONE_CSIGNAL", Const, 3},
+ {"CLONE_DETACHED", Const, 2},
+ {"CLONE_FILES", Const, 2},
+ {"CLONE_FS", Const, 2},
+ {"CLONE_INTO_CGROUP", Const, 20},
+ {"CLONE_IO", Const, 2},
+ {"CLONE_NEWCGROUP", Const, 20},
+ {"CLONE_NEWIPC", Const, 2},
+ {"CLONE_NEWNET", Const, 2},
+ {"CLONE_NEWNS", Const, 2},
+ {"CLONE_NEWPID", Const, 2},
+ {"CLONE_NEWTIME", Const, 20},
+ {"CLONE_NEWUSER", Const, 2},
+ {"CLONE_NEWUTS", Const, 2},
+ {"CLONE_PARENT", Const, 2},
+ {"CLONE_PARENT_SETTID", Const, 2},
+ {"CLONE_PID", Const, 3},
+ {"CLONE_PIDFD", Const, 20},
+ {"CLONE_PTRACE", Const, 2},
+ {"CLONE_SETTLS", Const, 2},
+ {"CLONE_SIGHAND", Const, 2},
+ {"CLONE_SYSVSEM", Const, 2},
+ {"CLONE_THREAD", Const, 2},
+ {"CLONE_UNTRACED", Const, 2},
+ {"CLONE_VFORK", Const, 2},
+ {"CLONE_VM", Const, 2},
+ {"CPUID_CFLUSH", Const, 1},
+ {"CREAD", Const, 0},
+ {"CREATE_ALWAYS", Const, 0},
+ {"CREATE_NEW", Const, 0},
+ {"CREATE_NEW_PROCESS_GROUP", Const, 1},
+ {"CREATE_UNICODE_ENVIRONMENT", Const, 0},
+ {"CRYPT_DEFAULT_CONTAINER_OPTIONAL", Const, 0},
+ {"CRYPT_DELETEKEYSET", Const, 0},
+ {"CRYPT_MACHINE_KEYSET", Const, 0},
+ {"CRYPT_NEWKEYSET", Const, 0},
+ {"CRYPT_SILENT", Const, 0},
+ {"CRYPT_VERIFYCONTEXT", Const, 0},
+ {"CS5", Const, 0},
+ {"CS6", Const, 0},
+ {"CS7", Const, 0},
+ {"CS8", Const, 0},
+ {"CSIZE", Const, 0},
+ {"CSTART", Const, 1},
+ {"CSTATUS", Const, 1},
+ {"CSTOP", Const, 1},
+ {"CSTOPB", Const, 0},
+ {"CSUSP", Const, 1},
+ {"CTL_MAXNAME", Const, 0},
+ {"CTL_NET", Const, 0},
+ {"CTL_QUERY", Const, 1},
+ {"CTRL_BREAK_EVENT", Const, 1},
+ {"CTRL_CLOSE_EVENT", Const, 14},
+ {"CTRL_C_EVENT", Const, 1},
+ {"CTRL_LOGOFF_EVENT", Const, 14},
+ {"CTRL_SHUTDOWN_EVENT", Const, 14},
+ {"CancelIo", Func, 0},
+ {"CancelIoEx", Func, 1},
+ {"CertAddCertificateContextToStore", Func, 0},
+ {"CertChainContext", Type, 0},
+ {"CertChainContext.ChainCount", Field, 0},
+ {"CertChainContext.Chains", Field, 0},
+ {"CertChainContext.HasRevocationFreshnessTime", Field, 0},
+ {"CertChainContext.LowerQualityChainCount", Field, 0},
+ {"CertChainContext.LowerQualityChains", Field, 0},
+ {"CertChainContext.RevocationFreshnessTime", Field, 0},
+ {"CertChainContext.Size", Field, 0},
+ {"CertChainContext.TrustStatus", Field, 0},
+ {"CertChainElement", Type, 0},
+ {"CertChainElement.ApplicationUsage", Field, 0},
+ {"CertChainElement.CertContext", Field, 0},
+ {"CertChainElement.ExtendedErrorInfo", Field, 0},
+ {"CertChainElement.IssuanceUsage", Field, 0},
+ {"CertChainElement.RevocationInfo", Field, 0},
+ {"CertChainElement.Size", Field, 0},
+ {"CertChainElement.TrustStatus", Field, 0},
+ {"CertChainPara", Type, 0},
+ {"CertChainPara.CacheResync", Field, 0},
+ {"CertChainPara.CheckRevocationFreshnessTime", Field, 0},
+ {"CertChainPara.RequestedUsage", Field, 0},
+ {"CertChainPara.RequstedIssuancePolicy", Field, 0},
+ {"CertChainPara.RevocationFreshnessTime", Field, 0},
+ {"CertChainPara.Size", Field, 0},
+ {"CertChainPara.URLRetrievalTimeout", Field, 0},
+ {"CertChainPolicyPara", Type, 0},
+ {"CertChainPolicyPara.ExtraPolicyPara", Field, 0},
+ {"CertChainPolicyPara.Flags", Field, 0},
+ {"CertChainPolicyPara.Size", Field, 0},
+ {"CertChainPolicyStatus", Type, 0},
+ {"CertChainPolicyStatus.ChainIndex", Field, 0},
+ {"CertChainPolicyStatus.ElementIndex", Field, 0},
+ {"CertChainPolicyStatus.Error", Field, 0},
+ {"CertChainPolicyStatus.ExtraPolicyStatus", Field, 0},
+ {"CertChainPolicyStatus.Size", Field, 0},
+ {"CertCloseStore", Func, 0},
+ {"CertContext", Type, 0},
+ {"CertContext.CertInfo", Field, 0},
+ {"CertContext.EncodedCert", Field, 0},
+ {"CertContext.EncodingType", Field, 0},
+ {"CertContext.Length", Field, 0},
+ {"CertContext.Store", Field, 0},
+ {"CertCreateCertificateContext", Func, 0},
+ {"CertEnhKeyUsage", Type, 0},
+ {"CertEnhKeyUsage.Length", Field, 0},
+ {"CertEnhKeyUsage.UsageIdentifiers", Field, 0},
+ {"CertEnumCertificatesInStore", Func, 0},
+ {"CertFreeCertificateChain", Func, 0},
+ {"CertFreeCertificateContext", Func, 0},
+ {"CertGetCertificateChain", Func, 0},
+ {"CertInfo", Type, 11},
+ {"CertOpenStore", Func, 0},
+ {"CertOpenSystemStore", Func, 0},
+ {"CertRevocationCrlInfo", Type, 11},
+ {"CertRevocationInfo", Type, 0},
+ {"CertRevocationInfo.CrlInfo", Field, 0},
+ {"CertRevocationInfo.FreshnessTime", Field, 0},
+ {"CertRevocationInfo.HasFreshnessTime", Field, 0},
+ {"CertRevocationInfo.OidSpecificInfo", Field, 0},
+ {"CertRevocationInfo.RevocationOid", Field, 0},
+ {"CertRevocationInfo.RevocationResult", Field, 0},
+ {"CertRevocationInfo.Size", Field, 0},
+ {"CertSimpleChain", Type, 0},
+ {"CertSimpleChain.Elements", Field, 0},
+ {"CertSimpleChain.HasRevocationFreshnessTime", Field, 0},
+ {"CertSimpleChain.NumElements", Field, 0},
+ {"CertSimpleChain.RevocationFreshnessTime", Field, 0},
+ {"CertSimpleChain.Size", Field, 0},
+ {"CertSimpleChain.TrustListInfo", Field, 0},
+ {"CertSimpleChain.TrustStatus", Field, 0},
+ {"CertTrustListInfo", Type, 11},
+ {"CertTrustStatus", Type, 0},
+ {"CertTrustStatus.ErrorStatus", Field, 0},
+ {"CertTrustStatus.InfoStatus", Field, 0},
+ {"CertUsageMatch", Type, 0},
+ {"CertUsageMatch.Type", Field, 0},
+ {"CertUsageMatch.Usage", Field, 0},
+ {"CertVerifyCertificateChainPolicy", Func, 0},
+ {"Chdir", Func, 0},
+ {"CheckBpfVersion", Func, 0},
+ {"Chflags", Func, 0},
+ {"Chmod", Func, 0},
+ {"Chown", Func, 0},
+ {"Chroot", Func, 0},
+ {"Clearenv", Func, 0},
+ {"Close", Func, 0},
+ {"CloseHandle", Func, 0},
+ {"CloseOnExec", Func, 0},
+ {"Closesocket", Func, 0},
+ {"CmsgLen", Func, 0},
+ {"CmsgSpace", Func, 0},
+ {"Cmsghdr", Type, 0},
+ {"Cmsghdr.Len", Field, 0},
+ {"Cmsghdr.Level", Field, 0},
+ {"Cmsghdr.Type", Field, 0},
+ {"Cmsghdr.X__cmsg_data", Field, 0},
+ {"CommandLineToArgv", Func, 0},
+ {"ComputerName", Func, 0},
+ {"Conn", Type, 9},
+ {"Connect", Func, 0},
+ {"ConnectEx", Func, 1},
+ {"ConvertSidToStringSid", Func, 0},
+ {"ConvertStringSidToSid", Func, 0},
+ {"CopySid", Func, 0},
+ {"Creat", Func, 0},
+ {"CreateDirectory", Func, 0},
+ {"CreateFile", Func, 0},
+ {"CreateFileMapping", Func, 0},
+ {"CreateHardLink", Func, 4},
+ {"CreateIoCompletionPort", Func, 0},
+ {"CreatePipe", Func, 0},
+ {"CreateProcess", Func, 0},
+ {"CreateProcessAsUser", Func, 10},
+ {"CreateSymbolicLink", Func, 4},
+ {"CreateToolhelp32Snapshot", Func, 4},
+ {"Credential", Type, 0},
+ {"Credential.Gid", Field, 0},
+ {"Credential.Groups", Field, 0},
+ {"Credential.NoSetGroups", Field, 9},
+ {"Credential.Uid", Field, 0},
+ {"CryptAcquireContext", Func, 0},
+ {"CryptGenRandom", Func, 0},
+ {"CryptReleaseContext", Func, 0},
+ {"DIOCBSFLUSH", Const, 1},
+ {"DIOCOSFPFLUSH", Const, 1},
+ {"DLL", Type, 0},
+ {"DLL.Handle", Field, 0},
+ {"DLL.Name", Field, 0},
+ {"DLLError", Type, 0},
+ {"DLLError.Err", Field, 0},
+ {"DLLError.Msg", Field, 0},
+ {"DLLError.ObjName", Field, 0},
+ {"DLT_A429", Const, 0},
+ {"DLT_A653_ICM", Const, 0},
+ {"DLT_AIRONET_HEADER", Const, 0},
+ {"DLT_AOS", Const, 1},
+ {"DLT_APPLE_IP_OVER_IEEE1394", Const, 0},
+ {"DLT_ARCNET", Const, 0},
+ {"DLT_ARCNET_LINUX", Const, 0},
+ {"DLT_ATM_CLIP", Const, 0},
+ {"DLT_ATM_RFC1483", Const, 0},
+ {"DLT_AURORA", Const, 0},
+ {"DLT_AX25", Const, 0},
+ {"DLT_AX25_KISS", Const, 0},
+ {"DLT_BACNET_MS_TP", Const, 0},
+ {"DLT_BLUETOOTH_HCI_H4", Const, 0},
+ {"DLT_BLUETOOTH_HCI_H4_WITH_PHDR", Const, 0},
+ {"DLT_CAN20B", Const, 0},
+ {"DLT_CAN_SOCKETCAN", Const, 1},
+ {"DLT_CHAOS", Const, 0},
+ {"DLT_CHDLC", Const, 0},
+ {"DLT_CISCO_IOS", Const, 0},
+ {"DLT_C_HDLC", Const, 0},
+ {"DLT_C_HDLC_WITH_DIR", Const, 0},
+ {"DLT_DBUS", Const, 1},
+ {"DLT_DECT", Const, 1},
+ {"DLT_DOCSIS", Const, 0},
+ {"DLT_DVB_CI", Const, 1},
+ {"DLT_ECONET", Const, 0},
+ {"DLT_EN10MB", Const, 0},
+ {"DLT_EN3MB", Const, 0},
+ {"DLT_ENC", Const, 0},
+ {"DLT_ERF", Const, 0},
+ {"DLT_ERF_ETH", Const, 0},
+ {"DLT_ERF_POS", Const, 0},
+ {"DLT_FC_2", Const, 1},
+ {"DLT_FC_2_WITH_FRAME_DELIMS", Const, 1},
+ {"DLT_FDDI", Const, 0},
+ {"DLT_FLEXRAY", Const, 0},
+ {"DLT_FRELAY", Const, 0},
+ {"DLT_FRELAY_WITH_DIR", Const, 0},
+ {"DLT_GCOM_SERIAL", Const, 0},
+ {"DLT_GCOM_T1E1", Const, 0},
+ {"DLT_GPF_F", Const, 0},
+ {"DLT_GPF_T", Const, 0},
+ {"DLT_GPRS_LLC", Const, 0},
+ {"DLT_GSMTAP_ABIS", Const, 1},
+ {"DLT_GSMTAP_UM", Const, 1},
+ {"DLT_HDLC", Const, 1},
+ {"DLT_HHDLC", Const, 0},
+ {"DLT_HIPPI", Const, 1},
+ {"DLT_IBM_SN", Const, 0},
+ {"DLT_IBM_SP", Const, 0},
+ {"DLT_IEEE802", Const, 0},
+ {"DLT_IEEE802_11", Const, 0},
+ {"DLT_IEEE802_11_RADIO", Const, 0},
+ {"DLT_IEEE802_11_RADIO_AVS", Const, 0},
+ {"DLT_IEEE802_15_4", Const, 0},
+ {"DLT_IEEE802_15_4_LINUX", Const, 0},
+ {"DLT_IEEE802_15_4_NOFCS", Const, 1},
+ {"DLT_IEEE802_15_4_NONASK_PHY", Const, 0},
+ {"DLT_IEEE802_16_MAC_CPS", Const, 0},
+ {"DLT_IEEE802_16_MAC_CPS_RADIO", Const, 0},
+ {"DLT_IPFILTER", Const, 0},
+ {"DLT_IPMB", Const, 0},
+ {"DLT_IPMB_LINUX", Const, 0},
+ {"DLT_IPNET", Const, 1},
+ {"DLT_IPOIB", Const, 1},
+ {"DLT_IPV4", Const, 1},
+ {"DLT_IPV6", Const, 1},
+ {"DLT_IP_OVER_FC", Const, 0},
+ {"DLT_JUNIPER_ATM1", Const, 0},
+ {"DLT_JUNIPER_ATM2", Const, 0},
+ {"DLT_JUNIPER_ATM_CEMIC", Const, 1},
+ {"DLT_JUNIPER_CHDLC", Const, 0},
+ {"DLT_JUNIPER_ES", Const, 0},
+ {"DLT_JUNIPER_ETHER", Const, 0},
+ {"DLT_JUNIPER_FIBRECHANNEL", Const, 1},
+ {"DLT_JUNIPER_FRELAY", Const, 0},
+ {"DLT_JUNIPER_GGSN", Const, 0},
+ {"DLT_JUNIPER_ISM", Const, 0},
+ {"DLT_JUNIPER_MFR", Const, 0},
+ {"DLT_JUNIPER_MLFR", Const, 0},
+ {"DLT_JUNIPER_MLPPP", Const, 0},
+ {"DLT_JUNIPER_MONITOR", Const, 0},
+ {"DLT_JUNIPER_PIC_PEER", Const, 0},
+ {"DLT_JUNIPER_PPP", Const, 0},
+ {"DLT_JUNIPER_PPPOE", Const, 0},
+ {"DLT_JUNIPER_PPPOE_ATM", Const, 0},
+ {"DLT_JUNIPER_SERVICES", Const, 0},
+ {"DLT_JUNIPER_SRX_E2E", Const, 1},
+ {"DLT_JUNIPER_ST", Const, 0},
+ {"DLT_JUNIPER_VP", Const, 0},
+ {"DLT_JUNIPER_VS", Const, 1},
+ {"DLT_LAPB_WITH_DIR", Const, 0},
+ {"DLT_LAPD", Const, 0},
+ {"DLT_LIN", Const, 0},
+ {"DLT_LINUX_EVDEV", Const, 1},
+ {"DLT_LINUX_IRDA", Const, 0},
+ {"DLT_LINUX_LAPD", Const, 0},
+ {"DLT_LINUX_PPP_WITHDIRECTION", Const, 0},
+ {"DLT_LINUX_SLL", Const, 0},
+ {"DLT_LOOP", Const, 0},
+ {"DLT_LTALK", Const, 0},
+ {"DLT_MATCHING_MAX", Const, 1},
+ {"DLT_MATCHING_MIN", Const, 1},
+ {"DLT_MFR", Const, 0},
+ {"DLT_MOST", Const, 0},
+ {"DLT_MPEG_2_TS", Const, 1},
+ {"DLT_MPLS", Const, 1},
+ {"DLT_MTP2", Const, 0},
+ {"DLT_MTP2_WITH_PHDR", Const, 0},
+ {"DLT_MTP3", Const, 0},
+ {"DLT_MUX27010", Const, 1},
+ {"DLT_NETANALYZER", Const, 1},
+ {"DLT_NETANALYZER_TRANSPARENT", Const, 1},
+ {"DLT_NFC_LLCP", Const, 1},
+ {"DLT_NFLOG", Const, 1},
+ {"DLT_NG40", Const, 1},
+ {"DLT_NULL", Const, 0},
+ {"DLT_PCI_EXP", Const, 0},
+ {"DLT_PFLOG", Const, 0},
+ {"DLT_PFSYNC", Const, 0},
+ {"DLT_PPI", Const, 0},
+ {"DLT_PPP", Const, 0},
+ {"DLT_PPP_BSDOS", Const, 0},
+ {"DLT_PPP_ETHER", Const, 0},
+ {"DLT_PPP_PPPD", Const, 0},
+ {"DLT_PPP_SERIAL", Const, 0},
+ {"DLT_PPP_WITH_DIR", Const, 0},
+ {"DLT_PPP_WITH_DIRECTION", Const, 0},
+ {"DLT_PRISM_HEADER", Const, 0},
+ {"DLT_PRONET", Const, 0},
+ {"DLT_RAIF1", Const, 0},
+ {"DLT_RAW", Const, 0},
+ {"DLT_RAWAF_MASK", Const, 1},
+ {"DLT_RIO", Const, 0},
+ {"DLT_SCCP", Const, 0},
+ {"DLT_SITA", Const, 0},
+ {"DLT_SLIP", Const, 0},
+ {"DLT_SLIP_BSDOS", Const, 0},
+ {"DLT_STANAG_5066_D_PDU", Const, 1},
+ {"DLT_SUNATM", Const, 0},
+ {"DLT_SYMANTEC_FIREWALL", Const, 0},
+ {"DLT_TZSP", Const, 0},
+ {"DLT_USB", Const, 0},
+ {"DLT_USB_LINUX", Const, 0},
+ {"DLT_USB_LINUX_MMAPPED", Const, 1},
+ {"DLT_USER0", Const, 0},
+ {"DLT_USER1", Const, 0},
+ {"DLT_USER10", Const, 0},
+ {"DLT_USER11", Const, 0},
+ {"DLT_USER12", Const, 0},
+ {"DLT_USER13", Const, 0},
+ {"DLT_USER14", Const, 0},
+ {"DLT_USER15", Const, 0},
+ {"DLT_USER2", Const, 0},
+ {"DLT_USER3", Const, 0},
+ {"DLT_USER4", Const, 0},
+ {"DLT_USER5", Const, 0},
+ {"DLT_USER6", Const, 0},
+ {"DLT_USER7", Const, 0},
+ {"DLT_USER8", Const, 0},
+ {"DLT_USER9", Const, 0},
+ {"DLT_WIHART", Const, 1},
+ {"DLT_X2E_SERIAL", Const, 0},
+ {"DLT_X2E_XORAYA", Const, 0},
+ {"DNSMXData", Type, 0},
+ {"DNSMXData.NameExchange", Field, 0},
+ {"DNSMXData.Pad", Field, 0},
+ {"DNSMXData.Preference", Field, 0},
+ {"DNSPTRData", Type, 0},
+ {"DNSPTRData.Host", Field, 0},
+ {"DNSRecord", Type, 0},
+ {"DNSRecord.Data", Field, 0},
+ {"DNSRecord.Dw", Field, 0},
+ {"DNSRecord.Length", Field, 0},
+ {"DNSRecord.Name", Field, 0},
+ {"DNSRecord.Next", Field, 0},
+ {"DNSRecord.Reserved", Field, 0},
+ {"DNSRecord.Ttl", Field, 0},
+ {"DNSRecord.Type", Field, 0},
+ {"DNSSRVData", Type, 0},
+ {"DNSSRVData.Pad", Field, 0},
+ {"DNSSRVData.Port", Field, 0},
+ {"DNSSRVData.Priority", Field, 0},
+ {"DNSSRVData.Target", Field, 0},
+ {"DNSSRVData.Weight", Field, 0},
+ {"DNSTXTData", Type, 0},
+ {"DNSTXTData.StringArray", Field, 0},
+ {"DNSTXTData.StringCount", Field, 0},
+ {"DNS_INFO_NO_RECORDS", Const, 4},
+ {"DNS_TYPE_A", Const, 0},
+ {"DNS_TYPE_A6", Const, 0},
+ {"DNS_TYPE_AAAA", Const, 0},
+ {"DNS_TYPE_ADDRS", Const, 0},
+ {"DNS_TYPE_AFSDB", Const, 0},
+ {"DNS_TYPE_ALL", Const, 0},
+ {"DNS_TYPE_ANY", Const, 0},
+ {"DNS_TYPE_ATMA", Const, 0},
+ {"DNS_TYPE_AXFR", Const, 0},
+ {"DNS_TYPE_CERT", Const, 0},
+ {"DNS_TYPE_CNAME", Const, 0},
+ {"DNS_TYPE_DHCID", Const, 0},
+ {"DNS_TYPE_DNAME", Const, 0},
+ {"DNS_TYPE_DNSKEY", Const, 0},
+ {"DNS_TYPE_DS", Const, 0},
+ {"DNS_TYPE_EID", Const, 0},
+ {"DNS_TYPE_GID", Const, 0},
+ {"DNS_TYPE_GPOS", Const, 0},
+ {"DNS_TYPE_HINFO", Const, 0},
+ {"DNS_TYPE_ISDN", Const, 0},
+ {"DNS_TYPE_IXFR", Const, 0},
+ {"DNS_TYPE_KEY", Const, 0},
+ {"DNS_TYPE_KX", Const, 0},
+ {"DNS_TYPE_LOC", Const, 0},
+ {"DNS_TYPE_MAILA", Const, 0},
+ {"DNS_TYPE_MAILB", Const, 0},
+ {"DNS_TYPE_MB", Const, 0},
+ {"DNS_TYPE_MD", Const, 0},
+ {"DNS_TYPE_MF", Const, 0},
+ {"DNS_TYPE_MG", Const, 0},
+ {"DNS_TYPE_MINFO", Const, 0},
+ {"DNS_TYPE_MR", Const, 0},
+ {"DNS_TYPE_MX", Const, 0},
+ {"DNS_TYPE_NAPTR", Const, 0},
+ {"DNS_TYPE_NBSTAT", Const, 0},
+ {"DNS_TYPE_NIMLOC", Const, 0},
+ {"DNS_TYPE_NS", Const, 0},
+ {"DNS_TYPE_NSAP", Const, 0},
+ {"DNS_TYPE_NSAPPTR", Const, 0},
+ {"DNS_TYPE_NSEC", Const, 0},
+ {"DNS_TYPE_NULL", Const, 0},
+ {"DNS_TYPE_NXT", Const, 0},
+ {"DNS_TYPE_OPT", Const, 0},
+ {"DNS_TYPE_PTR", Const, 0},
+ {"DNS_TYPE_PX", Const, 0},
+ {"DNS_TYPE_RP", Const, 0},
+ {"DNS_TYPE_RRSIG", Const, 0},
+ {"DNS_TYPE_RT", Const, 0},
+ {"DNS_TYPE_SIG", Const, 0},
+ {"DNS_TYPE_SINK", Const, 0},
+ {"DNS_TYPE_SOA", Const, 0},
+ {"DNS_TYPE_SRV", Const, 0},
+ {"DNS_TYPE_TEXT", Const, 0},
+ {"DNS_TYPE_TKEY", Const, 0},
+ {"DNS_TYPE_TSIG", Const, 0},
+ {"DNS_TYPE_UID", Const, 0},
+ {"DNS_TYPE_UINFO", Const, 0},
+ {"DNS_TYPE_UNSPEC", Const, 0},
+ {"DNS_TYPE_WINS", Const, 0},
+ {"DNS_TYPE_WINSR", Const, 0},
+ {"DNS_TYPE_WKS", Const, 0},
+ {"DNS_TYPE_X25", Const, 0},
+ {"DT_BLK", Const, 0},
+ {"DT_CHR", Const, 0},
+ {"DT_DIR", Const, 0},
+ {"DT_FIFO", Const, 0},
+ {"DT_LNK", Const, 0},
+ {"DT_REG", Const, 0},
+ {"DT_SOCK", Const, 0},
+ {"DT_UNKNOWN", Const, 0},
+ {"DT_WHT", Const, 0},
+ {"DUPLICATE_CLOSE_SOURCE", Const, 0},
+ {"DUPLICATE_SAME_ACCESS", Const, 0},
+ {"DeleteFile", Func, 0},
+ {"DetachLsf", Func, 0},
+ {"DeviceIoControl", Func, 4},
+ {"Dirent", Type, 0},
+ {"Dirent.Fileno", Field, 0},
+ {"Dirent.Ino", Field, 0},
+ {"Dirent.Name", Field, 0},
+ {"Dirent.Namlen", Field, 0},
+ {"Dirent.Off", Field, 0},
+ {"Dirent.Pad0", Field, 12},
+ {"Dirent.Pad1", Field, 12},
+ {"Dirent.Pad_cgo_0", Field, 0},
+ {"Dirent.Reclen", Field, 0},
+ {"Dirent.Seekoff", Field, 0},
+ {"Dirent.Type", Field, 0},
+ {"Dirent.X__d_padding", Field, 3},
+ {"DnsNameCompare", Func, 4},
+ {"DnsQuery", Func, 0},
+ {"DnsRecordListFree", Func, 0},
+ {"DnsSectionAdditional", Const, 4},
+ {"DnsSectionAnswer", Const, 4},
+ {"DnsSectionAuthority", Const, 4},
+ {"DnsSectionQuestion", Const, 4},
+ {"Dup", Func, 0},
+ {"Dup2", Func, 0},
+ {"Dup3", Func, 2},
+ {"DuplicateHandle", Func, 0},
+ {"E2BIG", Const, 0},
+ {"EACCES", Const, 0},
+ {"EADDRINUSE", Const, 0},
+ {"EADDRNOTAVAIL", Const, 0},
+ {"EADV", Const, 0},
+ {"EAFNOSUPPORT", Const, 0},
+ {"EAGAIN", Const, 0},
+ {"EALREADY", Const, 0},
+ {"EAUTH", Const, 0},
+ {"EBADARCH", Const, 0},
+ {"EBADE", Const, 0},
+ {"EBADEXEC", Const, 0},
+ {"EBADF", Const, 0},
+ {"EBADFD", Const, 0},
+ {"EBADMACHO", Const, 0},
+ {"EBADMSG", Const, 0},
+ {"EBADR", Const, 0},
+ {"EBADRPC", Const, 0},
+ {"EBADRQC", Const, 0},
+ {"EBADSLT", Const, 0},
+ {"EBFONT", Const, 0},
+ {"EBUSY", Const, 0},
+ {"ECANCELED", Const, 0},
+ {"ECAPMODE", Const, 1},
+ {"ECHILD", Const, 0},
+ {"ECHO", Const, 0},
+ {"ECHOCTL", Const, 0},
+ {"ECHOE", Const, 0},
+ {"ECHOK", Const, 0},
+ {"ECHOKE", Const, 0},
+ {"ECHONL", Const, 0},
+ {"ECHOPRT", Const, 0},
+ {"ECHRNG", Const, 0},
+ {"ECOMM", Const, 0},
+ {"ECONNABORTED", Const, 0},
+ {"ECONNREFUSED", Const, 0},
+ {"ECONNRESET", Const, 0},
+ {"EDEADLK", Const, 0},
+ {"EDEADLOCK", Const, 0},
+ {"EDESTADDRREQ", Const, 0},
+ {"EDEVERR", Const, 0},
+ {"EDOM", Const, 0},
+ {"EDOOFUS", Const, 0},
+ {"EDOTDOT", Const, 0},
+ {"EDQUOT", Const, 0},
+ {"EEXIST", Const, 0},
+ {"EFAULT", Const, 0},
+ {"EFBIG", Const, 0},
+ {"EFER_LMA", Const, 1},
+ {"EFER_LME", Const, 1},
+ {"EFER_NXE", Const, 1},
+ {"EFER_SCE", Const, 1},
+ {"EFTYPE", Const, 0},
+ {"EHOSTDOWN", Const, 0},
+ {"EHOSTUNREACH", Const, 0},
+ {"EHWPOISON", Const, 0},
+ {"EIDRM", Const, 0},
+ {"EILSEQ", Const, 0},
+ {"EINPROGRESS", Const, 0},
+ {"EINTR", Const, 0},
+ {"EINVAL", Const, 0},
+ {"EIO", Const, 0},
+ {"EIPSEC", Const, 1},
+ {"EISCONN", Const, 0},
+ {"EISDIR", Const, 0},
+ {"EISNAM", Const, 0},
+ {"EKEYEXPIRED", Const, 0},
+ {"EKEYREJECTED", Const, 0},
+ {"EKEYREVOKED", Const, 0},
+ {"EL2HLT", Const, 0},
+ {"EL2NSYNC", Const, 0},
+ {"EL3HLT", Const, 0},
+ {"EL3RST", Const, 0},
+ {"ELAST", Const, 0},
+ {"ELF_NGREG", Const, 0},
+ {"ELF_PRARGSZ", Const, 0},
+ {"ELIBACC", Const, 0},
+ {"ELIBBAD", Const, 0},
+ {"ELIBEXEC", Const, 0},
+ {"ELIBMAX", Const, 0},
+ {"ELIBSCN", Const, 0},
+ {"ELNRNG", Const, 0},
+ {"ELOOP", Const, 0},
+ {"EMEDIUMTYPE", Const, 0},
+ {"EMFILE", Const, 0},
+ {"EMLINK", Const, 0},
+ {"EMSGSIZE", Const, 0},
+ {"EMT_TAGOVF", Const, 1},
+ {"EMULTIHOP", Const, 0},
+ {"EMUL_ENABLED", Const, 1},
+ {"EMUL_LINUX", Const, 1},
+ {"EMUL_LINUX32", Const, 1},
+ {"EMUL_MAXID", Const, 1},
+ {"EMUL_NATIVE", Const, 1},
+ {"ENAMETOOLONG", Const, 0},
+ {"ENAVAIL", Const, 0},
+ {"ENDRUNDISC", Const, 1},
+ {"ENEEDAUTH", Const, 0},
+ {"ENETDOWN", Const, 0},
+ {"ENETRESET", Const, 0},
+ {"ENETUNREACH", Const, 0},
+ {"ENFILE", Const, 0},
+ {"ENOANO", Const, 0},
+ {"ENOATTR", Const, 0},
+ {"ENOBUFS", Const, 0},
+ {"ENOCSI", Const, 0},
+ {"ENODATA", Const, 0},
+ {"ENODEV", Const, 0},
+ {"ENOENT", Const, 0},
+ {"ENOEXEC", Const, 0},
+ {"ENOKEY", Const, 0},
+ {"ENOLCK", Const, 0},
+ {"ENOLINK", Const, 0},
+ {"ENOMEDIUM", Const, 0},
+ {"ENOMEM", Const, 0},
+ {"ENOMSG", Const, 0},
+ {"ENONET", Const, 0},
+ {"ENOPKG", Const, 0},
+ {"ENOPOLICY", Const, 0},
+ {"ENOPROTOOPT", Const, 0},
+ {"ENOSPC", Const, 0},
+ {"ENOSR", Const, 0},
+ {"ENOSTR", Const, 0},
+ {"ENOSYS", Const, 0},
+ {"ENOTBLK", Const, 0},
+ {"ENOTCAPABLE", Const, 0},
+ {"ENOTCONN", Const, 0},
+ {"ENOTDIR", Const, 0},
+ {"ENOTEMPTY", Const, 0},
+ {"ENOTNAM", Const, 0},
+ {"ENOTRECOVERABLE", Const, 0},
+ {"ENOTSOCK", Const, 0},
+ {"ENOTSUP", Const, 0},
+ {"ENOTTY", Const, 0},
+ {"ENOTUNIQ", Const, 0},
+ {"ENXIO", Const, 0},
+ {"EN_SW_CTL_INF", Const, 1},
+ {"EN_SW_CTL_PREC", Const, 1},
+ {"EN_SW_CTL_ROUND", Const, 1},
+ {"EN_SW_DATACHAIN", Const, 1},
+ {"EN_SW_DENORM", Const, 1},
+ {"EN_SW_INVOP", Const, 1},
+ {"EN_SW_OVERFLOW", Const, 1},
+ {"EN_SW_PRECLOSS", Const, 1},
+ {"EN_SW_UNDERFLOW", Const, 1},
+ {"EN_SW_ZERODIV", Const, 1},
+ {"EOPNOTSUPP", Const, 0},
+ {"EOVERFLOW", Const, 0},
+ {"EOWNERDEAD", Const, 0},
+ {"EPERM", Const, 0},
+ {"EPFNOSUPPORT", Const, 0},
+ {"EPIPE", Const, 0},
+ {"EPOLLERR", Const, 0},
+ {"EPOLLET", Const, 0},
+ {"EPOLLHUP", Const, 0},
+ {"EPOLLIN", Const, 0},
+ {"EPOLLMSG", Const, 0},
+ {"EPOLLONESHOT", Const, 0},
+ {"EPOLLOUT", Const, 0},
+ {"EPOLLPRI", Const, 0},
+ {"EPOLLRDBAND", Const, 0},
+ {"EPOLLRDHUP", Const, 0},
+ {"EPOLLRDNORM", Const, 0},
+ {"EPOLLWRBAND", Const, 0},
+ {"EPOLLWRNORM", Const, 0},
+ {"EPOLL_CLOEXEC", Const, 0},
+ {"EPOLL_CTL_ADD", Const, 0},
+ {"EPOLL_CTL_DEL", Const, 0},
+ {"EPOLL_CTL_MOD", Const, 0},
+ {"EPOLL_NONBLOCK", Const, 0},
+ {"EPROCLIM", Const, 0},
+ {"EPROCUNAVAIL", Const, 0},
+ {"EPROGMISMATCH", Const, 0},
+ {"EPROGUNAVAIL", Const, 0},
+ {"EPROTO", Const, 0},
+ {"EPROTONOSUPPORT", Const, 0},
+ {"EPROTOTYPE", Const, 0},
+ {"EPWROFF", Const, 0},
+ {"EQFULL", Const, 16},
+ {"ERANGE", Const, 0},
+ {"EREMCHG", Const, 0},
+ {"EREMOTE", Const, 0},
+ {"EREMOTEIO", Const, 0},
+ {"ERESTART", Const, 0},
+ {"ERFKILL", Const, 0},
+ {"EROFS", Const, 0},
+ {"ERPCMISMATCH", Const, 0},
+ {"ERROR_ACCESS_DENIED", Const, 0},
+ {"ERROR_ALREADY_EXISTS", Const, 0},
+ {"ERROR_BROKEN_PIPE", Const, 0},
+ {"ERROR_BUFFER_OVERFLOW", Const, 0},
+ {"ERROR_DIR_NOT_EMPTY", Const, 8},
+ {"ERROR_ENVVAR_NOT_FOUND", Const, 0},
+ {"ERROR_FILE_EXISTS", Const, 0},
+ {"ERROR_FILE_NOT_FOUND", Const, 0},
+ {"ERROR_HANDLE_EOF", Const, 2},
+ {"ERROR_INSUFFICIENT_BUFFER", Const, 0},
+ {"ERROR_IO_PENDING", Const, 0},
+ {"ERROR_MOD_NOT_FOUND", Const, 0},
+ {"ERROR_MORE_DATA", Const, 3},
+ {"ERROR_NETNAME_DELETED", Const, 3},
+ {"ERROR_NOT_FOUND", Const, 1},
+ {"ERROR_NO_MORE_FILES", Const, 0},
+ {"ERROR_OPERATION_ABORTED", Const, 0},
+ {"ERROR_PATH_NOT_FOUND", Const, 0},
+ {"ERROR_PRIVILEGE_NOT_HELD", Const, 4},
+ {"ERROR_PROC_NOT_FOUND", Const, 0},
+ {"ESHLIBVERS", Const, 0},
+ {"ESHUTDOWN", Const, 0},
+ {"ESOCKTNOSUPPORT", Const, 0},
+ {"ESPIPE", Const, 0},
+ {"ESRCH", Const, 0},
+ {"ESRMNT", Const, 0},
+ {"ESTALE", Const, 0},
+ {"ESTRPIPE", Const, 0},
+ {"ETHERCAP_JUMBO_MTU", Const, 1},
+ {"ETHERCAP_VLAN_HWTAGGING", Const, 1},
+ {"ETHERCAP_VLAN_MTU", Const, 1},
+ {"ETHERMIN", Const, 1},
+ {"ETHERMTU", Const, 1},
+ {"ETHERMTU_JUMBO", Const, 1},
+ {"ETHERTYPE_8023", Const, 1},
+ {"ETHERTYPE_AARP", Const, 1},
+ {"ETHERTYPE_ACCTON", Const, 1},
+ {"ETHERTYPE_AEONIC", Const, 1},
+ {"ETHERTYPE_ALPHA", Const, 1},
+ {"ETHERTYPE_AMBER", Const, 1},
+ {"ETHERTYPE_AMOEBA", Const, 1},
+ {"ETHERTYPE_AOE", Const, 1},
+ {"ETHERTYPE_APOLLO", Const, 1},
+ {"ETHERTYPE_APOLLODOMAIN", Const, 1},
+ {"ETHERTYPE_APPLETALK", Const, 1},
+ {"ETHERTYPE_APPLITEK", Const, 1},
+ {"ETHERTYPE_ARGONAUT", Const, 1},
+ {"ETHERTYPE_ARP", Const, 1},
+ {"ETHERTYPE_AT", Const, 1},
+ {"ETHERTYPE_ATALK", Const, 1},
+ {"ETHERTYPE_ATOMIC", Const, 1},
+ {"ETHERTYPE_ATT", Const, 1},
+ {"ETHERTYPE_ATTSTANFORD", Const, 1},
+ {"ETHERTYPE_AUTOPHON", Const, 1},
+ {"ETHERTYPE_AXIS", Const, 1},
+ {"ETHERTYPE_BCLOOP", Const, 1},
+ {"ETHERTYPE_BOFL", Const, 1},
+ {"ETHERTYPE_CABLETRON", Const, 1},
+ {"ETHERTYPE_CHAOS", Const, 1},
+ {"ETHERTYPE_COMDESIGN", Const, 1},
+ {"ETHERTYPE_COMPUGRAPHIC", Const, 1},
+ {"ETHERTYPE_COUNTERPOINT", Const, 1},
+ {"ETHERTYPE_CRONUS", Const, 1},
+ {"ETHERTYPE_CRONUSVLN", Const, 1},
+ {"ETHERTYPE_DCA", Const, 1},
+ {"ETHERTYPE_DDE", Const, 1},
+ {"ETHERTYPE_DEBNI", Const, 1},
+ {"ETHERTYPE_DECAM", Const, 1},
+ {"ETHERTYPE_DECCUST", Const, 1},
+ {"ETHERTYPE_DECDIAG", Const, 1},
+ {"ETHERTYPE_DECDNS", Const, 1},
+ {"ETHERTYPE_DECDTS", Const, 1},
+ {"ETHERTYPE_DECEXPER", Const, 1},
+ {"ETHERTYPE_DECLAST", Const, 1},
+ {"ETHERTYPE_DECLTM", Const, 1},
+ {"ETHERTYPE_DECMUMPS", Const, 1},
+ {"ETHERTYPE_DECNETBIOS", Const, 1},
+ {"ETHERTYPE_DELTACON", Const, 1},
+ {"ETHERTYPE_DIDDLE", Const, 1},
+ {"ETHERTYPE_DLOG1", Const, 1},
+ {"ETHERTYPE_DLOG2", Const, 1},
+ {"ETHERTYPE_DN", Const, 1},
+ {"ETHERTYPE_DOGFIGHT", Const, 1},
+ {"ETHERTYPE_DSMD", Const, 1},
+ {"ETHERTYPE_ECMA", Const, 1},
+ {"ETHERTYPE_ENCRYPT", Const, 1},
+ {"ETHERTYPE_ES", Const, 1},
+ {"ETHERTYPE_EXCELAN", Const, 1},
+ {"ETHERTYPE_EXPERDATA", Const, 1},
+ {"ETHERTYPE_FLIP", Const, 1},
+ {"ETHERTYPE_FLOWCONTROL", Const, 1},
+ {"ETHERTYPE_FRARP", Const, 1},
+ {"ETHERTYPE_GENDYN", Const, 1},
+ {"ETHERTYPE_HAYES", Const, 1},
+ {"ETHERTYPE_HIPPI_FP", Const, 1},
+ {"ETHERTYPE_HITACHI", Const, 1},
+ {"ETHERTYPE_HP", Const, 1},
+ {"ETHERTYPE_IEEEPUP", Const, 1},
+ {"ETHERTYPE_IEEEPUPAT", Const, 1},
+ {"ETHERTYPE_IMLBL", Const, 1},
+ {"ETHERTYPE_IMLBLDIAG", Const, 1},
+ {"ETHERTYPE_IP", Const, 1},
+ {"ETHERTYPE_IPAS", Const, 1},
+ {"ETHERTYPE_IPV6", Const, 1},
+ {"ETHERTYPE_IPX", Const, 1},
+ {"ETHERTYPE_IPXNEW", Const, 1},
+ {"ETHERTYPE_KALPANA", Const, 1},
+ {"ETHERTYPE_LANBRIDGE", Const, 1},
+ {"ETHERTYPE_LANPROBE", Const, 1},
+ {"ETHERTYPE_LAT", Const, 1},
+ {"ETHERTYPE_LBACK", Const, 1},
+ {"ETHERTYPE_LITTLE", Const, 1},
+ {"ETHERTYPE_LLDP", Const, 1},
+ {"ETHERTYPE_LOGICRAFT", Const, 1},
+ {"ETHERTYPE_LOOPBACK", Const, 1},
+ {"ETHERTYPE_MATRA", Const, 1},
+ {"ETHERTYPE_MAX", Const, 1},
+ {"ETHERTYPE_MERIT", Const, 1},
+ {"ETHERTYPE_MICP", Const, 1},
+ {"ETHERTYPE_MOPDL", Const, 1},
+ {"ETHERTYPE_MOPRC", Const, 1},
+ {"ETHERTYPE_MOTOROLA", Const, 1},
+ {"ETHERTYPE_MPLS", Const, 1},
+ {"ETHERTYPE_MPLS_MCAST", Const, 1},
+ {"ETHERTYPE_MUMPS", Const, 1},
+ {"ETHERTYPE_NBPCC", Const, 1},
+ {"ETHERTYPE_NBPCLAIM", Const, 1},
+ {"ETHERTYPE_NBPCLREQ", Const, 1},
+ {"ETHERTYPE_NBPCLRSP", Const, 1},
+ {"ETHERTYPE_NBPCREQ", Const, 1},
+ {"ETHERTYPE_NBPCRSP", Const, 1},
+ {"ETHERTYPE_NBPDG", Const, 1},
+ {"ETHERTYPE_NBPDGB", Const, 1},
+ {"ETHERTYPE_NBPDLTE", Const, 1},
+ {"ETHERTYPE_NBPRAR", Const, 1},
+ {"ETHERTYPE_NBPRAS", Const, 1},
+ {"ETHERTYPE_NBPRST", Const, 1},
+ {"ETHERTYPE_NBPSCD", Const, 1},
+ {"ETHERTYPE_NBPVCD", Const, 1},
+ {"ETHERTYPE_NBS", Const, 1},
+ {"ETHERTYPE_NCD", Const, 1},
+ {"ETHERTYPE_NESTAR", Const, 1},
+ {"ETHERTYPE_NETBEUI", Const, 1},
+ {"ETHERTYPE_NOVELL", Const, 1},
+ {"ETHERTYPE_NS", Const, 1},
+ {"ETHERTYPE_NSAT", Const, 1},
+ {"ETHERTYPE_NSCOMPAT", Const, 1},
+ {"ETHERTYPE_NTRAILER", Const, 1},
+ {"ETHERTYPE_OS9", Const, 1},
+ {"ETHERTYPE_OS9NET", Const, 1},
+ {"ETHERTYPE_PACER", Const, 1},
+ {"ETHERTYPE_PAE", Const, 1},
+ {"ETHERTYPE_PCS", Const, 1},
+ {"ETHERTYPE_PLANNING", Const, 1},
+ {"ETHERTYPE_PPP", Const, 1},
+ {"ETHERTYPE_PPPOE", Const, 1},
+ {"ETHERTYPE_PPPOEDISC", Const, 1},
+ {"ETHERTYPE_PRIMENTS", Const, 1},
+ {"ETHERTYPE_PUP", Const, 1},
+ {"ETHERTYPE_PUPAT", Const, 1},
+ {"ETHERTYPE_QINQ", Const, 1},
+ {"ETHERTYPE_RACAL", Const, 1},
+ {"ETHERTYPE_RATIONAL", Const, 1},
+ {"ETHERTYPE_RAWFR", Const, 1},
+ {"ETHERTYPE_RCL", Const, 1},
+ {"ETHERTYPE_RDP", Const, 1},
+ {"ETHERTYPE_RETIX", Const, 1},
+ {"ETHERTYPE_REVARP", Const, 1},
+ {"ETHERTYPE_SCA", Const, 1},
+ {"ETHERTYPE_SECTRA", Const, 1},
+ {"ETHERTYPE_SECUREDATA", Const, 1},
+ {"ETHERTYPE_SGITW", Const, 1},
+ {"ETHERTYPE_SG_BOUNCE", Const, 1},
+ {"ETHERTYPE_SG_DIAG", Const, 1},
+ {"ETHERTYPE_SG_NETGAMES", Const, 1},
+ {"ETHERTYPE_SG_RESV", Const, 1},
+ {"ETHERTYPE_SIMNET", Const, 1},
+ {"ETHERTYPE_SLOW", Const, 1},
+ {"ETHERTYPE_SLOWPROTOCOLS", Const, 1},
+ {"ETHERTYPE_SNA", Const, 1},
+ {"ETHERTYPE_SNMP", Const, 1},
+ {"ETHERTYPE_SONIX", Const, 1},
+ {"ETHERTYPE_SPIDER", Const, 1},
+ {"ETHERTYPE_SPRITE", Const, 1},
+ {"ETHERTYPE_STP", Const, 1},
+ {"ETHERTYPE_TALARIS", Const, 1},
+ {"ETHERTYPE_TALARISMC", Const, 1},
+ {"ETHERTYPE_TCPCOMP", Const, 1},
+ {"ETHERTYPE_TCPSM", Const, 1},
+ {"ETHERTYPE_TEC", Const, 1},
+ {"ETHERTYPE_TIGAN", Const, 1},
+ {"ETHERTYPE_TRAIL", Const, 1},
+ {"ETHERTYPE_TRANSETHER", Const, 1},
+ {"ETHERTYPE_TYMSHARE", Const, 1},
+ {"ETHERTYPE_UBBST", Const, 1},
+ {"ETHERTYPE_UBDEBUG", Const, 1},
+ {"ETHERTYPE_UBDIAGLOOP", Const, 1},
+ {"ETHERTYPE_UBDL", Const, 1},
+ {"ETHERTYPE_UBNIU", Const, 1},
+ {"ETHERTYPE_UBNMC", Const, 1},
+ {"ETHERTYPE_VALID", Const, 1},
+ {"ETHERTYPE_VARIAN", Const, 1},
+ {"ETHERTYPE_VAXELN", Const, 1},
+ {"ETHERTYPE_VEECO", Const, 1},
+ {"ETHERTYPE_VEXP", Const, 1},
+ {"ETHERTYPE_VGLAB", Const, 1},
+ {"ETHERTYPE_VINES", Const, 1},
+ {"ETHERTYPE_VINESECHO", Const, 1},
+ {"ETHERTYPE_VINESLOOP", Const, 1},
+ {"ETHERTYPE_VITAL", Const, 1},
+ {"ETHERTYPE_VLAN", Const, 1},
+ {"ETHERTYPE_VLTLMAN", Const, 1},
+ {"ETHERTYPE_VPROD", Const, 1},
+ {"ETHERTYPE_VURESERVED", Const, 1},
+ {"ETHERTYPE_WATERLOO", Const, 1},
+ {"ETHERTYPE_WELLFLEET", Const, 1},
+ {"ETHERTYPE_X25", Const, 1},
+ {"ETHERTYPE_X75", Const, 1},
+ {"ETHERTYPE_XNSSM", Const, 1},
+ {"ETHERTYPE_XTP", Const, 1},
+ {"ETHER_ADDR_LEN", Const, 1},
+ {"ETHER_ALIGN", Const, 1},
+ {"ETHER_CRC_LEN", Const, 1},
+ {"ETHER_CRC_POLY_BE", Const, 1},
+ {"ETHER_CRC_POLY_LE", Const, 1},
+ {"ETHER_HDR_LEN", Const, 1},
+ {"ETHER_MAX_DIX_LEN", Const, 1},
+ {"ETHER_MAX_LEN", Const, 1},
+ {"ETHER_MAX_LEN_JUMBO", Const, 1},
+ {"ETHER_MIN_LEN", Const, 1},
+ {"ETHER_PPPOE_ENCAP_LEN", Const, 1},
+ {"ETHER_TYPE_LEN", Const, 1},
+ {"ETHER_VLAN_ENCAP_LEN", Const, 1},
+ {"ETH_P_1588", Const, 0},
+ {"ETH_P_8021Q", Const, 0},
+ {"ETH_P_802_2", Const, 0},
+ {"ETH_P_802_3", Const, 0},
+ {"ETH_P_AARP", Const, 0},
+ {"ETH_P_ALL", Const, 0},
+ {"ETH_P_AOE", Const, 0},
+ {"ETH_P_ARCNET", Const, 0},
+ {"ETH_P_ARP", Const, 0},
+ {"ETH_P_ATALK", Const, 0},
+ {"ETH_P_ATMFATE", Const, 0},
+ {"ETH_P_ATMMPOA", Const, 0},
+ {"ETH_P_AX25", Const, 0},
+ {"ETH_P_BPQ", Const, 0},
+ {"ETH_P_CAIF", Const, 0},
+ {"ETH_P_CAN", Const, 0},
+ {"ETH_P_CONTROL", Const, 0},
+ {"ETH_P_CUST", Const, 0},
+ {"ETH_P_DDCMP", Const, 0},
+ {"ETH_P_DEC", Const, 0},
+ {"ETH_P_DIAG", Const, 0},
+ {"ETH_P_DNA_DL", Const, 0},
+ {"ETH_P_DNA_RC", Const, 0},
+ {"ETH_P_DNA_RT", Const, 0},
+ {"ETH_P_DSA", Const, 0},
+ {"ETH_P_ECONET", Const, 0},
+ {"ETH_P_EDSA", Const, 0},
+ {"ETH_P_FCOE", Const, 0},
+ {"ETH_P_FIP", Const, 0},
+ {"ETH_P_HDLC", Const, 0},
+ {"ETH_P_IEEE802154", Const, 0},
+ {"ETH_P_IEEEPUP", Const, 0},
+ {"ETH_P_IEEEPUPAT", Const, 0},
+ {"ETH_P_IP", Const, 0},
+ {"ETH_P_IPV6", Const, 0},
+ {"ETH_P_IPX", Const, 0},
+ {"ETH_P_IRDA", Const, 0},
+ {"ETH_P_LAT", Const, 0},
+ {"ETH_P_LINK_CTL", Const, 0},
+ {"ETH_P_LOCALTALK", Const, 0},
+ {"ETH_P_LOOP", Const, 0},
+ {"ETH_P_MOBITEX", Const, 0},
+ {"ETH_P_MPLS_MC", Const, 0},
+ {"ETH_P_MPLS_UC", Const, 0},
+ {"ETH_P_PAE", Const, 0},
+ {"ETH_P_PAUSE", Const, 0},
+ {"ETH_P_PHONET", Const, 0},
+ {"ETH_P_PPPTALK", Const, 0},
+ {"ETH_P_PPP_DISC", Const, 0},
+ {"ETH_P_PPP_MP", Const, 0},
+ {"ETH_P_PPP_SES", Const, 0},
+ {"ETH_P_PUP", Const, 0},
+ {"ETH_P_PUPAT", Const, 0},
+ {"ETH_P_RARP", Const, 0},
+ {"ETH_P_SCA", Const, 0},
+ {"ETH_P_SLOW", Const, 0},
+ {"ETH_P_SNAP", Const, 0},
+ {"ETH_P_TEB", Const, 0},
+ {"ETH_P_TIPC", Const, 0},
+ {"ETH_P_TRAILER", Const, 0},
+ {"ETH_P_TR_802_2", Const, 0},
+ {"ETH_P_WAN_PPP", Const, 0},
+ {"ETH_P_WCCP", Const, 0},
+ {"ETH_P_X25", Const, 0},
+ {"ETIME", Const, 0},
+ {"ETIMEDOUT", Const, 0},
+ {"ETOOMANYREFS", Const, 0},
+ {"ETXTBSY", Const, 0},
+ {"EUCLEAN", Const, 0},
+ {"EUNATCH", Const, 0},
+ {"EUSERS", Const, 0},
+ {"EVFILT_AIO", Const, 0},
+ {"EVFILT_FS", Const, 0},
+ {"EVFILT_LIO", Const, 0},
+ {"EVFILT_MACHPORT", Const, 0},
+ {"EVFILT_PROC", Const, 0},
+ {"EVFILT_READ", Const, 0},
+ {"EVFILT_SIGNAL", Const, 0},
+ {"EVFILT_SYSCOUNT", Const, 0},
+ {"EVFILT_THREADMARKER", Const, 0},
+ {"EVFILT_TIMER", Const, 0},
+ {"EVFILT_USER", Const, 0},
+ {"EVFILT_VM", Const, 0},
+ {"EVFILT_VNODE", Const, 0},
+ {"EVFILT_WRITE", Const, 0},
+ {"EV_ADD", Const, 0},
+ {"EV_CLEAR", Const, 0},
+ {"EV_DELETE", Const, 0},
+ {"EV_DISABLE", Const, 0},
+ {"EV_DISPATCH", Const, 0},
+ {"EV_DROP", Const, 3},
+ {"EV_ENABLE", Const, 0},
+ {"EV_EOF", Const, 0},
+ {"EV_ERROR", Const, 0},
+ {"EV_FLAG0", Const, 0},
+ {"EV_FLAG1", Const, 0},
+ {"EV_ONESHOT", Const, 0},
+ {"EV_OOBAND", Const, 0},
+ {"EV_POLL", Const, 0},
+ {"EV_RECEIPT", Const, 0},
+ {"EV_SYSFLAGS", Const, 0},
+ {"EWINDOWS", Const, 0},
+ {"EWOULDBLOCK", Const, 0},
+ {"EXDEV", Const, 0},
+ {"EXFULL", Const, 0},
+ {"EXTA", Const, 0},
+ {"EXTB", Const, 0},
+ {"EXTPROC", Const, 0},
+ {"Environ", Func, 0},
+ {"EpollCreate", Func, 0},
+ {"EpollCreate1", Func, 0},
+ {"EpollCtl", Func, 0},
+ {"EpollEvent", Type, 0},
+ {"EpollEvent.Events", Field, 0},
+ {"EpollEvent.Fd", Field, 0},
+ {"EpollEvent.Pad", Field, 0},
+ {"EpollEvent.PadFd", Field, 0},
+ {"EpollWait", Func, 0},
+ {"Errno", Type, 0},
+ {"EscapeArg", Func, 0},
+ {"Exchangedata", Func, 0},
+ {"Exec", Func, 0},
+ {"Exit", Func, 0},
+ {"ExitProcess", Func, 0},
+ {"FD_CLOEXEC", Const, 0},
+ {"FD_SETSIZE", Const, 0},
+ {"FILE_ACTION_ADDED", Const, 0},
+ {"FILE_ACTION_MODIFIED", Const, 0},
+ {"FILE_ACTION_REMOVED", Const, 0},
+ {"FILE_ACTION_RENAMED_NEW_NAME", Const, 0},
+ {"FILE_ACTION_RENAMED_OLD_NAME", Const, 0},
+ {"FILE_APPEND_DATA", Const, 0},
+ {"FILE_ATTRIBUTE_ARCHIVE", Const, 0},
+ {"FILE_ATTRIBUTE_DIRECTORY", Const, 0},
+ {"FILE_ATTRIBUTE_HIDDEN", Const, 0},
+ {"FILE_ATTRIBUTE_NORMAL", Const, 0},
+ {"FILE_ATTRIBUTE_READONLY", Const, 0},
+ {"FILE_ATTRIBUTE_REPARSE_POINT", Const, 4},
+ {"FILE_ATTRIBUTE_SYSTEM", Const, 0},
+ {"FILE_BEGIN", Const, 0},
+ {"FILE_CURRENT", Const, 0},
+ {"FILE_END", Const, 0},
+ {"FILE_FLAG_BACKUP_SEMANTICS", Const, 0},
+ {"FILE_FLAG_OPEN_REPARSE_POINT", Const, 4},
+ {"FILE_FLAG_OVERLAPPED", Const, 0},
+ {"FILE_LIST_DIRECTORY", Const, 0},
+ {"FILE_MAP_COPY", Const, 0},
+ {"FILE_MAP_EXECUTE", Const, 0},
+ {"FILE_MAP_READ", Const, 0},
+ {"FILE_MAP_WRITE", Const, 0},
+ {"FILE_NOTIFY_CHANGE_ATTRIBUTES", Const, 0},
+ {"FILE_NOTIFY_CHANGE_CREATION", Const, 0},
+ {"FILE_NOTIFY_CHANGE_DIR_NAME", Const, 0},
+ {"FILE_NOTIFY_CHANGE_FILE_NAME", Const, 0},
+ {"FILE_NOTIFY_CHANGE_LAST_ACCESS", Const, 0},
+ {"FILE_NOTIFY_CHANGE_LAST_WRITE", Const, 0},
+ {"FILE_NOTIFY_CHANGE_SIZE", Const, 0},
+ {"FILE_SHARE_DELETE", Const, 0},
+ {"FILE_SHARE_READ", Const, 0},
+ {"FILE_SHARE_WRITE", Const, 0},
+ {"FILE_SKIP_COMPLETION_PORT_ON_SUCCESS", Const, 2},
+ {"FILE_SKIP_SET_EVENT_ON_HANDLE", Const, 2},
+ {"FILE_TYPE_CHAR", Const, 0},
+ {"FILE_TYPE_DISK", Const, 0},
+ {"FILE_TYPE_PIPE", Const, 0},
+ {"FILE_TYPE_REMOTE", Const, 0},
+ {"FILE_TYPE_UNKNOWN", Const, 0},
+ {"FILE_WRITE_ATTRIBUTES", Const, 0},
+ {"FLUSHO", Const, 0},
+ {"FORMAT_MESSAGE_ALLOCATE_BUFFER", Const, 0},
+ {"FORMAT_MESSAGE_ARGUMENT_ARRAY", Const, 0},
+ {"FORMAT_MESSAGE_FROM_HMODULE", Const, 0},
+ {"FORMAT_MESSAGE_FROM_STRING", Const, 0},
+ {"FORMAT_MESSAGE_FROM_SYSTEM", Const, 0},
+ {"FORMAT_MESSAGE_IGNORE_INSERTS", Const, 0},
+ {"FORMAT_MESSAGE_MAX_WIDTH_MASK", Const, 0},
+ {"FSCTL_GET_REPARSE_POINT", Const, 4},
+ {"F_ADDFILESIGS", Const, 0},
+ {"F_ADDSIGS", Const, 0},
+ {"F_ALLOCATEALL", Const, 0},
+ {"F_ALLOCATECONTIG", Const, 0},
+ {"F_CANCEL", Const, 0},
+ {"F_CHKCLEAN", Const, 0},
+ {"F_CLOSEM", Const, 1},
+ {"F_DUP2FD", Const, 0},
+ {"F_DUP2FD_CLOEXEC", Const, 1},
+ {"F_DUPFD", Const, 0},
+ {"F_DUPFD_CLOEXEC", Const, 0},
+ {"F_EXLCK", Const, 0},
+ {"F_FINDSIGS", Const, 16},
+ {"F_FLUSH_DATA", Const, 0},
+ {"F_FREEZE_FS", Const, 0},
+ {"F_FSCTL", Const, 1},
+ {"F_FSDIRMASK", Const, 1},
+ {"F_FSIN", Const, 1},
+ {"F_FSINOUT", Const, 1},
+ {"F_FSOUT", Const, 1},
+ {"F_FSPRIV", Const, 1},
+ {"F_FSVOID", Const, 1},
+ {"F_FULLFSYNC", Const, 0},
+ {"F_GETCODEDIR", Const, 16},
+ {"F_GETFD", Const, 0},
+ {"F_GETFL", Const, 0},
+ {"F_GETLEASE", Const, 0},
+ {"F_GETLK", Const, 0},
+ {"F_GETLK64", Const, 0},
+ {"F_GETLKPID", Const, 0},
+ {"F_GETNOSIGPIPE", Const, 0},
+ {"F_GETOWN", Const, 0},
+ {"F_GETOWN_EX", Const, 0},
+ {"F_GETPATH", Const, 0},
+ {"F_GETPATH_MTMINFO", Const, 0},
+ {"F_GETPIPE_SZ", Const, 0},
+ {"F_GETPROTECTIONCLASS", Const, 0},
+ {"F_GETPROTECTIONLEVEL", Const, 16},
+ {"F_GETSIG", Const, 0},
+ {"F_GLOBAL_NOCACHE", Const, 0},
+ {"F_LOCK", Const, 0},
+ {"F_LOG2PHYS", Const, 0},
+ {"F_LOG2PHYS_EXT", Const, 0},
+ {"F_MARKDEPENDENCY", Const, 0},
+ {"F_MAXFD", Const, 1},
+ {"F_NOCACHE", Const, 0},
+ {"F_NODIRECT", Const, 0},
+ {"F_NOTIFY", Const, 0},
+ {"F_OGETLK", Const, 0},
+ {"F_OK", Const, 0},
+ {"F_OSETLK", Const, 0},
+ {"F_OSETLKW", Const, 0},
+ {"F_PARAM_MASK", Const, 1},
+ {"F_PARAM_MAX", Const, 1},
+ {"F_PATHPKG_CHECK", Const, 0},
+ {"F_PEOFPOSMODE", Const, 0},
+ {"F_PREALLOCATE", Const, 0},
+ {"F_RDADVISE", Const, 0},
+ {"F_RDAHEAD", Const, 0},
+ {"F_RDLCK", Const, 0},
+ {"F_READAHEAD", Const, 0},
+ {"F_READBOOTSTRAP", Const, 0},
+ {"F_SETBACKINGSTORE", Const, 0},
+ {"F_SETFD", Const, 0},
+ {"F_SETFL", Const, 0},
+ {"F_SETLEASE", Const, 0},
+ {"F_SETLK", Const, 0},
+ {"F_SETLK64", Const, 0},
+ {"F_SETLKW", Const, 0},
+ {"F_SETLKW64", Const, 0},
+ {"F_SETLKWTIMEOUT", Const, 16},
+ {"F_SETLK_REMOTE", Const, 0},
+ {"F_SETNOSIGPIPE", Const, 0},
+ {"F_SETOWN", Const, 0},
+ {"F_SETOWN_EX", Const, 0},
+ {"F_SETPIPE_SZ", Const, 0},
+ {"F_SETPROTECTIONCLASS", Const, 0},
+ {"F_SETSIG", Const, 0},
+ {"F_SETSIZE", Const, 0},
+ {"F_SHLCK", Const, 0},
+ {"F_SINGLE_WRITER", Const, 16},
+ {"F_TEST", Const, 0},
+ {"F_THAW_FS", Const, 0},
+ {"F_TLOCK", Const, 0},
+ {"F_TRANSCODEKEY", Const, 16},
+ {"F_ULOCK", Const, 0},
+ {"F_UNLCK", Const, 0},
+ {"F_UNLCKSYS", Const, 0},
+ {"F_VOLPOSMODE", Const, 0},
+ {"F_WRITEBOOTSTRAP", Const, 0},
+ {"F_WRLCK", Const, 0},
+ {"Faccessat", Func, 0},
+ {"Fallocate", Func, 0},
+ {"Fbootstraptransfer_t", Type, 0},
+ {"Fbootstraptransfer_t.Buffer", Field, 0},
+ {"Fbootstraptransfer_t.Length", Field, 0},
+ {"Fbootstraptransfer_t.Offset", Field, 0},
+ {"Fchdir", Func, 0},
+ {"Fchflags", Func, 0},
+ {"Fchmod", Func, 0},
+ {"Fchmodat", Func, 0},
+ {"Fchown", Func, 0},
+ {"Fchownat", Func, 0},
+ {"FcntlFlock", Func, 3},
+ {"FdSet", Type, 0},
+ {"FdSet.Bits", Field, 0},
+ {"FdSet.X__fds_bits", Field, 0},
+ {"Fdatasync", Func, 0},
+ {"FileNotifyInformation", Type, 0},
+ {"FileNotifyInformation.Action", Field, 0},
+ {"FileNotifyInformation.FileName", Field, 0},
+ {"FileNotifyInformation.FileNameLength", Field, 0},
+ {"FileNotifyInformation.NextEntryOffset", Field, 0},
+ {"Filetime", Type, 0},
+ {"Filetime.HighDateTime", Field, 0},
+ {"Filetime.LowDateTime", Field, 0},
+ {"FindClose", Func, 0},
+ {"FindFirstFile", Func, 0},
+ {"FindNextFile", Func, 0},
+ {"Flock", Func, 0},
+ {"Flock_t", Type, 0},
+ {"Flock_t.Len", Field, 0},
+ {"Flock_t.Pad_cgo_0", Field, 0},
+ {"Flock_t.Pad_cgo_1", Field, 3},
+ {"Flock_t.Pid", Field, 0},
+ {"Flock_t.Start", Field, 0},
+ {"Flock_t.Sysid", Field, 0},
+ {"Flock_t.Type", Field, 0},
+ {"Flock_t.Whence", Field, 0},
+ {"FlushBpf", Func, 0},
+ {"FlushFileBuffers", Func, 0},
+ {"FlushViewOfFile", Func, 0},
+ {"ForkExec", Func, 0},
+ {"ForkLock", Var, 0},
+ {"FormatMessage", Func, 0},
+ {"Fpathconf", Func, 0},
+ {"FreeAddrInfoW", Func, 1},
+ {"FreeEnvironmentStrings", Func, 0},
+ {"FreeLibrary", Func, 0},
+ {"Fsid", Type, 0},
+ {"Fsid.Val", Field, 0},
+ {"Fsid.X__fsid_val", Field, 2},
+ {"Fsid.X__val", Field, 0},
+ {"Fstat", Func, 0},
+ {"Fstatat", Func, 12},
+ {"Fstatfs", Func, 0},
+ {"Fstore_t", Type, 0},
+ {"Fstore_t.Bytesalloc", Field, 0},
+ {"Fstore_t.Flags", Field, 0},
+ {"Fstore_t.Length", Field, 0},
+ {"Fstore_t.Offset", Field, 0},
+ {"Fstore_t.Posmode", Field, 0},
+ {"Fsync", Func, 0},
+ {"Ftruncate", Func, 0},
+ {"FullPath", Func, 4},
+ {"Futimes", Func, 0},
+ {"Futimesat", Func, 0},
+ {"GENERIC_ALL", Const, 0},
+ {"GENERIC_EXECUTE", Const, 0},
+ {"GENERIC_READ", Const, 0},
+ {"GENERIC_WRITE", Const, 0},
+ {"GUID", Type, 1},
+ {"GUID.Data1", Field, 1},
+ {"GUID.Data2", Field, 1},
+ {"GUID.Data3", Field, 1},
+ {"GUID.Data4", Field, 1},
+ {"GetAcceptExSockaddrs", Func, 0},
+ {"GetAdaptersInfo", Func, 0},
+ {"GetAddrInfoW", Func, 1},
+ {"GetCommandLine", Func, 0},
+ {"GetComputerName", Func, 0},
+ {"GetConsoleMode", Func, 1},
+ {"GetCurrentDirectory", Func, 0},
+ {"GetCurrentProcess", Func, 0},
+ {"GetEnvironmentStrings", Func, 0},
+ {"GetEnvironmentVariable", Func, 0},
+ {"GetExitCodeProcess", Func, 0},
+ {"GetFileAttributes", Func, 0},
+ {"GetFileAttributesEx", Func, 0},
+ {"GetFileExInfoStandard", Const, 0},
+ {"GetFileExMaxInfoLevel", Const, 0},
+ {"GetFileInformationByHandle", Func, 0},
+ {"GetFileType", Func, 0},
+ {"GetFullPathName", Func, 0},
+ {"GetHostByName", Func, 0},
+ {"GetIfEntry", Func, 0},
+ {"GetLastError", Func, 0},
+ {"GetLengthSid", Func, 0},
+ {"GetLongPathName", Func, 0},
+ {"GetProcAddress", Func, 0},
+ {"GetProcessTimes", Func, 0},
+ {"GetProtoByName", Func, 0},
+ {"GetQueuedCompletionStatus", Func, 0},
+ {"GetServByName", Func, 0},
+ {"GetShortPathName", Func, 0},
+ {"GetStartupInfo", Func, 0},
+ {"GetStdHandle", Func, 0},
+ {"GetSystemTimeAsFileTime", Func, 0},
+ {"GetTempPath", Func, 0},
+ {"GetTimeZoneInformation", Func, 0},
+ {"GetTokenInformation", Func, 0},
+ {"GetUserNameEx", Func, 0},
+ {"GetUserProfileDirectory", Func, 0},
+ {"GetVersion", Func, 0},
+ {"Getcwd", Func, 0},
+ {"Getdents", Func, 0},
+ {"Getdirentries", Func, 0},
+ {"Getdtablesize", Func, 0},
+ {"Getegid", Func, 0},
+ {"Getenv", Func, 0},
+ {"Geteuid", Func, 0},
+ {"Getfsstat", Func, 0},
+ {"Getgid", Func, 0},
+ {"Getgroups", Func, 0},
+ {"Getpagesize", Func, 0},
+ {"Getpeername", Func, 0},
+ {"Getpgid", Func, 0},
+ {"Getpgrp", Func, 0},
+ {"Getpid", Func, 0},
+ {"Getppid", Func, 0},
+ {"Getpriority", Func, 0},
+ {"Getrlimit", Func, 0},
+ {"Getrusage", Func, 0},
+ {"Getsid", Func, 0},
+ {"Getsockname", Func, 0},
+ {"Getsockopt", Func, 1},
+ {"GetsockoptByte", Func, 0},
+ {"GetsockoptICMPv6Filter", Func, 2},
+ {"GetsockoptIPMreq", Func, 0},
+ {"GetsockoptIPMreqn", Func, 0},
+ {"GetsockoptIPv6MTUInfo", Func, 2},
+ {"GetsockoptIPv6Mreq", Func, 0},
+ {"GetsockoptInet4Addr", Func, 0},
+ {"GetsockoptInt", Func, 0},
+ {"GetsockoptUcred", Func, 1},
+ {"Gettid", Func, 0},
+ {"Gettimeofday", Func, 0},
+ {"Getuid", Func, 0},
+ {"Getwd", Func, 0},
+ {"Getxattr", Func, 1},
+ {"HANDLE_FLAG_INHERIT", Const, 0},
+ {"HKEY_CLASSES_ROOT", Const, 0},
+ {"HKEY_CURRENT_CONFIG", Const, 0},
+ {"HKEY_CURRENT_USER", Const, 0},
+ {"HKEY_DYN_DATA", Const, 0},
+ {"HKEY_LOCAL_MACHINE", Const, 0},
+ {"HKEY_PERFORMANCE_DATA", Const, 0},
+ {"HKEY_USERS", Const, 0},
+ {"HUPCL", Const, 0},
+ {"Handle", Type, 0},
+ {"Hostent", Type, 0},
+ {"Hostent.AddrList", Field, 0},
+ {"Hostent.AddrType", Field, 0},
+ {"Hostent.Aliases", Field, 0},
+ {"Hostent.Length", Field, 0},
+ {"Hostent.Name", Field, 0},
+ {"ICANON", Const, 0},
+ {"ICMP6_FILTER", Const, 2},
+ {"ICMPV6_FILTER", Const, 2},
+ {"ICMPv6Filter", Type, 2},
+ {"ICMPv6Filter.Data", Field, 2},
+ {"ICMPv6Filter.Filt", Field, 2},
+ {"ICRNL", Const, 0},
+ {"IEXTEN", Const, 0},
+ {"IFAN_ARRIVAL", Const, 1},
+ {"IFAN_DEPARTURE", Const, 1},
+ {"IFA_ADDRESS", Const, 0},
+ {"IFA_ANYCAST", Const, 0},
+ {"IFA_BROADCAST", Const, 0},
+ {"IFA_CACHEINFO", Const, 0},
+ {"IFA_F_DADFAILED", Const, 0},
+ {"IFA_F_DEPRECATED", Const, 0},
+ {"IFA_F_HOMEADDRESS", Const, 0},
+ {"IFA_F_NODAD", Const, 0},
+ {"IFA_F_OPTIMISTIC", Const, 0},
+ {"IFA_F_PERMANENT", Const, 0},
+ {"IFA_F_SECONDARY", Const, 0},
+ {"IFA_F_TEMPORARY", Const, 0},
+ {"IFA_F_TENTATIVE", Const, 0},
+ {"IFA_LABEL", Const, 0},
+ {"IFA_LOCAL", Const, 0},
+ {"IFA_MAX", Const, 0},
+ {"IFA_MULTICAST", Const, 0},
+ {"IFA_ROUTE", Const, 1},
+ {"IFA_UNSPEC", Const, 0},
+ {"IFF_ALLMULTI", Const, 0},
+ {"IFF_ALTPHYS", Const, 0},
+ {"IFF_AUTOMEDIA", Const, 0},
+ {"IFF_BROADCAST", Const, 0},
+ {"IFF_CANTCHANGE", Const, 0},
+ {"IFF_CANTCONFIG", Const, 1},
+ {"IFF_DEBUG", Const, 0},
+ {"IFF_DRV_OACTIVE", Const, 0},
+ {"IFF_DRV_RUNNING", Const, 0},
+ {"IFF_DYING", Const, 0},
+ {"IFF_DYNAMIC", Const, 0},
+ {"IFF_LINK0", Const, 0},
+ {"IFF_LINK1", Const, 0},
+ {"IFF_LINK2", Const, 0},
+ {"IFF_LOOPBACK", Const, 0},
+ {"IFF_MASTER", Const, 0},
+ {"IFF_MONITOR", Const, 0},
+ {"IFF_MULTICAST", Const, 0},
+ {"IFF_NOARP", Const, 0},
+ {"IFF_NOTRAILERS", Const, 0},
+ {"IFF_NO_PI", Const, 0},
+ {"IFF_OACTIVE", Const, 0},
+ {"IFF_ONE_QUEUE", Const, 0},
+ {"IFF_POINTOPOINT", Const, 0},
+ {"IFF_POINTTOPOINT", Const, 0},
+ {"IFF_PORTSEL", Const, 0},
+ {"IFF_PPROMISC", Const, 0},
+ {"IFF_PROMISC", Const, 0},
+ {"IFF_RENAMING", Const, 0},
+ {"IFF_RUNNING", Const, 0},
+ {"IFF_SIMPLEX", Const, 0},
+ {"IFF_SLAVE", Const, 0},
+ {"IFF_SMART", Const, 0},
+ {"IFF_STATICARP", Const, 0},
+ {"IFF_TAP", Const, 0},
+ {"IFF_TUN", Const, 0},
+ {"IFF_TUN_EXCL", Const, 0},
+ {"IFF_UP", Const, 0},
+ {"IFF_VNET_HDR", Const, 0},
+ {"IFLA_ADDRESS", Const, 0},
+ {"IFLA_BROADCAST", Const, 0},
+ {"IFLA_COST", Const, 0},
+ {"IFLA_IFALIAS", Const, 0},
+ {"IFLA_IFNAME", Const, 0},
+ {"IFLA_LINK", Const, 0},
+ {"IFLA_LINKINFO", Const, 0},
+ {"IFLA_LINKMODE", Const, 0},
+ {"IFLA_MAP", Const, 0},
+ {"IFLA_MASTER", Const, 0},
+ {"IFLA_MAX", Const, 0},
+ {"IFLA_MTU", Const, 0},
+ {"IFLA_NET_NS_PID", Const, 0},
+ {"IFLA_OPERSTATE", Const, 0},
+ {"IFLA_PRIORITY", Const, 0},
+ {"IFLA_PROTINFO", Const, 0},
+ {"IFLA_QDISC", Const, 0},
+ {"IFLA_STATS", Const, 0},
+ {"IFLA_TXQLEN", Const, 0},
+ {"IFLA_UNSPEC", Const, 0},
+ {"IFLA_WEIGHT", Const, 0},
+ {"IFLA_WIRELESS", Const, 0},
+ {"IFNAMSIZ", Const, 0},
+ {"IFT_1822", Const, 0},
+ {"IFT_A12MPPSWITCH", Const, 0},
+ {"IFT_AAL2", Const, 0},
+ {"IFT_AAL5", Const, 0},
+ {"IFT_ADSL", Const, 0},
+ {"IFT_AFLANE8023", Const, 0},
+ {"IFT_AFLANE8025", Const, 0},
+ {"IFT_ARAP", Const, 0},
+ {"IFT_ARCNET", Const, 0},
+ {"IFT_ARCNETPLUS", Const, 0},
+ {"IFT_ASYNC", Const, 0},
+ {"IFT_ATM", Const, 0},
+ {"IFT_ATMDXI", Const, 0},
+ {"IFT_ATMFUNI", Const, 0},
+ {"IFT_ATMIMA", Const, 0},
+ {"IFT_ATMLOGICAL", Const, 0},
+ {"IFT_ATMRADIO", Const, 0},
+ {"IFT_ATMSUBINTERFACE", Const, 0},
+ {"IFT_ATMVCIENDPT", Const, 0},
+ {"IFT_ATMVIRTUAL", Const, 0},
+ {"IFT_BGPPOLICYACCOUNTING", Const, 0},
+ {"IFT_BLUETOOTH", Const, 1},
+ {"IFT_BRIDGE", Const, 0},
+ {"IFT_BSC", Const, 0},
+ {"IFT_CARP", Const, 0},
+ {"IFT_CCTEMUL", Const, 0},
+ {"IFT_CELLULAR", Const, 0},
+ {"IFT_CEPT", Const, 0},
+ {"IFT_CES", Const, 0},
+ {"IFT_CHANNEL", Const, 0},
+ {"IFT_CNR", Const, 0},
+ {"IFT_COFFEE", Const, 0},
+ {"IFT_COMPOSITELINK", Const, 0},
+ {"IFT_DCN", Const, 0},
+ {"IFT_DIGITALPOWERLINE", Const, 0},
+ {"IFT_DIGITALWRAPPEROVERHEADCHANNEL", Const, 0},
+ {"IFT_DLSW", Const, 0},
+ {"IFT_DOCSCABLEDOWNSTREAM", Const, 0},
+ {"IFT_DOCSCABLEMACLAYER", Const, 0},
+ {"IFT_DOCSCABLEUPSTREAM", Const, 0},
+ {"IFT_DOCSCABLEUPSTREAMCHANNEL", Const, 1},
+ {"IFT_DS0", Const, 0},
+ {"IFT_DS0BUNDLE", Const, 0},
+ {"IFT_DS1FDL", Const, 0},
+ {"IFT_DS3", Const, 0},
+ {"IFT_DTM", Const, 0},
+ {"IFT_DUMMY", Const, 1},
+ {"IFT_DVBASILN", Const, 0},
+ {"IFT_DVBASIOUT", Const, 0},
+ {"IFT_DVBRCCDOWNSTREAM", Const, 0},
+ {"IFT_DVBRCCMACLAYER", Const, 0},
+ {"IFT_DVBRCCUPSTREAM", Const, 0},
+ {"IFT_ECONET", Const, 1},
+ {"IFT_ENC", Const, 0},
+ {"IFT_EON", Const, 0},
+ {"IFT_EPLRS", Const, 0},
+ {"IFT_ESCON", Const, 0},
+ {"IFT_ETHER", Const, 0},
+ {"IFT_FAITH", Const, 0},
+ {"IFT_FAST", Const, 0},
+ {"IFT_FASTETHER", Const, 0},
+ {"IFT_FASTETHERFX", Const, 0},
+ {"IFT_FDDI", Const, 0},
+ {"IFT_FIBRECHANNEL", Const, 0},
+ {"IFT_FRAMERELAYINTERCONNECT", Const, 0},
+ {"IFT_FRAMERELAYMPI", Const, 0},
+ {"IFT_FRDLCIENDPT", Const, 0},
+ {"IFT_FRELAY", Const, 0},
+ {"IFT_FRELAYDCE", Const, 0},
+ {"IFT_FRF16MFRBUNDLE", Const, 0},
+ {"IFT_FRFORWARD", Const, 0},
+ {"IFT_G703AT2MB", Const, 0},
+ {"IFT_G703AT64K", Const, 0},
+ {"IFT_GIF", Const, 0},
+ {"IFT_GIGABITETHERNET", Const, 0},
+ {"IFT_GR303IDT", Const, 0},
+ {"IFT_GR303RDT", Const, 0},
+ {"IFT_H323GATEKEEPER", Const, 0},
+ {"IFT_H323PROXY", Const, 0},
+ {"IFT_HDH1822", Const, 0},
+ {"IFT_HDLC", Const, 0},
+ {"IFT_HDSL2", Const, 0},
+ {"IFT_HIPERLAN2", Const, 0},
+ {"IFT_HIPPI", Const, 0},
+ {"IFT_HIPPIINTERFACE", Const, 0},
+ {"IFT_HOSTPAD", Const, 0},
+ {"IFT_HSSI", Const, 0},
+ {"IFT_HY", Const, 0},
+ {"IFT_IBM370PARCHAN", Const, 0},
+ {"IFT_IDSL", Const, 0},
+ {"IFT_IEEE1394", Const, 0},
+ {"IFT_IEEE80211", Const, 0},
+ {"IFT_IEEE80212", Const, 0},
+ {"IFT_IEEE8023ADLAG", Const, 0},
+ {"IFT_IFGSN", Const, 0},
+ {"IFT_IMT", Const, 0},
+ {"IFT_INFINIBAND", Const, 1},
+ {"IFT_INTERLEAVE", Const, 0},
+ {"IFT_IP", Const, 0},
+ {"IFT_IPFORWARD", Const, 0},
+ {"IFT_IPOVERATM", Const, 0},
+ {"IFT_IPOVERCDLC", Const, 0},
+ {"IFT_IPOVERCLAW", Const, 0},
+ {"IFT_IPSWITCH", Const, 0},
+ {"IFT_IPXIP", Const, 0},
+ {"IFT_ISDN", Const, 0},
+ {"IFT_ISDNBASIC", Const, 0},
+ {"IFT_ISDNPRIMARY", Const, 0},
+ {"IFT_ISDNS", Const, 0},
+ {"IFT_ISDNU", Const, 0},
+ {"IFT_ISO88022LLC", Const, 0},
+ {"IFT_ISO88023", Const, 0},
+ {"IFT_ISO88024", Const, 0},
+ {"IFT_ISO88025", Const, 0},
+ {"IFT_ISO88025CRFPINT", Const, 0},
+ {"IFT_ISO88025DTR", Const, 0},
+ {"IFT_ISO88025FIBER", Const, 0},
+ {"IFT_ISO88026", Const, 0},
+ {"IFT_ISUP", Const, 0},
+ {"IFT_L2VLAN", Const, 0},
+ {"IFT_L3IPVLAN", Const, 0},
+ {"IFT_L3IPXVLAN", Const, 0},
+ {"IFT_LAPB", Const, 0},
+ {"IFT_LAPD", Const, 0},
+ {"IFT_LAPF", Const, 0},
+ {"IFT_LINEGROUP", Const, 1},
+ {"IFT_LOCALTALK", Const, 0},
+ {"IFT_LOOP", Const, 0},
+ {"IFT_MEDIAMAILOVERIP", Const, 0},
+ {"IFT_MFSIGLINK", Const, 0},
+ {"IFT_MIOX25", Const, 0},
+ {"IFT_MODEM", Const, 0},
+ {"IFT_MPC", Const, 0},
+ {"IFT_MPLS", Const, 0},
+ {"IFT_MPLSTUNNEL", Const, 0},
+ {"IFT_MSDSL", Const, 0},
+ {"IFT_MVL", Const, 0},
+ {"IFT_MYRINET", Const, 0},
+ {"IFT_NFAS", Const, 0},
+ {"IFT_NSIP", Const, 0},
+ {"IFT_OPTICALCHANNEL", Const, 0},
+ {"IFT_OPTICALTRANSPORT", Const, 0},
+ {"IFT_OTHER", Const, 0},
+ {"IFT_P10", Const, 0},
+ {"IFT_P80", Const, 0},
+ {"IFT_PARA", Const, 0},
+ {"IFT_PDP", Const, 0},
+ {"IFT_PFLOG", Const, 0},
+ {"IFT_PFLOW", Const, 1},
+ {"IFT_PFSYNC", Const, 0},
+ {"IFT_PLC", Const, 0},
+ {"IFT_PON155", Const, 1},
+ {"IFT_PON622", Const, 1},
+ {"IFT_POS", Const, 0},
+ {"IFT_PPP", Const, 0},
+ {"IFT_PPPMULTILINKBUNDLE", Const, 0},
+ {"IFT_PROPATM", Const, 1},
+ {"IFT_PROPBWAP2MP", Const, 0},
+ {"IFT_PROPCNLS", Const, 0},
+ {"IFT_PROPDOCSWIRELESSDOWNSTREAM", Const, 0},
+ {"IFT_PROPDOCSWIRELESSMACLAYER", Const, 0},
+ {"IFT_PROPDOCSWIRELESSUPSTREAM", Const, 0},
+ {"IFT_PROPMUX", Const, 0},
+ {"IFT_PROPVIRTUAL", Const, 0},
+ {"IFT_PROPWIRELESSP2P", Const, 0},
+ {"IFT_PTPSERIAL", Const, 0},
+ {"IFT_PVC", Const, 0},
+ {"IFT_Q2931", Const, 1},
+ {"IFT_QLLC", Const, 0},
+ {"IFT_RADIOMAC", Const, 0},
+ {"IFT_RADSL", Const, 0},
+ {"IFT_REACHDSL", Const, 0},
+ {"IFT_RFC1483", Const, 0},
+ {"IFT_RS232", Const, 0},
+ {"IFT_RSRB", Const, 0},
+ {"IFT_SDLC", Const, 0},
+ {"IFT_SDSL", Const, 0},
+ {"IFT_SHDSL", Const, 0},
+ {"IFT_SIP", Const, 0},
+ {"IFT_SIPSIG", Const, 1},
+ {"IFT_SIPTG", Const, 1},
+ {"IFT_SLIP", Const, 0},
+ {"IFT_SMDSDXI", Const, 0},
+ {"IFT_SMDSICIP", Const, 0},
+ {"IFT_SONET", Const, 0},
+ {"IFT_SONETOVERHEADCHANNEL", Const, 0},
+ {"IFT_SONETPATH", Const, 0},
+ {"IFT_SONETVT", Const, 0},
+ {"IFT_SRP", Const, 0},
+ {"IFT_SS7SIGLINK", Const, 0},
+ {"IFT_STACKTOSTACK", Const, 0},
+ {"IFT_STARLAN", Const, 0},
+ {"IFT_STF", Const, 0},
+ {"IFT_T1", Const, 0},
+ {"IFT_TDLC", Const, 0},
+ {"IFT_TELINK", Const, 1},
+ {"IFT_TERMPAD", Const, 0},
+ {"IFT_TR008", Const, 0},
+ {"IFT_TRANSPHDLC", Const, 0},
+ {"IFT_TUNNEL", Const, 0},
+ {"IFT_ULTRA", Const, 0},
+ {"IFT_USB", Const, 0},
+ {"IFT_V11", Const, 0},
+ {"IFT_V35", Const, 0},
+ {"IFT_V36", Const, 0},
+ {"IFT_V37", Const, 0},
+ {"IFT_VDSL", Const, 0},
+ {"IFT_VIRTUALIPADDRESS", Const, 0},
+ {"IFT_VIRTUALTG", Const, 1},
+ {"IFT_VOICEDID", Const, 1},
+ {"IFT_VOICEEM", Const, 0},
+ {"IFT_VOICEEMFGD", Const, 1},
+ {"IFT_VOICEENCAP", Const, 0},
+ {"IFT_VOICEFGDEANA", Const, 1},
+ {"IFT_VOICEFXO", Const, 0},
+ {"IFT_VOICEFXS", Const, 0},
+ {"IFT_VOICEOVERATM", Const, 0},
+ {"IFT_VOICEOVERCABLE", Const, 1},
+ {"IFT_VOICEOVERFRAMERELAY", Const, 0},
+ {"IFT_VOICEOVERIP", Const, 0},
+ {"IFT_X213", Const, 0},
+ {"IFT_X25", Const, 0},
+ {"IFT_X25DDN", Const, 0},
+ {"IFT_X25HUNTGROUP", Const, 0},
+ {"IFT_X25MLP", Const, 0},
+ {"IFT_X25PLE", Const, 0},
+ {"IFT_XETHER", Const, 0},
+ {"IGNBRK", Const, 0},
+ {"IGNCR", Const, 0},
+ {"IGNORE", Const, 0},
+ {"IGNPAR", Const, 0},
+ {"IMAXBEL", Const, 0},
+ {"INFINITE", Const, 0},
+ {"INLCR", Const, 0},
+ {"INPCK", Const, 0},
+ {"INVALID_FILE_ATTRIBUTES", Const, 0},
+ {"IN_ACCESS", Const, 0},
+ {"IN_ALL_EVENTS", Const, 0},
+ {"IN_ATTRIB", Const, 0},
+ {"IN_CLASSA_HOST", Const, 0},
+ {"IN_CLASSA_MAX", Const, 0},
+ {"IN_CLASSA_NET", Const, 0},
+ {"IN_CLASSA_NSHIFT", Const, 0},
+ {"IN_CLASSB_HOST", Const, 0},
+ {"IN_CLASSB_MAX", Const, 0},
+ {"IN_CLASSB_NET", Const, 0},
+ {"IN_CLASSB_NSHIFT", Const, 0},
+ {"IN_CLASSC_HOST", Const, 0},
+ {"IN_CLASSC_NET", Const, 0},
+ {"IN_CLASSC_NSHIFT", Const, 0},
+ {"IN_CLASSD_HOST", Const, 0},
+ {"IN_CLASSD_NET", Const, 0},
+ {"IN_CLASSD_NSHIFT", Const, 0},
+ {"IN_CLOEXEC", Const, 0},
+ {"IN_CLOSE", Const, 0},
+ {"IN_CLOSE_NOWRITE", Const, 0},
+ {"IN_CLOSE_WRITE", Const, 0},
+ {"IN_CREATE", Const, 0},
+ {"IN_DELETE", Const, 0},
+ {"IN_DELETE_SELF", Const, 0},
+ {"IN_DONT_FOLLOW", Const, 0},
+ {"IN_EXCL_UNLINK", Const, 0},
+ {"IN_IGNORED", Const, 0},
+ {"IN_ISDIR", Const, 0},
+ {"IN_LINKLOCALNETNUM", Const, 0},
+ {"IN_LOOPBACKNET", Const, 0},
+ {"IN_MASK_ADD", Const, 0},
+ {"IN_MODIFY", Const, 0},
+ {"IN_MOVE", Const, 0},
+ {"IN_MOVED_FROM", Const, 0},
+ {"IN_MOVED_TO", Const, 0},
+ {"IN_MOVE_SELF", Const, 0},
+ {"IN_NONBLOCK", Const, 0},
+ {"IN_ONESHOT", Const, 0},
+ {"IN_ONLYDIR", Const, 0},
+ {"IN_OPEN", Const, 0},
+ {"IN_Q_OVERFLOW", Const, 0},
+ {"IN_RFC3021_HOST", Const, 1},
+ {"IN_RFC3021_MASK", Const, 1},
+ {"IN_RFC3021_NET", Const, 1},
+ {"IN_RFC3021_NSHIFT", Const, 1},
+ {"IN_UNMOUNT", Const, 0},
+ {"IOC_IN", Const, 1},
+ {"IOC_INOUT", Const, 1},
+ {"IOC_OUT", Const, 1},
+ {"IOC_VENDOR", Const, 3},
+ {"IOC_WS2", Const, 1},
+ {"IO_REPARSE_TAG_SYMLINK", Const, 4},
+ {"IPMreq", Type, 0},
+ {"IPMreq.Interface", Field, 0},
+ {"IPMreq.Multiaddr", Field, 0},
+ {"IPMreqn", Type, 0},
+ {"IPMreqn.Address", Field, 0},
+ {"IPMreqn.Ifindex", Field, 0},
+ {"IPMreqn.Multiaddr", Field, 0},
+ {"IPPROTO_3PC", Const, 0},
+ {"IPPROTO_ADFS", Const, 0},
+ {"IPPROTO_AH", Const, 0},
+ {"IPPROTO_AHIP", Const, 0},
+ {"IPPROTO_APES", Const, 0},
+ {"IPPROTO_ARGUS", Const, 0},
+ {"IPPROTO_AX25", Const, 0},
+ {"IPPROTO_BHA", Const, 0},
+ {"IPPROTO_BLT", Const, 0},
+ {"IPPROTO_BRSATMON", Const, 0},
+ {"IPPROTO_CARP", Const, 0},
+ {"IPPROTO_CFTP", Const, 0},
+ {"IPPROTO_CHAOS", Const, 0},
+ {"IPPROTO_CMTP", Const, 0},
+ {"IPPROTO_COMP", Const, 0},
+ {"IPPROTO_CPHB", Const, 0},
+ {"IPPROTO_CPNX", Const, 0},
+ {"IPPROTO_DCCP", Const, 0},
+ {"IPPROTO_DDP", Const, 0},
+ {"IPPROTO_DGP", Const, 0},
+ {"IPPROTO_DIVERT", Const, 0},
+ {"IPPROTO_DIVERT_INIT", Const, 3},
+ {"IPPROTO_DIVERT_RESP", Const, 3},
+ {"IPPROTO_DONE", Const, 0},
+ {"IPPROTO_DSTOPTS", Const, 0},
+ {"IPPROTO_EGP", Const, 0},
+ {"IPPROTO_EMCON", Const, 0},
+ {"IPPROTO_ENCAP", Const, 0},
+ {"IPPROTO_EON", Const, 0},
+ {"IPPROTO_ESP", Const, 0},
+ {"IPPROTO_ETHERIP", Const, 0},
+ {"IPPROTO_FRAGMENT", Const, 0},
+ {"IPPROTO_GGP", Const, 0},
+ {"IPPROTO_GMTP", Const, 0},
+ {"IPPROTO_GRE", Const, 0},
+ {"IPPROTO_HELLO", Const, 0},
+ {"IPPROTO_HMP", Const, 0},
+ {"IPPROTO_HOPOPTS", Const, 0},
+ {"IPPROTO_ICMP", Const, 0},
+ {"IPPROTO_ICMPV6", Const, 0},
+ {"IPPROTO_IDP", Const, 0},
+ {"IPPROTO_IDPR", Const, 0},
+ {"IPPROTO_IDRP", Const, 0},
+ {"IPPROTO_IGMP", Const, 0},
+ {"IPPROTO_IGP", Const, 0},
+ {"IPPROTO_IGRP", Const, 0},
+ {"IPPROTO_IL", Const, 0},
+ {"IPPROTO_INLSP", Const, 0},
+ {"IPPROTO_INP", Const, 0},
+ {"IPPROTO_IP", Const, 0},
+ {"IPPROTO_IPCOMP", Const, 0},
+ {"IPPROTO_IPCV", Const, 0},
+ {"IPPROTO_IPEIP", Const, 0},
+ {"IPPROTO_IPIP", Const, 0},
+ {"IPPROTO_IPPC", Const, 0},
+ {"IPPROTO_IPV4", Const, 0},
+ {"IPPROTO_IPV6", Const, 0},
+ {"IPPROTO_IPV6_ICMP", Const, 1},
+ {"IPPROTO_IRTP", Const, 0},
+ {"IPPROTO_KRYPTOLAN", Const, 0},
+ {"IPPROTO_LARP", Const, 0},
+ {"IPPROTO_LEAF1", Const, 0},
+ {"IPPROTO_LEAF2", Const, 0},
+ {"IPPROTO_MAX", Const, 0},
+ {"IPPROTO_MAXID", Const, 0},
+ {"IPPROTO_MEAS", Const, 0},
+ {"IPPROTO_MH", Const, 1},
+ {"IPPROTO_MHRP", Const, 0},
+ {"IPPROTO_MICP", Const, 0},
+ {"IPPROTO_MOBILE", Const, 0},
+ {"IPPROTO_MPLS", Const, 1},
+ {"IPPROTO_MTP", Const, 0},
+ {"IPPROTO_MUX", Const, 0},
+ {"IPPROTO_ND", Const, 0},
+ {"IPPROTO_NHRP", Const, 0},
+ {"IPPROTO_NONE", Const, 0},
+ {"IPPROTO_NSP", Const, 0},
+ {"IPPROTO_NVPII", Const, 0},
+ {"IPPROTO_OLD_DIVERT", Const, 0},
+ {"IPPROTO_OSPFIGP", Const, 0},
+ {"IPPROTO_PFSYNC", Const, 0},
+ {"IPPROTO_PGM", Const, 0},
+ {"IPPROTO_PIGP", Const, 0},
+ {"IPPROTO_PIM", Const, 0},
+ {"IPPROTO_PRM", Const, 0},
+ {"IPPROTO_PUP", Const, 0},
+ {"IPPROTO_PVP", Const, 0},
+ {"IPPROTO_RAW", Const, 0},
+ {"IPPROTO_RCCMON", Const, 0},
+ {"IPPROTO_RDP", Const, 0},
+ {"IPPROTO_ROUTING", Const, 0},
+ {"IPPROTO_RSVP", Const, 0},
+ {"IPPROTO_RVD", Const, 0},
+ {"IPPROTO_SATEXPAK", Const, 0},
+ {"IPPROTO_SATMON", Const, 0},
+ {"IPPROTO_SCCSP", Const, 0},
+ {"IPPROTO_SCTP", Const, 0},
+ {"IPPROTO_SDRP", Const, 0},
+ {"IPPROTO_SEND", Const, 1},
+ {"IPPROTO_SEP", Const, 0},
+ {"IPPROTO_SKIP", Const, 0},
+ {"IPPROTO_SPACER", Const, 0},
+ {"IPPROTO_SRPC", Const, 0},
+ {"IPPROTO_ST", Const, 0},
+ {"IPPROTO_SVMTP", Const, 0},
+ {"IPPROTO_SWIPE", Const, 0},
+ {"IPPROTO_TCF", Const, 0},
+ {"IPPROTO_TCP", Const, 0},
+ {"IPPROTO_TLSP", Const, 0},
+ {"IPPROTO_TP", Const, 0},
+ {"IPPROTO_TPXX", Const, 0},
+ {"IPPROTO_TRUNK1", Const, 0},
+ {"IPPROTO_TRUNK2", Const, 0},
+ {"IPPROTO_TTP", Const, 0},
+ {"IPPROTO_UDP", Const, 0},
+ {"IPPROTO_UDPLITE", Const, 0},
+ {"IPPROTO_VINES", Const, 0},
+ {"IPPROTO_VISA", Const, 0},
+ {"IPPROTO_VMTP", Const, 0},
+ {"IPPROTO_VRRP", Const, 1},
+ {"IPPROTO_WBEXPAK", Const, 0},
+ {"IPPROTO_WBMON", Const, 0},
+ {"IPPROTO_WSN", Const, 0},
+ {"IPPROTO_XNET", Const, 0},
+ {"IPPROTO_XTP", Const, 0},
+ {"IPV6_2292DSTOPTS", Const, 0},
+ {"IPV6_2292HOPLIMIT", Const, 0},
+ {"IPV6_2292HOPOPTS", Const, 0},
+ {"IPV6_2292NEXTHOP", Const, 0},
+ {"IPV6_2292PKTINFO", Const, 0},
+ {"IPV6_2292PKTOPTIONS", Const, 0},
+ {"IPV6_2292RTHDR", Const, 0},
+ {"IPV6_ADDRFORM", Const, 0},
+ {"IPV6_ADD_MEMBERSHIP", Const, 0},
+ {"IPV6_AUTHHDR", Const, 0},
+ {"IPV6_AUTH_LEVEL", Const, 1},
+ {"IPV6_AUTOFLOWLABEL", Const, 0},
+ {"IPV6_BINDANY", Const, 0},
+ {"IPV6_BINDV6ONLY", Const, 0},
+ {"IPV6_BOUND_IF", Const, 0},
+ {"IPV6_CHECKSUM", Const, 0},
+ {"IPV6_DEFAULT_MULTICAST_HOPS", Const, 0},
+ {"IPV6_DEFAULT_MULTICAST_LOOP", Const, 0},
+ {"IPV6_DEFHLIM", Const, 0},
+ {"IPV6_DONTFRAG", Const, 0},
+ {"IPV6_DROP_MEMBERSHIP", Const, 0},
+ {"IPV6_DSTOPTS", Const, 0},
+ {"IPV6_ESP_NETWORK_LEVEL", Const, 1},
+ {"IPV6_ESP_TRANS_LEVEL", Const, 1},
+ {"IPV6_FAITH", Const, 0},
+ {"IPV6_FLOWINFO_MASK", Const, 0},
+ {"IPV6_FLOWLABEL_MASK", Const, 0},
+ {"IPV6_FRAGTTL", Const, 0},
+ {"IPV6_FW_ADD", Const, 0},
+ {"IPV6_FW_DEL", Const, 0},
+ {"IPV6_FW_FLUSH", Const, 0},
+ {"IPV6_FW_GET", Const, 0},
+ {"IPV6_FW_ZERO", Const, 0},
+ {"IPV6_HLIMDEC", Const, 0},
+ {"IPV6_HOPLIMIT", Const, 0},
+ {"IPV6_HOPOPTS", Const, 0},
+ {"IPV6_IPCOMP_LEVEL", Const, 1},
+ {"IPV6_IPSEC_POLICY", Const, 0},
+ {"IPV6_JOIN_ANYCAST", Const, 0},
+ {"IPV6_JOIN_GROUP", Const, 0},
+ {"IPV6_LEAVE_ANYCAST", Const, 0},
+ {"IPV6_LEAVE_GROUP", Const, 0},
+ {"IPV6_MAXHLIM", Const, 0},
+ {"IPV6_MAXOPTHDR", Const, 0},
+ {"IPV6_MAXPACKET", Const, 0},
+ {"IPV6_MAX_GROUP_SRC_FILTER", Const, 0},
+ {"IPV6_MAX_MEMBERSHIPS", Const, 0},
+ {"IPV6_MAX_SOCK_SRC_FILTER", Const, 0},
+ {"IPV6_MIN_MEMBERSHIPS", Const, 0},
+ {"IPV6_MMTU", Const, 0},
+ {"IPV6_MSFILTER", Const, 0},
+ {"IPV6_MTU", Const, 0},
+ {"IPV6_MTU_DISCOVER", Const, 0},
+ {"IPV6_MULTICAST_HOPS", Const, 0},
+ {"IPV6_MULTICAST_IF", Const, 0},
+ {"IPV6_MULTICAST_LOOP", Const, 0},
+ {"IPV6_NEXTHOP", Const, 0},
+ {"IPV6_OPTIONS", Const, 1},
+ {"IPV6_PATHMTU", Const, 0},
+ {"IPV6_PIPEX", Const, 1},
+ {"IPV6_PKTINFO", Const, 0},
+ {"IPV6_PMTUDISC_DO", Const, 0},
+ {"IPV6_PMTUDISC_DONT", Const, 0},
+ {"IPV6_PMTUDISC_PROBE", Const, 0},
+ {"IPV6_PMTUDISC_WANT", Const, 0},
+ {"IPV6_PORTRANGE", Const, 0},
+ {"IPV6_PORTRANGE_DEFAULT", Const, 0},
+ {"IPV6_PORTRANGE_HIGH", Const, 0},
+ {"IPV6_PORTRANGE_LOW", Const, 0},
+ {"IPV6_PREFER_TEMPADDR", Const, 0},
+ {"IPV6_RECVDSTOPTS", Const, 0},
+ {"IPV6_RECVDSTPORT", Const, 3},
+ {"IPV6_RECVERR", Const, 0},
+ {"IPV6_RECVHOPLIMIT", Const, 0},
+ {"IPV6_RECVHOPOPTS", Const, 0},
+ {"IPV6_RECVPATHMTU", Const, 0},
+ {"IPV6_RECVPKTINFO", Const, 0},
+ {"IPV6_RECVRTHDR", Const, 0},
+ {"IPV6_RECVTCLASS", Const, 0},
+ {"IPV6_ROUTER_ALERT", Const, 0},
+ {"IPV6_RTABLE", Const, 1},
+ {"IPV6_RTHDR", Const, 0},
+ {"IPV6_RTHDRDSTOPTS", Const, 0},
+ {"IPV6_RTHDR_LOOSE", Const, 0},
+ {"IPV6_RTHDR_STRICT", Const, 0},
+ {"IPV6_RTHDR_TYPE_0", Const, 0},
+ {"IPV6_RXDSTOPTS", Const, 0},
+ {"IPV6_RXHOPOPTS", Const, 0},
+ {"IPV6_SOCKOPT_RESERVED1", Const, 0},
+ {"IPV6_TCLASS", Const, 0},
+ {"IPV6_UNICAST_HOPS", Const, 0},
+ {"IPV6_USE_MIN_MTU", Const, 0},
+ {"IPV6_V6ONLY", Const, 0},
+ {"IPV6_VERSION", Const, 0},
+ {"IPV6_VERSION_MASK", Const, 0},
+ {"IPV6_XFRM_POLICY", Const, 0},
+ {"IP_ADD_MEMBERSHIP", Const, 0},
+ {"IP_ADD_SOURCE_MEMBERSHIP", Const, 0},
+ {"IP_AUTH_LEVEL", Const, 1},
+ {"IP_BINDANY", Const, 0},
+ {"IP_BLOCK_SOURCE", Const, 0},
+ {"IP_BOUND_IF", Const, 0},
+ {"IP_DEFAULT_MULTICAST_LOOP", Const, 0},
+ {"IP_DEFAULT_MULTICAST_TTL", Const, 0},
+ {"IP_DF", Const, 0},
+ {"IP_DIVERTFL", Const, 3},
+ {"IP_DONTFRAG", Const, 0},
+ {"IP_DROP_MEMBERSHIP", Const, 0},
+ {"IP_DROP_SOURCE_MEMBERSHIP", Const, 0},
+ {"IP_DUMMYNET3", Const, 0},
+ {"IP_DUMMYNET_CONFIGURE", Const, 0},
+ {"IP_DUMMYNET_DEL", Const, 0},
+ {"IP_DUMMYNET_FLUSH", Const, 0},
+ {"IP_DUMMYNET_GET", Const, 0},
+ {"IP_EF", Const, 1},
+ {"IP_ERRORMTU", Const, 1},
+ {"IP_ESP_NETWORK_LEVEL", Const, 1},
+ {"IP_ESP_TRANS_LEVEL", Const, 1},
+ {"IP_FAITH", Const, 0},
+ {"IP_FREEBIND", Const, 0},
+ {"IP_FW3", Const, 0},
+ {"IP_FW_ADD", Const, 0},
+ {"IP_FW_DEL", Const, 0},
+ {"IP_FW_FLUSH", Const, 0},
+ {"IP_FW_GET", Const, 0},
+ {"IP_FW_NAT_CFG", Const, 0},
+ {"IP_FW_NAT_DEL", Const, 0},
+ {"IP_FW_NAT_GET_CONFIG", Const, 0},
+ {"IP_FW_NAT_GET_LOG", Const, 0},
+ {"IP_FW_RESETLOG", Const, 0},
+ {"IP_FW_TABLE_ADD", Const, 0},
+ {"IP_FW_TABLE_DEL", Const, 0},
+ {"IP_FW_TABLE_FLUSH", Const, 0},
+ {"IP_FW_TABLE_GETSIZE", Const, 0},
+ {"IP_FW_TABLE_LIST", Const, 0},
+ {"IP_FW_ZERO", Const, 0},
+ {"IP_HDRINCL", Const, 0},
+ {"IP_IPCOMP_LEVEL", Const, 1},
+ {"IP_IPSECFLOWINFO", Const, 1},
+ {"IP_IPSEC_LOCAL_AUTH", Const, 1},
+ {"IP_IPSEC_LOCAL_CRED", Const, 1},
+ {"IP_IPSEC_LOCAL_ID", Const, 1},
+ {"IP_IPSEC_POLICY", Const, 0},
+ {"IP_IPSEC_REMOTE_AUTH", Const, 1},
+ {"IP_IPSEC_REMOTE_CRED", Const, 1},
+ {"IP_IPSEC_REMOTE_ID", Const, 1},
+ {"IP_MAXPACKET", Const, 0},
+ {"IP_MAX_GROUP_SRC_FILTER", Const, 0},
+ {"IP_MAX_MEMBERSHIPS", Const, 0},
+ {"IP_MAX_SOCK_MUTE_FILTER", Const, 0},
+ {"IP_MAX_SOCK_SRC_FILTER", Const, 0},
+ {"IP_MAX_SOURCE_FILTER", Const, 0},
+ {"IP_MF", Const, 0},
+ {"IP_MINFRAGSIZE", Const, 1},
+ {"IP_MINTTL", Const, 0},
+ {"IP_MIN_MEMBERSHIPS", Const, 0},
+ {"IP_MSFILTER", Const, 0},
+ {"IP_MSS", Const, 0},
+ {"IP_MTU", Const, 0},
+ {"IP_MTU_DISCOVER", Const, 0},
+ {"IP_MULTICAST_IF", Const, 0},
+ {"IP_MULTICAST_IFINDEX", Const, 0},
+ {"IP_MULTICAST_LOOP", Const, 0},
+ {"IP_MULTICAST_TTL", Const, 0},
+ {"IP_MULTICAST_VIF", Const, 0},
+ {"IP_NAT__XXX", Const, 0},
+ {"IP_OFFMASK", Const, 0},
+ {"IP_OLD_FW_ADD", Const, 0},
+ {"IP_OLD_FW_DEL", Const, 0},
+ {"IP_OLD_FW_FLUSH", Const, 0},
+ {"IP_OLD_FW_GET", Const, 0},
+ {"IP_OLD_FW_RESETLOG", Const, 0},
+ {"IP_OLD_FW_ZERO", Const, 0},
+ {"IP_ONESBCAST", Const, 0},
+ {"IP_OPTIONS", Const, 0},
+ {"IP_ORIGDSTADDR", Const, 0},
+ {"IP_PASSSEC", Const, 0},
+ {"IP_PIPEX", Const, 1},
+ {"IP_PKTINFO", Const, 0},
+ {"IP_PKTOPTIONS", Const, 0},
+ {"IP_PMTUDISC", Const, 0},
+ {"IP_PMTUDISC_DO", Const, 0},
+ {"IP_PMTUDISC_DONT", Const, 0},
+ {"IP_PMTUDISC_PROBE", Const, 0},
+ {"IP_PMTUDISC_WANT", Const, 0},
+ {"IP_PORTRANGE", Const, 0},
+ {"IP_PORTRANGE_DEFAULT", Const, 0},
+ {"IP_PORTRANGE_HIGH", Const, 0},
+ {"IP_PORTRANGE_LOW", Const, 0},
+ {"IP_RECVDSTADDR", Const, 0},
+ {"IP_RECVDSTPORT", Const, 1},
+ {"IP_RECVERR", Const, 0},
+ {"IP_RECVIF", Const, 0},
+ {"IP_RECVOPTS", Const, 0},
+ {"IP_RECVORIGDSTADDR", Const, 0},
+ {"IP_RECVPKTINFO", Const, 0},
+ {"IP_RECVRETOPTS", Const, 0},
+ {"IP_RECVRTABLE", Const, 1},
+ {"IP_RECVTOS", Const, 0},
+ {"IP_RECVTTL", Const, 0},
+ {"IP_RETOPTS", Const, 0},
+ {"IP_RF", Const, 0},
+ {"IP_ROUTER_ALERT", Const, 0},
+ {"IP_RSVP_OFF", Const, 0},
+ {"IP_RSVP_ON", Const, 0},
+ {"IP_RSVP_VIF_OFF", Const, 0},
+ {"IP_RSVP_VIF_ON", Const, 0},
+ {"IP_RTABLE", Const, 1},
+ {"IP_SENDSRCADDR", Const, 0},
+ {"IP_STRIPHDR", Const, 0},
+ {"IP_TOS", Const, 0},
+ {"IP_TRAFFIC_MGT_BACKGROUND", Const, 0},
+ {"IP_TRANSPARENT", Const, 0},
+ {"IP_TTL", Const, 0},
+ {"IP_UNBLOCK_SOURCE", Const, 0},
+ {"IP_XFRM_POLICY", Const, 0},
+ {"IPv6MTUInfo", Type, 2},
+ {"IPv6MTUInfo.Addr", Field, 2},
+ {"IPv6MTUInfo.Mtu", Field, 2},
+ {"IPv6Mreq", Type, 0},
+ {"IPv6Mreq.Interface", Field, 0},
+ {"IPv6Mreq.Multiaddr", Field, 0},
+ {"ISIG", Const, 0},
+ {"ISTRIP", Const, 0},
+ {"IUCLC", Const, 0},
+ {"IUTF8", Const, 0},
+ {"IXANY", Const, 0},
+ {"IXOFF", Const, 0},
+ {"IXON", Const, 0},
+ {"IfAddrmsg", Type, 0},
+ {"IfAddrmsg.Family", Field, 0},
+ {"IfAddrmsg.Flags", Field, 0},
+ {"IfAddrmsg.Index", Field, 0},
+ {"IfAddrmsg.Prefixlen", Field, 0},
+ {"IfAddrmsg.Scope", Field, 0},
+ {"IfAnnounceMsghdr", Type, 1},
+ {"IfAnnounceMsghdr.Hdrlen", Field, 2},
+ {"IfAnnounceMsghdr.Index", Field, 1},
+ {"IfAnnounceMsghdr.Msglen", Field, 1},
+ {"IfAnnounceMsghdr.Name", Field, 1},
+ {"IfAnnounceMsghdr.Type", Field, 1},
+ {"IfAnnounceMsghdr.Version", Field, 1},
+ {"IfAnnounceMsghdr.What", Field, 1},
+ {"IfData", Type, 0},
+ {"IfData.Addrlen", Field, 0},
+ {"IfData.Baudrate", Field, 0},
+ {"IfData.Capabilities", Field, 2},
+ {"IfData.Collisions", Field, 0},
+ {"IfData.Datalen", Field, 0},
+ {"IfData.Epoch", Field, 0},
+ {"IfData.Hdrlen", Field, 0},
+ {"IfData.Hwassist", Field, 0},
+ {"IfData.Ibytes", Field, 0},
+ {"IfData.Ierrors", Field, 0},
+ {"IfData.Imcasts", Field, 0},
+ {"IfData.Ipackets", Field, 0},
+ {"IfData.Iqdrops", Field, 0},
+ {"IfData.Lastchange", Field, 0},
+ {"IfData.Link_state", Field, 0},
+ {"IfData.Mclpool", Field, 2},
+ {"IfData.Metric", Field, 0},
+ {"IfData.Mtu", Field, 0},
+ {"IfData.Noproto", Field, 0},
+ {"IfData.Obytes", Field, 0},
+ {"IfData.Oerrors", Field, 0},
+ {"IfData.Omcasts", Field, 0},
+ {"IfData.Opackets", Field, 0},
+ {"IfData.Pad", Field, 2},
+ {"IfData.Pad_cgo_0", Field, 2},
+ {"IfData.Pad_cgo_1", Field, 2},
+ {"IfData.Physical", Field, 0},
+ {"IfData.Recvquota", Field, 0},
+ {"IfData.Recvtiming", Field, 0},
+ {"IfData.Reserved1", Field, 0},
+ {"IfData.Reserved2", Field, 0},
+ {"IfData.Spare_char1", Field, 0},
+ {"IfData.Spare_char2", Field, 0},
+ {"IfData.Type", Field, 0},
+ {"IfData.Typelen", Field, 0},
+ {"IfData.Unused1", Field, 0},
+ {"IfData.Unused2", Field, 0},
+ {"IfData.Xmitquota", Field, 0},
+ {"IfData.Xmittiming", Field, 0},
+ {"IfInfomsg", Type, 0},
+ {"IfInfomsg.Change", Field, 0},
+ {"IfInfomsg.Family", Field, 0},
+ {"IfInfomsg.Flags", Field, 0},
+ {"IfInfomsg.Index", Field, 0},
+ {"IfInfomsg.Type", Field, 0},
+ {"IfInfomsg.X__ifi_pad", Field, 0},
+ {"IfMsghdr", Type, 0},
+ {"IfMsghdr.Addrs", Field, 0},
+ {"IfMsghdr.Data", Field, 0},
+ {"IfMsghdr.Flags", Field, 0},
+ {"IfMsghdr.Hdrlen", Field, 2},
+ {"IfMsghdr.Index", Field, 0},
+ {"IfMsghdr.Msglen", Field, 0},
+ {"IfMsghdr.Pad1", Field, 2},
+ {"IfMsghdr.Pad2", Field, 2},
+ {"IfMsghdr.Pad_cgo_0", Field, 0},
+ {"IfMsghdr.Pad_cgo_1", Field, 2},
+ {"IfMsghdr.Tableid", Field, 2},
+ {"IfMsghdr.Type", Field, 0},
+ {"IfMsghdr.Version", Field, 0},
+ {"IfMsghdr.Xflags", Field, 2},
+ {"IfaMsghdr", Type, 0},
+ {"IfaMsghdr.Addrs", Field, 0},
+ {"IfaMsghdr.Flags", Field, 0},
+ {"IfaMsghdr.Hdrlen", Field, 2},
+ {"IfaMsghdr.Index", Field, 0},
+ {"IfaMsghdr.Metric", Field, 0},
+ {"IfaMsghdr.Msglen", Field, 0},
+ {"IfaMsghdr.Pad1", Field, 2},
+ {"IfaMsghdr.Pad2", Field, 2},
+ {"IfaMsghdr.Pad_cgo_0", Field, 0},
+ {"IfaMsghdr.Tableid", Field, 2},
+ {"IfaMsghdr.Type", Field, 0},
+ {"IfaMsghdr.Version", Field, 0},
+ {"IfmaMsghdr", Type, 0},
+ {"IfmaMsghdr.Addrs", Field, 0},
+ {"IfmaMsghdr.Flags", Field, 0},
+ {"IfmaMsghdr.Index", Field, 0},
+ {"IfmaMsghdr.Msglen", Field, 0},
+ {"IfmaMsghdr.Pad_cgo_0", Field, 0},
+ {"IfmaMsghdr.Type", Field, 0},
+ {"IfmaMsghdr.Version", Field, 0},
+ {"IfmaMsghdr2", Type, 0},
+ {"IfmaMsghdr2.Addrs", Field, 0},
+ {"IfmaMsghdr2.Flags", Field, 0},
+ {"IfmaMsghdr2.Index", Field, 0},
+ {"IfmaMsghdr2.Msglen", Field, 0},
+ {"IfmaMsghdr2.Pad_cgo_0", Field, 0},
+ {"IfmaMsghdr2.Refcount", Field, 0},
+ {"IfmaMsghdr2.Type", Field, 0},
+ {"IfmaMsghdr2.Version", Field, 0},
+ {"ImplementsGetwd", Const, 0},
+ {"Inet4Pktinfo", Type, 0},
+ {"Inet4Pktinfo.Addr", Field, 0},
+ {"Inet4Pktinfo.Ifindex", Field, 0},
+ {"Inet4Pktinfo.Spec_dst", Field, 0},
+ {"Inet6Pktinfo", Type, 0},
+ {"Inet6Pktinfo.Addr", Field, 0},
+ {"Inet6Pktinfo.Ifindex", Field, 0},
+ {"InotifyAddWatch", Func, 0},
+ {"InotifyEvent", Type, 0},
+ {"InotifyEvent.Cookie", Field, 0},
+ {"InotifyEvent.Len", Field, 0},
+ {"InotifyEvent.Mask", Field, 0},
+ {"InotifyEvent.Name", Field, 0},
+ {"InotifyEvent.Wd", Field, 0},
+ {"InotifyInit", Func, 0},
+ {"InotifyInit1", Func, 0},
+ {"InotifyRmWatch", Func, 0},
+ {"InterfaceAddrMessage", Type, 0},
+ {"InterfaceAddrMessage.Data", Field, 0},
+ {"InterfaceAddrMessage.Header", Field, 0},
+ {"InterfaceAnnounceMessage", Type, 1},
+ {"InterfaceAnnounceMessage.Header", Field, 1},
+ {"InterfaceInfo", Type, 0},
+ {"InterfaceInfo.Address", Field, 0},
+ {"InterfaceInfo.BroadcastAddress", Field, 0},
+ {"InterfaceInfo.Flags", Field, 0},
+ {"InterfaceInfo.Netmask", Field, 0},
+ {"InterfaceMessage", Type, 0},
+ {"InterfaceMessage.Data", Field, 0},
+ {"InterfaceMessage.Header", Field, 0},
+ {"InterfaceMulticastAddrMessage", Type, 0},
+ {"InterfaceMulticastAddrMessage.Data", Field, 0},
+ {"InterfaceMulticastAddrMessage.Header", Field, 0},
+ {"InvalidHandle", Const, 0},
+ {"Ioperm", Func, 0},
+ {"Iopl", Func, 0},
+ {"Iovec", Type, 0},
+ {"Iovec.Base", Field, 0},
+ {"Iovec.Len", Field, 0},
+ {"IpAdapterInfo", Type, 0},
+ {"IpAdapterInfo.AdapterName", Field, 0},
+ {"IpAdapterInfo.Address", Field, 0},
+ {"IpAdapterInfo.AddressLength", Field, 0},
+ {"IpAdapterInfo.ComboIndex", Field, 0},
+ {"IpAdapterInfo.CurrentIpAddress", Field, 0},
+ {"IpAdapterInfo.Description", Field, 0},
+ {"IpAdapterInfo.DhcpEnabled", Field, 0},
+ {"IpAdapterInfo.DhcpServer", Field, 0},
+ {"IpAdapterInfo.GatewayList", Field, 0},
+ {"IpAdapterInfo.HaveWins", Field, 0},
+ {"IpAdapterInfo.Index", Field, 0},
+ {"IpAdapterInfo.IpAddressList", Field, 0},
+ {"IpAdapterInfo.LeaseExpires", Field, 0},
+ {"IpAdapterInfo.LeaseObtained", Field, 0},
+ {"IpAdapterInfo.Next", Field, 0},
+ {"IpAdapterInfo.PrimaryWinsServer", Field, 0},
+ {"IpAdapterInfo.SecondaryWinsServer", Field, 0},
+ {"IpAdapterInfo.Type", Field, 0},
+ {"IpAddrString", Type, 0},
+ {"IpAddrString.Context", Field, 0},
+ {"IpAddrString.IpAddress", Field, 0},
+ {"IpAddrString.IpMask", Field, 0},
+ {"IpAddrString.Next", Field, 0},
+ {"IpAddressString", Type, 0},
+ {"IpAddressString.String", Field, 0},
+ {"IpMaskString", Type, 0},
+ {"IpMaskString.String", Field, 2},
+ {"Issetugid", Func, 0},
+ {"KEY_ALL_ACCESS", Const, 0},
+ {"KEY_CREATE_LINK", Const, 0},
+ {"KEY_CREATE_SUB_KEY", Const, 0},
+ {"KEY_ENUMERATE_SUB_KEYS", Const, 0},
+ {"KEY_EXECUTE", Const, 0},
+ {"KEY_NOTIFY", Const, 0},
+ {"KEY_QUERY_VALUE", Const, 0},
+ {"KEY_READ", Const, 0},
+ {"KEY_SET_VALUE", Const, 0},
+ {"KEY_WOW64_32KEY", Const, 0},
+ {"KEY_WOW64_64KEY", Const, 0},
+ {"KEY_WRITE", Const, 0},
+ {"Kevent", Func, 0},
+ {"Kevent_t", Type, 0},
+ {"Kevent_t.Data", Field, 0},
+ {"Kevent_t.Fflags", Field, 0},
+ {"Kevent_t.Filter", Field, 0},
+ {"Kevent_t.Flags", Field, 0},
+ {"Kevent_t.Ident", Field, 0},
+ {"Kevent_t.Pad_cgo_0", Field, 2},
+ {"Kevent_t.Udata", Field, 0},
+ {"Kill", Func, 0},
+ {"Klogctl", Func, 0},
+ {"Kqueue", Func, 0},
+ {"LANG_ENGLISH", Const, 0},
+ {"LAYERED_PROTOCOL", Const, 2},
+ {"LCNT_OVERLOAD_FLUSH", Const, 1},
+ {"LINUX_REBOOT_CMD_CAD_OFF", Const, 0},
+ {"LINUX_REBOOT_CMD_CAD_ON", Const, 0},
+ {"LINUX_REBOOT_CMD_HALT", Const, 0},
+ {"LINUX_REBOOT_CMD_KEXEC", Const, 0},
+ {"LINUX_REBOOT_CMD_POWER_OFF", Const, 0},
+ {"LINUX_REBOOT_CMD_RESTART", Const, 0},
+ {"LINUX_REBOOT_CMD_RESTART2", Const, 0},
+ {"LINUX_REBOOT_CMD_SW_SUSPEND", Const, 0},
+ {"LINUX_REBOOT_MAGIC1", Const, 0},
+ {"LINUX_REBOOT_MAGIC2", Const, 0},
+ {"LOCK_EX", Const, 0},
+ {"LOCK_NB", Const, 0},
+ {"LOCK_SH", Const, 0},
+ {"LOCK_UN", Const, 0},
+ {"LazyDLL", Type, 0},
+ {"LazyDLL.Name", Field, 0},
+ {"LazyProc", Type, 0},
+ {"LazyProc.Name", Field, 0},
+ {"Lchown", Func, 0},
+ {"Linger", Type, 0},
+ {"Linger.Linger", Field, 0},
+ {"Linger.Onoff", Field, 0},
+ {"Link", Func, 0},
+ {"Listen", Func, 0},
+ {"Listxattr", Func, 1},
+ {"LoadCancelIoEx", Func, 1},
+ {"LoadConnectEx", Func, 1},
+ {"LoadCreateSymbolicLink", Func, 4},
+ {"LoadDLL", Func, 0},
+ {"LoadGetAddrInfo", Func, 1},
+ {"LoadLibrary", Func, 0},
+ {"LoadSetFileCompletionNotificationModes", Func, 2},
+ {"LocalFree", Func, 0},
+ {"Log2phys_t", Type, 0},
+ {"Log2phys_t.Contigbytes", Field, 0},
+ {"Log2phys_t.Devoffset", Field, 0},
+ {"Log2phys_t.Flags", Field, 0},
+ {"LookupAccountName", Func, 0},
+ {"LookupAccountSid", Func, 0},
+ {"LookupSID", Func, 0},
+ {"LsfJump", Func, 0},
+ {"LsfSocket", Func, 0},
+ {"LsfStmt", Func, 0},
+ {"Lstat", Func, 0},
+ {"MADV_AUTOSYNC", Const, 1},
+ {"MADV_CAN_REUSE", Const, 0},
+ {"MADV_CORE", Const, 1},
+ {"MADV_DOFORK", Const, 0},
+ {"MADV_DONTFORK", Const, 0},
+ {"MADV_DONTNEED", Const, 0},
+ {"MADV_FREE", Const, 0},
+ {"MADV_FREE_REUSABLE", Const, 0},
+ {"MADV_FREE_REUSE", Const, 0},
+ {"MADV_HUGEPAGE", Const, 0},
+ {"MADV_HWPOISON", Const, 0},
+ {"MADV_MERGEABLE", Const, 0},
+ {"MADV_NOCORE", Const, 1},
+ {"MADV_NOHUGEPAGE", Const, 0},
+ {"MADV_NORMAL", Const, 0},
+ {"MADV_NOSYNC", Const, 1},
+ {"MADV_PROTECT", Const, 1},
+ {"MADV_RANDOM", Const, 0},
+ {"MADV_REMOVE", Const, 0},
+ {"MADV_SEQUENTIAL", Const, 0},
+ {"MADV_SPACEAVAIL", Const, 3},
+ {"MADV_UNMERGEABLE", Const, 0},
+ {"MADV_WILLNEED", Const, 0},
+ {"MADV_ZERO_WIRED_PAGES", Const, 0},
+ {"MAP_32BIT", Const, 0},
+ {"MAP_ALIGNED_SUPER", Const, 3},
+ {"MAP_ALIGNMENT_16MB", Const, 3},
+ {"MAP_ALIGNMENT_1TB", Const, 3},
+ {"MAP_ALIGNMENT_256TB", Const, 3},
+ {"MAP_ALIGNMENT_4GB", Const, 3},
+ {"MAP_ALIGNMENT_64KB", Const, 3},
+ {"MAP_ALIGNMENT_64PB", Const, 3},
+ {"MAP_ALIGNMENT_MASK", Const, 3},
+ {"MAP_ALIGNMENT_SHIFT", Const, 3},
+ {"MAP_ANON", Const, 0},
+ {"MAP_ANONYMOUS", Const, 0},
+ {"MAP_COPY", Const, 0},
+ {"MAP_DENYWRITE", Const, 0},
+ {"MAP_EXECUTABLE", Const, 0},
+ {"MAP_FILE", Const, 0},
+ {"MAP_FIXED", Const, 0},
+ {"MAP_FLAGMASK", Const, 3},
+ {"MAP_GROWSDOWN", Const, 0},
+ {"MAP_HASSEMAPHORE", Const, 0},
+ {"MAP_HUGETLB", Const, 0},
+ {"MAP_INHERIT", Const, 3},
+ {"MAP_INHERIT_COPY", Const, 3},
+ {"MAP_INHERIT_DEFAULT", Const, 3},
+ {"MAP_INHERIT_DONATE_COPY", Const, 3},
+ {"MAP_INHERIT_NONE", Const, 3},
+ {"MAP_INHERIT_SHARE", Const, 3},
+ {"MAP_JIT", Const, 0},
+ {"MAP_LOCKED", Const, 0},
+ {"MAP_NOCACHE", Const, 0},
+ {"MAP_NOCORE", Const, 1},
+ {"MAP_NOEXTEND", Const, 0},
+ {"MAP_NONBLOCK", Const, 0},
+ {"MAP_NORESERVE", Const, 0},
+ {"MAP_NOSYNC", Const, 1},
+ {"MAP_POPULATE", Const, 0},
+ {"MAP_PREFAULT_READ", Const, 1},
+ {"MAP_PRIVATE", Const, 0},
+ {"MAP_RENAME", Const, 0},
+ {"MAP_RESERVED0080", Const, 0},
+ {"MAP_RESERVED0100", Const, 1},
+ {"MAP_SHARED", Const, 0},
+ {"MAP_STACK", Const, 0},
+ {"MAP_TRYFIXED", Const, 3},
+ {"MAP_TYPE", Const, 0},
+ {"MAP_WIRED", Const, 3},
+ {"MAXIMUM_REPARSE_DATA_BUFFER_SIZE", Const, 4},
+ {"MAXLEN_IFDESCR", Const, 0},
+ {"MAXLEN_PHYSADDR", Const, 0},
+ {"MAX_ADAPTER_ADDRESS_LENGTH", Const, 0},
+ {"MAX_ADAPTER_DESCRIPTION_LENGTH", Const, 0},
+ {"MAX_ADAPTER_NAME_LENGTH", Const, 0},
+ {"MAX_COMPUTERNAME_LENGTH", Const, 0},
+ {"MAX_INTERFACE_NAME_LEN", Const, 0},
+ {"MAX_LONG_PATH", Const, 0},
+ {"MAX_PATH", Const, 0},
+ {"MAX_PROTOCOL_CHAIN", Const, 2},
+ {"MCL_CURRENT", Const, 0},
+ {"MCL_FUTURE", Const, 0},
+ {"MNT_DETACH", Const, 0},
+ {"MNT_EXPIRE", Const, 0},
+ {"MNT_FORCE", Const, 0},
+ {"MSG_BCAST", Const, 1},
+ {"MSG_CMSG_CLOEXEC", Const, 0},
+ {"MSG_COMPAT", Const, 0},
+ {"MSG_CONFIRM", Const, 0},
+ {"MSG_CONTROLMBUF", Const, 1},
+ {"MSG_CTRUNC", Const, 0},
+ {"MSG_DONTROUTE", Const, 0},
+ {"MSG_DONTWAIT", Const, 0},
+ {"MSG_EOF", Const, 0},
+ {"MSG_EOR", Const, 0},
+ {"MSG_ERRQUEUE", Const, 0},
+ {"MSG_FASTOPEN", Const, 1},
+ {"MSG_FIN", Const, 0},
+ {"MSG_FLUSH", Const, 0},
+ {"MSG_HAVEMORE", Const, 0},
+ {"MSG_HOLD", Const, 0},
+ {"MSG_IOVUSRSPACE", Const, 1},
+ {"MSG_LENUSRSPACE", Const, 1},
+ {"MSG_MCAST", Const, 1},
+ {"MSG_MORE", Const, 0},
+ {"MSG_NAMEMBUF", Const, 1},
+ {"MSG_NBIO", Const, 0},
+ {"MSG_NEEDSA", Const, 0},
+ {"MSG_NOSIGNAL", Const, 0},
+ {"MSG_NOTIFICATION", Const, 0},
+ {"MSG_OOB", Const, 0},
+ {"MSG_PEEK", Const, 0},
+ {"MSG_PROXY", Const, 0},
+ {"MSG_RCVMORE", Const, 0},
+ {"MSG_RST", Const, 0},
+ {"MSG_SEND", Const, 0},
+ {"MSG_SYN", Const, 0},
+ {"MSG_TRUNC", Const, 0},
+ {"MSG_TRYHARD", Const, 0},
+ {"MSG_USERFLAGS", Const, 1},
+ {"MSG_WAITALL", Const, 0},
+ {"MSG_WAITFORONE", Const, 0},
+ {"MSG_WAITSTREAM", Const, 0},
+ {"MS_ACTIVE", Const, 0},
+ {"MS_ASYNC", Const, 0},
+ {"MS_BIND", Const, 0},
+ {"MS_DEACTIVATE", Const, 0},
+ {"MS_DIRSYNC", Const, 0},
+ {"MS_INVALIDATE", Const, 0},
+ {"MS_I_VERSION", Const, 0},
+ {"MS_KERNMOUNT", Const, 0},
+ {"MS_KILLPAGES", Const, 0},
+ {"MS_MANDLOCK", Const, 0},
+ {"MS_MGC_MSK", Const, 0},
+ {"MS_MGC_VAL", Const, 0},
+ {"MS_MOVE", Const, 0},
+ {"MS_NOATIME", Const, 0},
+ {"MS_NODEV", Const, 0},
+ {"MS_NODIRATIME", Const, 0},
+ {"MS_NOEXEC", Const, 0},
+ {"MS_NOSUID", Const, 0},
+ {"MS_NOUSER", Const, 0},
+ {"MS_POSIXACL", Const, 0},
+ {"MS_PRIVATE", Const, 0},
+ {"MS_RDONLY", Const, 0},
+ {"MS_REC", Const, 0},
+ {"MS_RELATIME", Const, 0},
+ {"MS_REMOUNT", Const, 0},
+ {"MS_RMT_MASK", Const, 0},
+ {"MS_SHARED", Const, 0},
+ {"MS_SILENT", Const, 0},
+ {"MS_SLAVE", Const, 0},
+ {"MS_STRICTATIME", Const, 0},
+ {"MS_SYNC", Const, 0},
+ {"MS_SYNCHRONOUS", Const, 0},
+ {"MS_UNBINDABLE", Const, 0},
+ {"Madvise", Func, 0},
+ {"MapViewOfFile", Func, 0},
+ {"MaxTokenInfoClass", Const, 0},
+ {"Mclpool", Type, 2},
+ {"Mclpool.Alive", Field, 2},
+ {"Mclpool.Cwm", Field, 2},
+ {"Mclpool.Grown", Field, 2},
+ {"Mclpool.Hwm", Field, 2},
+ {"Mclpool.Lwm", Field, 2},
+ {"MibIfRow", Type, 0},
+ {"MibIfRow.AdminStatus", Field, 0},
+ {"MibIfRow.Descr", Field, 0},
+ {"MibIfRow.DescrLen", Field, 0},
+ {"MibIfRow.InDiscards", Field, 0},
+ {"MibIfRow.InErrors", Field, 0},
+ {"MibIfRow.InNUcastPkts", Field, 0},
+ {"MibIfRow.InOctets", Field, 0},
+ {"MibIfRow.InUcastPkts", Field, 0},
+ {"MibIfRow.InUnknownProtos", Field, 0},
+ {"MibIfRow.Index", Field, 0},
+ {"MibIfRow.LastChange", Field, 0},
+ {"MibIfRow.Mtu", Field, 0},
+ {"MibIfRow.Name", Field, 0},
+ {"MibIfRow.OperStatus", Field, 0},
+ {"MibIfRow.OutDiscards", Field, 0},
+ {"MibIfRow.OutErrors", Field, 0},
+ {"MibIfRow.OutNUcastPkts", Field, 0},
+ {"MibIfRow.OutOctets", Field, 0},
+ {"MibIfRow.OutQLen", Field, 0},
+ {"MibIfRow.OutUcastPkts", Field, 0},
+ {"MibIfRow.PhysAddr", Field, 0},
+ {"MibIfRow.PhysAddrLen", Field, 0},
+ {"MibIfRow.Speed", Field, 0},
+ {"MibIfRow.Type", Field, 0},
+ {"Mkdir", Func, 0},
+ {"Mkdirat", Func, 0},
+ {"Mkfifo", Func, 0},
+ {"Mknod", Func, 0},
+ {"Mknodat", Func, 0},
+ {"Mlock", Func, 0},
+ {"Mlockall", Func, 0},
+ {"Mmap", Func, 0},
+ {"Mount", Func, 0},
+ {"MoveFile", Func, 0},
+ {"Mprotect", Func, 0},
+ {"Msghdr", Type, 0},
+ {"Msghdr.Control", Field, 0},
+ {"Msghdr.Controllen", Field, 0},
+ {"Msghdr.Flags", Field, 0},
+ {"Msghdr.Iov", Field, 0},
+ {"Msghdr.Iovlen", Field, 0},
+ {"Msghdr.Name", Field, 0},
+ {"Msghdr.Namelen", Field, 0},
+ {"Msghdr.Pad_cgo_0", Field, 0},
+ {"Msghdr.Pad_cgo_1", Field, 0},
+ {"Munlock", Func, 0},
+ {"Munlockall", Func, 0},
+ {"Munmap", Func, 0},
+ {"MustLoadDLL", Func, 0},
+ {"NAME_MAX", Const, 0},
+ {"NETLINK_ADD_MEMBERSHIP", Const, 0},
+ {"NETLINK_AUDIT", Const, 0},
+ {"NETLINK_BROADCAST_ERROR", Const, 0},
+ {"NETLINK_CONNECTOR", Const, 0},
+ {"NETLINK_DNRTMSG", Const, 0},
+ {"NETLINK_DROP_MEMBERSHIP", Const, 0},
+ {"NETLINK_ECRYPTFS", Const, 0},
+ {"NETLINK_FIB_LOOKUP", Const, 0},
+ {"NETLINK_FIREWALL", Const, 0},
+ {"NETLINK_GENERIC", Const, 0},
+ {"NETLINK_INET_DIAG", Const, 0},
+ {"NETLINK_IP6_FW", Const, 0},
+ {"NETLINK_ISCSI", Const, 0},
+ {"NETLINK_KOBJECT_UEVENT", Const, 0},
+ {"NETLINK_NETFILTER", Const, 0},
+ {"NETLINK_NFLOG", Const, 0},
+ {"NETLINK_NO_ENOBUFS", Const, 0},
+ {"NETLINK_PKTINFO", Const, 0},
+ {"NETLINK_RDMA", Const, 0},
+ {"NETLINK_ROUTE", Const, 0},
+ {"NETLINK_SCSITRANSPORT", Const, 0},
+ {"NETLINK_SELINUX", Const, 0},
+ {"NETLINK_UNUSED", Const, 0},
+ {"NETLINK_USERSOCK", Const, 0},
+ {"NETLINK_XFRM", Const, 0},
+ {"NET_RT_DUMP", Const, 0},
+ {"NET_RT_DUMP2", Const, 0},
+ {"NET_RT_FLAGS", Const, 0},
+ {"NET_RT_IFLIST", Const, 0},
+ {"NET_RT_IFLIST2", Const, 0},
+ {"NET_RT_IFLISTL", Const, 1},
+ {"NET_RT_IFMALIST", Const, 0},
+ {"NET_RT_MAXID", Const, 0},
+ {"NET_RT_OIFLIST", Const, 1},
+ {"NET_RT_OOIFLIST", Const, 1},
+ {"NET_RT_STAT", Const, 0},
+ {"NET_RT_STATS", Const, 1},
+ {"NET_RT_TABLE", Const, 1},
+ {"NET_RT_TRASH", Const, 0},
+ {"NLA_ALIGNTO", Const, 0},
+ {"NLA_F_NESTED", Const, 0},
+ {"NLA_F_NET_BYTEORDER", Const, 0},
+ {"NLA_HDRLEN", Const, 0},
+ {"NLMSG_ALIGNTO", Const, 0},
+ {"NLMSG_DONE", Const, 0},
+ {"NLMSG_ERROR", Const, 0},
+ {"NLMSG_HDRLEN", Const, 0},
+ {"NLMSG_MIN_TYPE", Const, 0},
+ {"NLMSG_NOOP", Const, 0},
+ {"NLMSG_OVERRUN", Const, 0},
+ {"NLM_F_ACK", Const, 0},
+ {"NLM_F_APPEND", Const, 0},
+ {"NLM_F_ATOMIC", Const, 0},
+ {"NLM_F_CREATE", Const, 0},
+ {"NLM_F_DUMP", Const, 0},
+ {"NLM_F_ECHO", Const, 0},
+ {"NLM_F_EXCL", Const, 0},
+ {"NLM_F_MATCH", Const, 0},
+ {"NLM_F_MULTI", Const, 0},
+ {"NLM_F_REPLACE", Const, 0},
+ {"NLM_F_REQUEST", Const, 0},
+ {"NLM_F_ROOT", Const, 0},
+ {"NOFLSH", Const, 0},
+ {"NOTE_ABSOLUTE", Const, 0},
+ {"NOTE_ATTRIB", Const, 0},
+ {"NOTE_BACKGROUND", Const, 16},
+ {"NOTE_CHILD", Const, 0},
+ {"NOTE_CRITICAL", Const, 16},
+ {"NOTE_DELETE", Const, 0},
+ {"NOTE_EOF", Const, 1},
+ {"NOTE_EXEC", Const, 0},
+ {"NOTE_EXIT", Const, 0},
+ {"NOTE_EXITSTATUS", Const, 0},
+ {"NOTE_EXIT_CSERROR", Const, 16},
+ {"NOTE_EXIT_DECRYPTFAIL", Const, 16},
+ {"NOTE_EXIT_DETAIL", Const, 16},
+ {"NOTE_EXIT_DETAIL_MASK", Const, 16},
+ {"NOTE_EXIT_MEMORY", Const, 16},
+ {"NOTE_EXIT_REPARENTED", Const, 16},
+ {"NOTE_EXTEND", Const, 0},
+ {"NOTE_FFAND", Const, 0},
+ {"NOTE_FFCOPY", Const, 0},
+ {"NOTE_FFCTRLMASK", Const, 0},
+ {"NOTE_FFLAGSMASK", Const, 0},
+ {"NOTE_FFNOP", Const, 0},
+ {"NOTE_FFOR", Const, 0},
+ {"NOTE_FORK", Const, 0},
+ {"NOTE_LEEWAY", Const, 16},
+ {"NOTE_LINK", Const, 0},
+ {"NOTE_LOWAT", Const, 0},
+ {"NOTE_NONE", Const, 0},
+ {"NOTE_NSECONDS", Const, 0},
+ {"NOTE_PCTRLMASK", Const, 0},
+ {"NOTE_PDATAMASK", Const, 0},
+ {"NOTE_REAP", Const, 0},
+ {"NOTE_RENAME", Const, 0},
+ {"NOTE_RESOURCEEND", Const, 0},
+ {"NOTE_REVOKE", Const, 0},
+ {"NOTE_SECONDS", Const, 0},
+ {"NOTE_SIGNAL", Const, 0},
+ {"NOTE_TRACK", Const, 0},
+ {"NOTE_TRACKERR", Const, 0},
+ {"NOTE_TRIGGER", Const, 0},
+ {"NOTE_TRUNCATE", Const, 1},
+ {"NOTE_USECONDS", Const, 0},
+ {"NOTE_VM_ERROR", Const, 0},
+ {"NOTE_VM_PRESSURE", Const, 0},
+ {"NOTE_VM_PRESSURE_SUDDEN_TERMINATE", Const, 0},
+ {"NOTE_VM_PRESSURE_TERMINATE", Const, 0},
+ {"NOTE_WRITE", Const, 0},
+ {"NameCanonical", Const, 0},
+ {"NameCanonicalEx", Const, 0},
+ {"NameDisplay", Const, 0},
+ {"NameDnsDomain", Const, 0},
+ {"NameFullyQualifiedDN", Const, 0},
+ {"NameSamCompatible", Const, 0},
+ {"NameServicePrincipal", Const, 0},
+ {"NameUniqueId", Const, 0},
+ {"NameUnknown", Const, 0},
+ {"NameUserPrincipal", Const, 0},
+ {"Nanosleep", Func, 0},
+ {"NetApiBufferFree", Func, 0},
+ {"NetGetJoinInformation", Func, 2},
+ {"NetSetupDomainName", Const, 2},
+ {"NetSetupUnjoined", Const, 2},
+ {"NetSetupUnknownStatus", Const, 2},
+ {"NetSetupWorkgroupName", Const, 2},
+ {"NetUserGetInfo", Func, 0},
+ {"NetlinkMessage", Type, 0},
+ {"NetlinkMessage.Data", Field, 0},
+ {"NetlinkMessage.Header", Field, 0},
+ {"NetlinkRIB", Func, 0},
+ {"NetlinkRouteAttr", Type, 0},
+ {"NetlinkRouteAttr.Attr", Field, 0},
+ {"NetlinkRouteAttr.Value", Field, 0},
+ {"NetlinkRouteRequest", Type, 0},
+ {"NetlinkRouteRequest.Data", Field, 0},
+ {"NetlinkRouteRequest.Header", Field, 0},
+ {"NewCallback", Func, 0},
+ {"NewCallbackCDecl", Func, 3},
+ {"NewLazyDLL", Func, 0},
+ {"NlAttr", Type, 0},
+ {"NlAttr.Len", Field, 0},
+ {"NlAttr.Type", Field, 0},
+ {"NlMsgerr", Type, 0},
+ {"NlMsgerr.Error", Field, 0},
+ {"NlMsgerr.Msg", Field, 0},
+ {"NlMsghdr", Type, 0},
+ {"NlMsghdr.Flags", Field, 0},
+ {"NlMsghdr.Len", Field, 0},
+ {"NlMsghdr.Pid", Field, 0},
+ {"NlMsghdr.Seq", Field, 0},
+ {"NlMsghdr.Type", Field, 0},
+ {"NsecToFiletime", Func, 0},
+ {"NsecToTimespec", Func, 0},
+ {"NsecToTimeval", Func, 0},
+ {"Ntohs", Func, 0},
+ {"OCRNL", Const, 0},
+ {"OFDEL", Const, 0},
+ {"OFILL", Const, 0},
+ {"OFIOGETBMAP", Const, 1},
+ {"OID_PKIX_KP_SERVER_AUTH", Var, 0},
+ {"OID_SERVER_GATED_CRYPTO", Var, 0},
+ {"OID_SGC_NETSCAPE", Var, 0},
+ {"OLCUC", Const, 0},
+ {"ONLCR", Const, 0},
+ {"ONLRET", Const, 0},
+ {"ONOCR", Const, 0},
+ {"ONOEOT", Const, 1},
+ {"OPEN_ALWAYS", Const, 0},
+ {"OPEN_EXISTING", Const, 0},
+ {"OPOST", Const, 0},
+ {"O_ACCMODE", Const, 0},
+ {"O_ALERT", Const, 0},
+ {"O_ALT_IO", Const, 1},
+ {"O_APPEND", Const, 0},
+ {"O_ASYNC", Const, 0},
+ {"O_CLOEXEC", Const, 0},
+ {"O_CREAT", Const, 0},
+ {"O_DIRECT", Const, 0},
+ {"O_DIRECTORY", Const, 0},
+ {"O_DP_GETRAWENCRYPTED", Const, 16},
+ {"O_DSYNC", Const, 0},
+ {"O_EVTONLY", Const, 0},
+ {"O_EXCL", Const, 0},
+ {"O_EXEC", Const, 0},
+ {"O_EXLOCK", Const, 0},
+ {"O_FSYNC", Const, 0},
+ {"O_LARGEFILE", Const, 0},
+ {"O_NDELAY", Const, 0},
+ {"O_NOATIME", Const, 0},
+ {"O_NOCTTY", Const, 0},
+ {"O_NOFOLLOW", Const, 0},
+ {"O_NONBLOCK", Const, 0},
+ {"O_NOSIGPIPE", Const, 1},
+ {"O_POPUP", Const, 0},
+ {"O_RDONLY", Const, 0},
+ {"O_RDWR", Const, 0},
+ {"O_RSYNC", Const, 0},
+ {"O_SHLOCK", Const, 0},
+ {"O_SYMLINK", Const, 0},
+ {"O_SYNC", Const, 0},
+ {"O_TRUNC", Const, 0},
+ {"O_TTY_INIT", Const, 0},
+ {"O_WRONLY", Const, 0},
+ {"Open", Func, 0},
+ {"OpenCurrentProcessToken", Func, 0},
+ {"OpenProcess", Func, 0},
+ {"OpenProcessToken", Func, 0},
+ {"Openat", Func, 0},
+ {"Overlapped", Type, 0},
+ {"Overlapped.HEvent", Field, 0},
+ {"Overlapped.Internal", Field, 0},
+ {"Overlapped.InternalHigh", Field, 0},
+ {"Overlapped.Offset", Field, 0},
+ {"Overlapped.OffsetHigh", Field, 0},
+ {"PACKET_ADD_MEMBERSHIP", Const, 0},
+ {"PACKET_BROADCAST", Const, 0},
+ {"PACKET_DROP_MEMBERSHIP", Const, 0},
+ {"PACKET_FASTROUTE", Const, 0},
+ {"PACKET_HOST", Const, 0},
+ {"PACKET_LOOPBACK", Const, 0},
+ {"PACKET_MR_ALLMULTI", Const, 0},
+ {"PACKET_MR_MULTICAST", Const, 0},
+ {"PACKET_MR_PROMISC", Const, 0},
+ {"PACKET_MULTICAST", Const, 0},
+ {"PACKET_OTHERHOST", Const, 0},
+ {"PACKET_OUTGOING", Const, 0},
+ {"PACKET_RECV_OUTPUT", Const, 0},
+ {"PACKET_RX_RING", Const, 0},
+ {"PACKET_STATISTICS", Const, 0},
+ {"PAGE_EXECUTE_READ", Const, 0},
+ {"PAGE_EXECUTE_READWRITE", Const, 0},
+ {"PAGE_EXECUTE_WRITECOPY", Const, 0},
+ {"PAGE_READONLY", Const, 0},
+ {"PAGE_READWRITE", Const, 0},
+ {"PAGE_WRITECOPY", Const, 0},
+ {"PARENB", Const, 0},
+ {"PARMRK", Const, 0},
+ {"PARODD", Const, 0},
+ {"PENDIN", Const, 0},
+ {"PFL_HIDDEN", Const, 2},
+ {"PFL_MATCHES_PROTOCOL_ZERO", Const, 2},
+ {"PFL_MULTIPLE_PROTO_ENTRIES", Const, 2},
+ {"PFL_NETWORKDIRECT_PROVIDER", Const, 2},
+ {"PFL_RECOMMENDED_PROTO_ENTRY", Const, 2},
+ {"PF_FLUSH", Const, 1},
+ {"PKCS_7_ASN_ENCODING", Const, 0},
+ {"PMC5_PIPELINE_FLUSH", Const, 1},
+ {"PRIO_PGRP", Const, 2},
+ {"PRIO_PROCESS", Const, 2},
+ {"PRIO_USER", Const, 2},
+ {"PRI_IOFLUSH", Const, 1},
+ {"PROCESS_QUERY_INFORMATION", Const, 0},
+ {"PROCESS_TERMINATE", Const, 2},
+ {"PROT_EXEC", Const, 0},
+ {"PROT_GROWSDOWN", Const, 0},
+ {"PROT_GROWSUP", Const, 0},
+ {"PROT_NONE", Const, 0},
+ {"PROT_READ", Const, 0},
+ {"PROT_WRITE", Const, 0},
+ {"PROV_DH_SCHANNEL", Const, 0},
+ {"PROV_DSS", Const, 0},
+ {"PROV_DSS_DH", Const, 0},
+ {"PROV_EC_ECDSA_FULL", Const, 0},
+ {"PROV_EC_ECDSA_SIG", Const, 0},
+ {"PROV_EC_ECNRA_FULL", Const, 0},
+ {"PROV_EC_ECNRA_SIG", Const, 0},
+ {"PROV_FORTEZZA", Const, 0},
+ {"PROV_INTEL_SEC", Const, 0},
+ {"PROV_MS_EXCHANGE", Const, 0},
+ {"PROV_REPLACE_OWF", Const, 0},
+ {"PROV_RNG", Const, 0},
+ {"PROV_RSA_AES", Const, 0},
+ {"PROV_RSA_FULL", Const, 0},
+ {"PROV_RSA_SCHANNEL", Const, 0},
+ {"PROV_RSA_SIG", Const, 0},
+ {"PROV_SPYRUS_LYNKS", Const, 0},
+ {"PROV_SSL", Const, 0},
+ {"PR_CAPBSET_DROP", Const, 0},
+ {"PR_CAPBSET_READ", Const, 0},
+ {"PR_CLEAR_SECCOMP_FILTER", Const, 0},
+ {"PR_ENDIAN_BIG", Const, 0},
+ {"PR_ENDIAN_LITTLE", Const, 0},
+ {"PR_ENDIAN_PPC_LITTLE", Const, 0},
+ {"PR_FPEMU_NOPRINT", Const, 0},
+ {"PR_FPEMU_SIGFPE", Const, 0},
+ {"PR_FP_EXC_ASYNC", Const, 0},
+ {"PR_FP_EXC_DISABLED", Const, 0},
+ {"PR_FP_EXC_DIV", Const, 0},
+ {"PR_FP_EXC_INV", Const, 0},
+ {"PR_FP_EXC_NONRECOV", Const, 0},
+ {"PR_FP_EXC_OVF", Const, 0},
+ {"PR_FP_EXC_PRECISE", Const, 0},
+ {"PR_FP_EXC_RES", Const, 0},
+ {"PR_FP_EXC_SW_ENABLE", Const, 0},
+ {"PR_FP_EXC_UND", Const, 0},
+ {"PR_GET_DUMPABLE", Const, 0},
+ {"PR_GET_ENDIAN", Const, 0},
+ {"PR_GET_FPEMU", Const, 0},
+ {"PR_GET_FPEXC", Const, 0},
+ {"PR_GET_KEEPCAPS", Const, 0},
+ {"PR_GET_NAME", Const, 0},
+ {"PR_GET_PDEATHSIG", Const, 0},
+ {"PR_GET_SECCOMP", Const, 0},
+ {"PR_GET_SECCOMP_FILTER", Const, 0},
+ {"PR_GET_SECUREBITS", Const, 0},
+ {"PR_GET_TIMERSLACK", Const, 0},
+ {"PR_GET_TIMING", Const, 0},
+ {"PR_GET_TSC", Const, 0},
+ {"PR_GET_UNALIGN", Const, 0},
+ {"PR_MCE_KILL", Const, 0},
+ {"PR_MCE_KILL_CLEAR", Const, 0},
+ {"PR_MCE_KILL_DEFAULT", Const, 0},
+ {"PR_MCE_KILL_EARLY", Const, 0},
+ {"PR_MCE_KILL_GET", Const, 0},
+ {"PR_MCE_KILL_LATE", Const, 0},
+ {"PR_MCE_KILL_SET", Const, 0},
+ {"PR_SECCOMP_FILTER_EVENT", Const, 0},
+ {"PR_SECCOMP_FILTER_SYSCALL", Const, 0},
+ {"PR_SET_DUMPABLE", Const, 0},
+ {"PR_SET_ENDIAN", Const, 0},
+ {"PR_SET_FPEMU", Const, 0},
+ {"PR_SET_FPEXC", Const, 0},
+ {"PR_SET_KEEPCAPS", Const, 0},
+ {"PR_SET_NAME", Const, 0},
+ {"PR_SET_PDEATHSIG", Const, 0},
+ {"PR_SET_PTRACER", Const, 0},
+ {"PR_SET_SECCOMP", Const, 0},
+ {"PR_SET_SECCOMP_FILTER", Const, 0},
+ {"PR_SET_SECUREBITS", Const, 0},
+ {"PR_SET_TIMERSLACK", Const, 0},
+ {"PR_SET_TIMING", Const, 0},
+ {"PR_SET_TSC", Const, 0},
+ {"PR_SET_UNALIGN", Const, 0},
+ {"PR_TASK_PERF_EVENTS_DISABLE", Const, 0},
+ {"PR_TASK_PERF_EVENTS_ENABLE", Const, 0},
+ {"PR_TIMING_STATISTICAL", Const, 0},
+ {"PR_TIMING_TIMESTAMP", Const, 0},
+ {"PR_TSC_ENABLE", Const, 0},
+ {"PR_TSC_SIGSEGV", Const, 0},
+ {"PR_UNALIGN_NOPRINT", Const, 0},
+ {"PR_UNALIGN_SIGBUS", Const, 0},
+ {"PTRACE_ARCH_PRCTL", Const, 0},
+ {"PTRACE_ATTACH", Const, 0},
+ {"PTRACE_CONT", Const, 0},
+ {"PTRACE_DETACH", Const, 0},
+ {"PTRACE_EVENT_CLONE", Const, 0},
+ {"PTRACE_EVENT_EXEC", Const, 0},
+ {"PTRACE_EVENT_EXIT", Const, 0},
+ {"PTRACE_EVENT_FORK", Const, 0},
+ {"PTRACE_EVENT_VFORK", Const, 0},
+ {"PTRACE_EVENT_VFORK_DONE", Const, 0},
+ {"PTRACE_GETCRUNCHREGS", Const, 0},
+ {"PTRACE_GETEVENTMSG", Const, 0},
+ {"PTRACE_GETFPREGS", Const, 0},
+ {"PTRACE_GETFPXREGS", Const, 0},
+ {"PTRACE_GETHBPREGS", Const, 0},
+ {"PTRACE_GETREGS", Const, 0},
+ {"PTRACE_GETREGSET", Const, 0},
+ {"PTRACE_GETSIGINFO", Const, 0},
+ {"PTRACE_GETVFPREGS", Const, 0},
+ {"PTRACE_GETWMMXREGS", Const, 0},
+ {"PTRACE_GET_THREAD_AREA", Const, 0},
+ {"PTRACE_KILL", Const, 0},
+ {"PTRACE_OLDSETOPTIONS", Const, 0},
+ {"PTRACE_O_MASK", Const, 0},
+ {"PTRACE_O_TRACECLONE", Const, 0},
+ {"PTRACE_O_TRACEEXEC", Const, 0},
+ {"PTRACE_O_TRACEEXIT", Const, 0},
+ {"PTRACE_O_TRACEFORK", Const, 0},
+ {"PTRACE_O_TRACESYSGOOD", Const, 0},
+ {"PTRACE_O_TRACEVFORK", Const, 0},
+ {"PTRACE_O_TRACEVFORKDONE", Const, 0},
+ {"PTRACE_PEEKDATA", Const, 0},
+ {"PTRACE_PEEKTEXT", Const, 0},
+ {"PTRACE_PEEKUSR", Const, 0},
+ {"PTRACE_POKEDATA", Const, 0},
+ {"PTRACE_POKETEXT", Const, 0},
+ {"PTRACE_POKEUSR", Const, 0},
+ {"PTRACE_SETCRUNCHREGS", Const, 0},
+ {"PTRACE_SETFPREGS", Const, 0},
+ {"PTRACE_SETFPXREGS", Const, 0},
+ {"PTRACE_SETHBPREGS", Const, 0},
+ {"PTRACE_SETOPTIONS", Const, 0},
+ {"PTRACE_SETREGS", Const, 0},
+ {"PTRACE_SETREGSET", Const, 0},
+ {"PTRACE_SETSIGINFO", Const, 0},
+ {"PTRACE_SETVFPREGS", Const, 0},
+ {"PTRACE_SETWMMXREGS", Const, 0},
+ {"PTRACE_SET_SYSCALL", Const, 0},
+ {"PTRACE_SET_THREAD_AREA", Const, 0},
+ {"PTRACE_SINGLEBLOCK", Const, 0},
+ {"PTRACE_SINGLESTEP", Const, 0},
+ {"PTRACE_SYSCALL", Const, 0},
+ {"PTRACE_SYSEMU", Const, 0},
+ {"PTRACE_SYSEMU_SINGLESTEP", Const, 0},
+ {"PTRACE_TRACEME", Const, 0},
+ {"PT_ATTACH", Const, 0},
+ {"PT_ATTACHEXC", Const, 0},
+ {"PT_CONTINUE", Const, 0},
+ {"PT_DATA_ADDR", Const, 0},
+ {"PT_DENY_ATTACH", Const, 0},
+ {"PT_DETACH", Const, 0},
+ {"PT_FIRSTMACH", Const, 0},
+ {"PT_FORCEQUOTA", Const, 0},
+ {"PT_KILL", Const, 0},
+ {"PT_MASK", Const, 1},
+ {"PT_READ_D", Const, 0},
+ {"PT_READ_I", Const, 0},
+ {"PT_READ_U", Const, 0},
+ {"PT_SIGEXC", Const, 0},
+ {"PT_STEP", Const, 0},
+ {"PT_TEXT_ADDR", Const, 0},
+ {"PT_TEXT_END_ADDR", Const, 0},
+ {"PT_THUPDATE", Const, 0},
+ {"PT_TRACE_ME", Const, 0},
+ {"PT_WRITE_D", Const, 0},
+ {"PT_WRITE_I", Const, 0},
+ {"PT_WRITE_U", Const, 0},
+ {"ParseDirent", Func, 0},
+ {"ParseNetlinkMessage", Func, 0},
+ {"ParseNetlinkRouteAttr", Func, 0},
+ {"ParseRoutingMessage", Func, 0},
+ {"ParseRoutingSockaddr", Func, 0},
+ {"ParseSocketControlMessage", Func, 0},
+ {"ParseUnixCredentials", Func, 0},
+ {"ParseUnixRights", Func, 0},
+ {"PathMax", Const, 0},
+ {"Pathconf", Func, 0},
+ {"Pause", Func, 0},
+ {"Pipe", Func, 0},
+ {"Pipe2", Func, 1},
+ {"PivotRoot", Func, 0},
+ {"Pointer", Type, 11},
+ {"PostQueuedCompletionStatus", Func, 0},
+ {"Pread", Func, 0},
+ {"Proc", Type, 0},
+ {"Proc.Dll", Field, 0},
+ {"Proc.Name", Field, 0},
+ {"ProcAttr", Type, 0},
+ {"ProcAttr.Dir", Field, 0},
+ {"ProcAttr.Env", Field, 0},
+ {"ProcAttr.Files", Field, 0},
+ {"ProcAttr.Sys", Field, 0},
+ {"Process32First", Func, 4},
+ {"Process32Next", Func, 4},
+ {"ProcessEntry32", Type, 4},
+ {"ProcessEntry32.DefaultHeapID", Field, 4},
+ {"ProcessEntry32.ExeFile", Field, 4},
+ {"ProcessEntry32.Flags", Field, 4},
+ {"ProcessEntry32.ModuleID", Field, 4},
+ {"ProcessEntry32.ParentProcessID", Field, 4},
+ {"ProcessEntry32.PriClassBase", Field, 4},
+ {"ProcessEntry32.ProcessID", Field, 4},
+ {"ProcessEntry32.Size", Field, 4},
+ {"ProcessEntry32.Threads", Field, 4},
+ {"ProcessEntry32.Usage", Field, 4},
+ {"ProcessInformation", Type, 0},
+ {"ProcessInformation.Process", Field, 0},
+ {"ProcessInformation.ProcessId", Field, 0},
+ {"ProcessInformation.Thread", Field, 0},
+ {"ProcessInformation.ThreadId", Field, 0},
+ {"Protoent", Type, 0},
+ {"Protoent.Aliases", Field, 0},
+ {"Protoent.Name", Field, 0},
+ {"Protoent.Proto", Field, 0},
+ {"PtraceAttach", Func, 0},
+ {"PtraceCont", Func, 0},
+ {"PtraceDetach", Func, 0},
+ {"PtraceGetEventMsg", Func, 0},
+ {"PtraceGetRegs", Func, 0},
+ {"PtracePeekData", Func, 0},
+ {"PtracePeekText", Func, 0},
+ {"PtracePokeData", Func, 0},
+ {"PtracePokeText", Func, 0},
+ {"PtraceRegs", Type, 0},
+ {"PtraceRegs.Cs", Field, 0},
+ {"PtraceRegs.Ds", Field, 0},
+ {"PtraceRegs.Eax", Field, 0},
+ {"PtraceRegs.Ebp", Field, 0},
+ {"PtraceRegs.Ebx", Field, 0},
+ {"PtraceRegs.Ecx", Field, 0},
+ {"PtraceRegs.Edi", Field, 0},
+ {"PtraceRegs.Edx", Field, 0},
+ {"PtraceRegs.Eflags", Field, 0},
+ {"PtraceRegs.Eip", Field, 0},
+ {"PtraceRegs.Es", Field, 0},
+ {"PtraceRegs.Esi", Field, 0},
+ {"PtraceRegs.Esp", Field, 0},
+ {"PtraceRegs.Fs", Field, 0},
+ {"PtraceRegs.Fs_base", Field, 0},
+ {"PtraceRegs.Gs", Field, 0},
+ {"PtraceRegs.Gs_base", Field, 0},
+ {"PtraceRegs.Orig_eax", Field, 0},
+ {"PtraceRegs.Orig_rax", Field, 0},
+ {"PtraceRegs.R10", Field, 0},
+ {"PtraceRegs.R11", Field, 0},
+ {"PtraceRegs.R12", Field, 0},
+ {"PtraceRegs.R13", Field, 0},
+ {"PtraceRegs.R14", Field, 0},
+ {"PtraceRegs.R15", Field, 0},
+ {"PtraceRegs.R8", Field, 0},
+ {"PtraceRegs.R9", Field, 0},
+ {"PtraceRegs.Rax", Field, 0},
+ {"PtraceRegs.Rbp", Field, 0},
+ {"PtraceRegs.Rbx", Field, 0},
+ {"PtraceRegs.Rcx", Field, 0},
+ {"PtraceRegs.Rdi", Field, 0},
+ {"PtraceRegs.Rdx", Field, 0},
+ {"PtraceRegs.Rip", Field, 0},
+ {"PtraceRegs.Rsi", Field, 0},
+ {"PtraceRegs.Rsp", Field, 0},
+ {"PtraceRegs.Ss", Field, 0},
+ {"PtraceRegs.Uregs", Field, 0},
+ {"PtraceRegs.Xcs", Field, 0},
+ {"PtraceRegs.Xds", Field, 0},
+ {"PtraceRegs.Xes", Field, 0},
+ {"PtraceRegs.Xfs", Field, 0},
+ {"PtraceRegs.Xgs", Field, 0},
+ {"PtraceRegs.Xss", Field, 0},
+ {"PtraceSetOptions", Func, 0},
+ {"PtraceSetRegs", Func, 0},
+ {"PtraceSingleStep", Func, 0},
+ {"PtraceSyscall", Func, 1},
+ {"Pwrite", Func, 0},
+ {"REG_BINARY", Const, 0},
+ {"REG_DWORD", Const, 0},
+ {"REG_DWORD_BIG_ENDIAN", Const, 0},
+ {"REG_DWORD_LITTLE_ENDIAN", Const, 0},
+ {"REG_EXPAND_SZ", Const, 0},
+ {"REG_FULL_RESOURCE_DESCRIPTOR", Const, 0},
+ {"REG_LINK", Const, 0},
+ {"REG_MULTI_SZ", Const, 0},
+ {"REG_NONE", Const, 0},
+ {"REG_QWORD", Const, 0},
+ {"REG_QWORD_LITTLE_ENDIAN", Const, 0},
+ {"REG_RESOURCE_LIST", Const, 0},
+ {"REG_RESOURCE_REQUIREMENTS_LIST", Const, 0},
+ {"REG_SZ", Const, 0},
+ {"RLIMIT_AS", Const, 0},
+ {"RLIMIT_CORE", Const, 0},
+ {"RLIMIT_CPU", Const, 0},
+ {"RLIMIT_CPU_USAGE_MONITOR", Const, 16},
+ {"RLIMIT_DATA", Const, 0},
+ {"RLIMIT_FSIZE", Const, 0},
+ {"RLIMIT_NOFILE", Const, 0},
+ {"RLIMIT_STACK", Const, 0},
+ {"RLIM_INFINITY", Const, 0},
+ {"RTAX_ADVMSS", Const, 0},
+ {"RTAX_AUTHOR", Const, 0},
+ {"RTAX_BRD", Const, 0},
+ {"RTAX_CWND", Const, 0},
+ {"RTAX_DST", Const, 0},
+ {"RTAX_FEATURES", Const, 0},
+ {"RTAX_FEATURE_ALLFRAG", Const, 0},
+ {"RTAX_FEATURE_ECN", Const, 0},
+ {"RTAX_FEATURE_SACK", Const, 0},
+ {"RTAX_FEATURE_TIMESTAMP", Const, 0},
+ {"RTAX_GATEWAY", Const, 0},
+ {"RTAX_GENMASK", Const, 0},
+ {"RTAX_HOPLIMIT", Const, 0},
+ {"RTAX_IFA", Const, 0},
+ {"RTAX_IFP", Const, 0},
+ {"RTAX_INITCWND", Const, 0},
+ {"RTAX_INITRWND", Const, 0},
+ {"RTAX_LABEL", Const, 1},
+ {"RTAX_LOCK", Const, 0},
+ {"RTAX_MAX", Const, 0},
+ {"RTAX_MTU", Const, 0},
+ {"RTAX_NETMASK", Const, 0},
+ {"RTAX_REORDERING", Const, 0},
+ {"RTAX_RTO_MIN", Const, 0},
+ {"RTAX_RTT", Const, 0},
+ {"RTAX_RTTVAR", Const, 0},
+ {"RTAX_SRC", Const, 1},
+ {"RTAX_SRCMASK", Const, 1},
+ {"RTAX_SSTHRESH", Const, 0},
+ {"RTAX_TAG", Const, 1},
+ {"RTAX_UNSPEC", Const, 0},
+ {"RTAX_WINDOW", Const, 0},
+ {"RTA_ALIGNTO", Const, 0},
+ {"RTA_AUTHOR", Const, 0},
+ {"RTA_BRD", Const, 0},
+ {"RTA_CACHEINFO", Const, 0},
+ {"RTA_DST", Const, 0},
+ {"RTA_FLOW", Const, 0},
+ {"RTA_GATEWAY", Const, 0},
+ {"RTA_GENMASK", Const, 0},
+ {"RTA_IFA", Const, 0},
+ {"RTA_IFP", Const, 0},
+ {"RTA_IIF", Const, 0},
+ {"RTA_LABEL", Const, 1},
+ {"RTA_MAX", Const, 0},
+ {"RTA_METRICS", Const, 0},
+ {"RTA_MULTIPATH", Const, 0},
+ {"RTA_NETMASK", Const, 0},
+ {"RTA_OIF", Const, 0},
+ {"RTA_PREFSRC", Const, 0},
+ {"RTA_PRIORITY", Const, 0},
+ {"RTA_SRC", Const, 0},
+ {"RTA_SRCMASK", Const, 1},
+ {"RTA_TABLE", Const, 0},
+ {"RTA_TAG", Const, 1},
+ {"RTA_UNSPEC", Const, 0},
+ {"RTCF_DIRECTSRC", Const, 0},
+ {"RTCF_DOREDIRECT", Const, 0},
+ {"RTCF_LOG", Const, 0},
+ {"RTCF_MASQ", Const, 0},
+ {"RTCF_NAT", Const, 0},
+ {"RTCF_VALVE", Const, 0},
+ {"RTF_ADDRCLASSMASK", Const, 0},
+ {"RTF_ADDRCONF", Const, 0},
+ {"RTF_ALLONLINK", Const, 0},
+ {"RTF_ANNOUNCE", Const, 1},
+ {"RTF_BLACKHOLE", Const, 0},
+ {"RTF_BROADCAST", Const, 0},
+ {"RTF_CACHE", Const, 0},
+ {"RTF_CLONED", Const, 1},
+ {"RTF_CLONING", Const, 0},
+ {"RTF_CONDEMNED", Const, 0},
+ {"RTF_DEFAULT", Const, 0},
+ {"RTF_DELCLONE", Const, 0},
+ {"RTF_DONE", Const, 0},
+ {"RTF_DYNAMIC", Const, 0},
+ {"RTF_FLOW", Const, 0},
+ {"RTF_FMASK", Const, 0},
+ {"RTF_GATEWAY", Const, 0},
+ {"RTF_GWFLAG_COMPAT", Const, 3},
+ {"RTF_HOST", Const, 0},
+ {"RTF_IFREF", Const, 0},
+ {"RTF_IFSCOPE", Const, 0},
+ {"RTF_INTERFACE", Const, 0},
+ {"RTF_IRTT", Const, 0},
+ {"RTF_LINKRT", Const, 0},
+ {"RTF_LLDATA", Const, 0},
+ {"RTF_LLINFO", Const, 0},
+ {"RTF_LOCAL", Const, 0},
+ {"RTF_MASK", Const, 1},
+ {"RTF_MODIFIED", Const, 0},
+ {"RTF_MPATH", Const, 1},
+ {"RTF_MPLS", Const, 1},
+ {"RTF_MSS", Const, 0},
+ {"RTF_MTU", Const, 0},
+ {"RTF_MULTICAST", Const, 0},
+ {"RTF_NAT", Const, 0},
+ {"RTF_NOFORWARD", Const, 0},
+ {"RTF_NONEXTHOP", Const, 0},
+ {"RTF_NOPMTUDISC", Const, 0},
+ {"RTF_PERMANENT_ARP", Const, 1},
+ {"RTF_PINNED", Const, 0},
+ {"RTF_POLICY", Const, 0},
+ {"RTF_PRCLONING", Const, 0},
+ {"RTF_PROTO1", Const, 0},
+ {"RTF_PROTO2", Const, 0},
+ {"RTF_PROTO3", Const, 0},
+ {"RTF_PROXY", Const, 16},
+ {"RTF_REINSTATE", Const, 0},
+ {"RTF_REJECT", Const, 0},
+ {"RTF_RNH_LOCKED", Const, 0},
+ {"RTF_ROUTER", Const, 16},
+ {"RTF_SOURCE", Const, 1},
+ {"RTF_SRC", Const, 1},
+ {"RTF_STATIC", Const, 0},
+ {"RTF_STICKY", Const, 0},
+ {"RTF_THROW", Const, 0},
+ {"RTF_TUNNEL", Const, 1},
+ {"RTF_UP", Const, 0},
+ {"RTF_USETRAILERS", Const, 1},
+ {"RTF_WASCLONED", Const, 0},
+ {"RTF_WINDOW", Const, 0},
+ {"RTF_XRESOLVE", Const, 0},
+ {"RTM_ADD", Const, 0},
+ {"RTM_BASE", Const, 0},
+ {"RTM_CHANGE", Const, 0},
+ {"RTM_CHGADDR", Const, 1},
+ {"RTM_DELACTION", Const, 0},
+ {"RTM_DELADDR", Const, 0},
+ {"RTM_DELADDRLABEL", Const, 0},
+ {"RTM_DELETE", Const, 0},
+ {"RTM_DELLINK", Const, 0},
+ {"RTM_DELMADDR", Const, 0},
+ {"RTM_DELNEIGH", Const, 0},
+ {"RTM_DELQDISC", Const, 0},
+ {"RTM_DELROUTE", Const, 0},
+ {"RTM_DELRULE", Const, 0},
+ {"RTM_DELTCLASS", Const, 0},
+ {"RTM_DELTFILTER", Const, 0},
+ {"RTM_DESYNC", Const, 1},
+ {"RTM_F_CLONED", Const, 0},
+ {"RTM_F_EQUALIZE", Const, 0},
+ {"RTM_F_NOTIFY", Const, 0},
+ {"RTM_F_PREFIX", Const, 0},
+ {"RTM_GET", Const, 0},
+ {"RTM_GET2", Const, 0},
+ {"RTM_GETACTION", Const, 0},
+ {"RTM_GETADDR", Const, 0},
+ {"RTM_GETADDRLABEL", Const, 0},
+ {"RTM_GETANYCAST", Const, 0},
+ {"RTM_GETDCB", Const, 0},
+ {"RTM_GETLINK", Const, 0},
+ {"RTM_GETMULTICAST", Const, 0},
+ {"RTM_GETNEIGH", Const, 0},
+ {"RTM_GETNEIGHTBL", Const, 0},
+ {"RTM_GETQDISC", Const, 0},
+ {"RTM_GETROUTE", Const, 0},
+ {"RTM_GETRULE", Const, 0},
+ {"RTM_GETTCLASS", Const, 0},
+ {"RTM_GETTFILTER", Const, 0},
+ {"RTM_IEEE80211", Const, 0},
+ {"RTM_IFANNOUNCE", Const, 0},
+ {"RTM_IFINFO", Const, 0},
+ {"RTM_IFINFO2", Const, 0},
+ {"RTM_LLINFO_UPD", Const, 1},
+ {"RTM_LOCK", Const, 0},
+ {"RTM_LOSING", Const, 0},
+ {"RTM_MAX", Const, 0},
+ {"RTM_MAXSIZE", Const, 1},
+ {"RTM_MISS", Const, 0},
+ {"RTM_NEWACTION", Const, 0},
+ {"RTM_NEWADDR", Const, 0},
+ {"RTM_NEWADDRLABEL", Const, 0},
+ {"RTM_NEWLINK", Const, 0},
+ {"RTM_NEWMADDR", Const, 0},
+ {"RTM_NEWMADDR2", Const, 0},
+ {"RTM_NEWNDUSEROPT", Const, 0},
+ {"RTM_NEWNEIGH", Const, 0},
+ {"RTM_NEWNEIGHTBL", Const, 0},
+ {"RTM_NEWPREFIX", Const, 0},
+ {"RTM_NEWQDISC", Const, 0},
+ {"RTM_NEWROUTE", Const, 0},
+ {"RTM_NEWRULE", Const, 0},
+ {"RTM_NEWTCLASS", Const, 0},
+ {"RTM_NEWTFILTER", Const, 0},
+ {"RTM_NR_FAMILIES", Const, 0},
+ {"RTM_NR_MSGTYPES", Const, 0},
+ {"RTM_OIFINFO", Const, 1},
+ {"RTM_OLDADD", Const, 0},
+ {"RTM_OLDDEL", Const, 0},
+ {"RTM_OOIFINFO", Const, 1},
+ {"RTM_REDIRECT", Const, 0},
+ {"RTM_RESOLVE", Const, 0},
+ {"RTM_RTTUNIT", Const, 0},
+ {"RTM_SETDCB", Const, 0},
+ {"RTM_SETGATE", Const, 1},
+ {"RTM_SETLINK", Const, 0},
+ {"RTM_SETNEIGHTBL", Const, 0},
+ {"RTM_VERSION", Const, 0},
+ {"RTNH_ALIGNTO", Const, 0},
+ {"RTNH_F_DEAD", Const, 0},
+ {"RTNH_F_ONLINK", Const, 0},
+ {"RTNH_F_PERVASIVE", Const, 0},
+ {"RTNLGRP_IPV4_IFADDR", Const, 1},
+ {"RTNLGRP_IPV4_MROUTE", Const, 1},
+ {"RTNLGRP_IPV4_ROUTE", Const, 1},
+ {"RTNLGRP_IPV4_RULE", Const, 1},
+ {"RTNLGRP_IPV6_IFADDR", Const, 1},
+ {"RTNLGRP_IPV6_IFINFO", Const, 1},
+ {"RTNLGRP_IPV6_MROUTE", Const, 1},
+ {"RTNLGRP_IPV6_PREFIX", Const, 1},
+ {"RTNLGRP_IPV6_ROUTE", Const, 1},
+ {"RTNLGRP_IPV6_RULE", Const, 1},
+ {"RTNLGRP_LINK", Const, 1},
+ {"RTNLGRP_ND_USEROPT", Const, 1},
+ {"RTNLGRP_NEIGH", Const, 1},
+ {"RTNLGRP_NONE", Const, 1},
+ {"RTNLGRP_NOTIFY", Const, 1},
+ {"RTNLGRP_TC", Const, 1},
+ {"RTN_ANYCAST", Const, 0},
+ {"RTN_BLACKHOLE", Const, 0},
+ {"RTN_BROADCAST", Const, 0},
+ {"RTN_LOCAL", Const, 0},
+ {"RTN_MAX", Const, 0},
+ {"RTN_MULTICAST", Const, 0},
+ {"RTN_NAT", Const, 0},
+ {"RTN_PROHIBIT", Const, 0},
+ {"RTN_THROW", Const, 0},
+ {"RTN_UNICAST", Const, 0},
+ {"RTN_UNREACHABLE", Const, 0},
+ {"RTN_UNSPEC", Const, 0},
+ {"RTN_XRESOLVE", Const, 0},
+ {"RTPROT_BIRD", Const, 0},
+ {"RTPROT_BOOT", Const, 0},
+ {"RTPROT_DHCP", Const, 0},
+ {"RTPROT_DNROUTED", Const, 0},
+ {"RTPROT_GATED", Const, 0},
+ {"RTPROT_KERNEL", Const, 0},
+ {"RTPROT_MRT", Const, 0},
+ {"RTPROT_NTK", Const, 0},
+ {"RTPROT_RA", Const, 0},
+ {"RTPROT_REDIRECT", Const, 0},
+ {"RTPROT_STATIC", Const, 0},
+ {"RTPROT_UNSPEC", Const, 0},
+ {"RTPROT_XORP", Const, 0},
+ {"RTPROT_ZEBRA", Const, 0},
+ {"RTV_EXPIRE", Const, 0},
+ {"RTV_HOPCOUNT", Const, 0},
+ {"RTV_MTU", Const, 0},
+ {"RTV_RPIPE", Const, 0},
+ {"RTV_RTT", Const, 0},
+ {"RTV_RTTVAR", Const, 0},
+ {"RTV_SPIPE", Const, 0},
+ {"RTV_SSTHRESH", Const, 0},
+ {"RTV_WEIGHT", Const, 0},
+ {"RT_CACHING_CONTEXT", Const, 1},
+ {"RT_CLASS_DEFAULT", Const, 0},
+ {"RT_CLASS_LOCAL", Const, 0},
+ {"RT_CLASS_MAIN", Const, 0},
+ {"RT_CLASS_MAX", Const, 0},
+ {"RT_CLASS_UNSPEC", Const, 0},
+ {"RT_DEFAULT_FIB", Const, 1},
+ {"RT_NORTREF", Const, 1},
+ {"RT_SCOPE_HOST", Const, 0},
+ {"RT_SCOPE_LINK", Const, 0},
+ {"RT_SCOPE_NOWHERE", Const, 0},
+ {"RT_SCOPE_SITE", Const, 0},
+ {"RT_SCOPE_UNIVERSE", Const, 0},
+ {"RT_TABLEID_MAX", Const, 1},
+ {"RT_TABLE_COMPAT", Const, 0},
+ {"RT_TABLE_DEFAULT", Const, 0},
+ {"RT_TABLE_LOCAL", Const, 0},
+ {"RT_TABLE_MAIN", Const, 0},
+ {"RT_TABLE_MAX", Const, 0},
+ {"RT_TABLE_UNSPEC", Const, 0},
+ {"RUSAGE_CHILDREN", Const, 0},
+ {"RUSAGE_SELF", Const, 0},
+ {"RUSAGE_THREAD", Const, 0},
+ {"Radvisory_t", Type, 0},
+ {"Radvisory_t.Count", Field, 0},
+ {"Radvisory_t.Offset", Field, 0},
+ {"Radvisory_t.Pad_cgo_0", Field, 0},
+ {"RawConn", Type, 9},
+ {"RawSockaddr", Type, 0},
+ {"RawSockaddr.Data", Field, 0},
+ {"RawSockaddr.Family", Field, 0},
+ {"RawSockaddr.Len", Field, 0},
+ {"RawSockaddrAny", Type, 0},
+ {"RawSockaddrAny.Addr", Field, 0},
+ {"RawSockaddrAny.Pad", Field, 0},
+ {"RawSockaddrDatalink", Type, 0},
+ {"RawSockaddrDatalink.Alen", Field, 0},
+ {"RawSockaddrDatalink.Data", Field, 0},
+ {"RawSockaddrDatalink.Family", Field, 0},
+ {"RawSockaddrDatalink.Index", Field, 0},
+ {"RawSockaddrDatalink.Len", Field, 0},
+ {"RawSockaddrDatalink.Nlen", Field, 0},
+ {"RawSockaddrDatalink.Pad_cgo_0", Field, 2},
+ {"RawSockaddrDatalink.Slen", Field, 0},
+ {"RawSockaddrDatalink.Type", Field, 0},
+ {"RawSockaddrInet4", Type, 0},
+ {"RawSockaddrInet4.Addr", Field, 0},
+ {"RawSockaddrInet4.Family", Field, 0},
+ {"RawSockaddrInet4.Len", Field, 0},
+ {"RawSockaddrInet4.Port", Field, 0},
+ {"RawSockaddrInet4.Zero", Field, 0},
+ {"RawSockaddrInet6", Type, 0},
+ {"RawSockaddrInet6.Addr", Field, 0},
+ {"RawSockaddrInet6.Family", Field, 0},
+ {"RawSockaddrInet6.Flowinfo", Field, 0},
+ {"RawSockaddrInet6.Len", Field, 0},
+ {"RawSockaddrInet6.Port", Field, 0},
+ {"RawSockaddrInet6.Scope_id", Field, 0},
+ {"RawSockaddrLinklayer", Type, 0},
+ {"RawSockaddrLinklayer.Addr", Field, 0},
+ {"RawSockaddrLinklayer.Family", Field, 0},
+ {"RawSockaddrLinklayer.Halen", Field, 0},
+ {"RawSockaddrLinklayer.Hatype", Field, 0},
+ {"RawSockaddrLinklayer.Ifindex", Field, 0},
+ {"RawSockaddrLinklayer.Pkttype", Field, 0},
+ {"RawSockaddrLinklayer.Protocol", Field, 0},
+ {"RawSockaddrNetlink", Type, 0},
+ {"RawSockaddrNetlink.Family", Field, 0},
+ {"RawSockaddrNetlink.Groups", Field, 0},
+ {"RawSockaddrNetlink.Pad", Field, 0},
+ {"RawSockaddrNetlink.Pid", Field, 0},
+ {"RawSockaddrUnix", Type, 0},
+ {"RawSockaddrUnix.Family", Field, 0},
+ {"RawSockaddrUnix.Len", Field, 0},
+ {"RawSockaddrUnix.Pad_cgo_0", Field, 2},
+ {"RawSockaddrUnix.Path", Field, 0},
+ {"RawSyscall", Func, 0},
+ {"RawSyscall6", Func, 0},
+ {"Read", Func, 0},
+ {"ReadConsole", Func, 1},
+ {"ReadDirectoryChanges", Func, 0},
+ {"ReadDirent", Func, 0},
+ {"ReadFile", Func, 0},
+ {"Readlink", Func, 0},
+ {"Reboot", Func, 0},
+ {"Recvfrom", Func, 0},
+ {"Recvmsg", Func, 0},
+ {"RegCloseKey", Func, 0},
+ {"RegEnumKeyEx", Func, 0},
+ {"RegOpenKeyEx", Func, 0},
+ {"RegQueryInfoKey", Func, 0},
+ {"RegQueryValueEx", Func, 0},
+ {"RemoveDirectory", Func, 0},
+ {"Removexattr", Func, 1},
+ {"Rename", Func, 0},
+ {"Renameat", Func, 0},
+ {"Revoke", Func, 0},
+ {"Rlimit", Type, 0},
+ {"Rlimit.Cur", Field, 0},
+ {"Rlimit.Max", Field, 0},
+ {"Rmdir", Func, 0},
+ {"RouteMessage", Type, 0},
+ {"RouteMessage.Data", Field, 0},
+ {"RouteMessage.Header", Field, 0},
+ {"RouteRIB", Func, 0},
+ {"RoutingMessage", Type, 0},
+ {"RtAttr", Type, 0},
+ {"RtAttr.Len", Field, 0},
+ {"RtAttr.Type", Field, 0},
+ {"RtGenmsg", Type, 0},
+ {"RtGenmsg.Family", Field, 0},
+ {"RtMetrics", Type, 0},
+ {"RtMetrics.Expire", Field, 0},
+ {"RtMetrics.Filler", Field, 0},
+ {"RtMetrics.Hopcount", Field, 0},
+ {"RtMetrics.Locks", Field, 0},
+ {"RtMetrics.Mtu", Field, 0},
+ {"RtMetrics.Pad", Field, 3},
+ {"RtMetrics.Pksent", Field, 0},
+ {"RtMetrics.Recvpipe", Field, 0},
+ {"RtMetrics.Refcnt", Field, 2},
+ {"RtMetrics.Rtt", Field, 0},
+ {"RtMetrics.Rttvar", Field, 0},
+ {"RtMetrics.Sendpipe", Field, 0},
+ {"RtMetrics.Ssthresh", Field, 0},
+ {"RtMetrics.Weight", Field, 0},
+ {"RtMsg", Type, 0},
+ {"RtMsg.Dst_len", Field, 0},
+ {"RtMsg.Family", Field, 0},
+ {"RtMsg.Flags", Field, 0},
+ {"RtMsg.Protocol", Field, 0},
+ {"RtMsg.Scope", Field, 0},
+ {"RtMsg.Src_len", Field, 0},
+ {"RtMsg.Table", Field, 0},
+ {"RtMsg.Tos", Field, 0},
+ {"RtMsg.Type", Field, 0},
+ {"RtMsghdr", Type, 0},
+ {"RtMsghdr.Addrs", Field, 0},
+ {"RtMsghdr.Errno", Field, 0},
+ {"RtMsghdr.Flags", Field, 0},
+ {"RtMsghdr.Fmask", Field, 0},
+ {"RtMsghdr.Hdrlen", Field, 2},
+ {"RtMsghdr.Index", Field, 0},
+ {"RtMsghdr.Inits", Field, 0},
+ {"RtMsghdr.Mpls", Field, 2},
+ {"RtMsghdr.Msglen", Field, 0},
+ {"RtMsghdr.Pad_cgo_0", Field, 0},
+ {"RtMsghdr.Pad_cgo_1", Field, 2},
+ {"RtMsghdr.Pid", Field, 0},
+ {"RtMsghdr.Priority", Field, 2},
+ {"RtMsghdr.Rmx", Field, 0},
+ {"RtMsghdr.Seq", Field, 0},
+ {"RtMsghdr.Tableid", Field, 2},
+ {"RtMsghdr.Type", Field, 0},
+ {"RtMsghdr.Use", Field, 0},
+ {"RtMsghdr.Version", Field, 0},
+ {"RtNexthop", Type, 0},
+ {"RtNexthop.Flags", Field, 0},
+ {"RtNexthop.Hops", Field, 0},
+ {"RtNexthop.Ifindex", Field, 0},
+ {"RtNexthop.Len", Field, 0},
+ {"Rusage", Type, 0},
+ {"Rusage.CreationTime", Field, 0},
+ {"Rusage.ExitTime", Field, 0},
+ {"Rusage.Idrss", Field, 0},
+ {"Rusage.Inblock", Field, 0},
+ {"Rusage.Isrss", Field, 0},
+ {"Rusage.Ixrss", Field, 0},
+ {"Rusage.KernelTime", Field, 0},
+ {"Rusage.Majflt", Field, 0},
+ {"Rusage.Maxrss", Field, 0},
+ {"Rusage.Minflt", Field, 0},
+ {"Rusage.Msgrcv", Field, 0},
+ {"Rusage.Msgsnd", Field, 0},
+ {"Rusage.Nivcsw", Field, 0},
+ {"Rusage.Nsignals", Field, 0},
+ {"Rusage.Nswap", Field, 0},
+ {"Rusage.Nvcsw", Field, 0},
+ {"Rusage.Oublock", Field, 0},
+ {"Rusage.Stime", Field, 0},
+ {"Rusage.UserTime", Field, 0},
+ {"Rusage.Utime", Field, 0},
+ {"SCM_BINTIME", Const, 0},
+ {"SCM_CREDENTIALS", Const, 0},
+ {"SCM_CREDS", Const, 0},
+ {"SCM_RIGHTS", Const, 0},
+ {"SCM_TIMESTAMP", Const, 0},
+ {"SCM_TIMESTAMPING", Const, 0},
+ {"SCM_TIMESTAMPNS", Const, 0},
+ {"SCM_TIMESTAMP_MONOTONIC", Const, 0},
+ {"SHUT_RD", Const, 0},
+ {"SHUT_RDWR", Const, 0},
+ {"SHUT_WR", Const, 0},
+ {"SID", Type, 0},
+ {"SIDAndAttributes", Type, 0},
+ {"SIDAndAttributes.Attributes", Field, 0},
+ {"SIDAndAttributes.Sid", Field, 0},
+ {"SIGABRT", Const, 0},
+ {"SIGALRM", Const, 0},
+ {"SIGBUS", Const, 0},
+ {"SIGCHLD", Const, 0},
+ {"SIGCLD", Const, 0},
+ {"SIGCONT", Const, 0},
+ {"SIGEMT", Const, 0},
+ {"SIGFPE", Const, 0},
+ {"SIGHUP", Const, 0},
+ {"SIGILL", Const, 0},
+ {"SIGINFO", Const, 0},
+ {"SIGINT", Const, 0},
+ {"SIGIO", Const, 0},
+ {"SIGIOT", Const, 0},
+ {"SIGKILL", Const, 0},
+ {"SIGLIBRT", Const, 1},
+ {"SIGLWP", Const, 0},
+ {"SIGPIPE", Const, 0},
+ {"SIGPOLL", Const, 0},
+ {"SIGPROF", Const, 0},
+ {"SIGPWR", Const, 0},
+ {"SIGQUIT", Const, 0},
+ {"SIGSEGV", Const, 0},
+ {"SIGSTKFLT", Const, 0},
+ {"SIGSTOP", Const, 0},
+ {"SIGSYS", Const, 0},
+ {"SIGTERM", Const, 0},
+ {"SIGTHR", Const, 0},
+ {"SIGTRAP", Const, 0},
+ {"SIGTSTP", Const, 0},
+ {"SIGTTIN", Const, 0},
+ {"SIGTTOU", Const, 0},
+ {"SIGUNUSED", Const, 0},
+ {"SIGURG", Const, 0},
+ {"SIGUSR1", Const, 0},
+ {"SIGUSR2", Const, 0},
+ {"SIGVTALRM", Const, 0},
+ {"SIGWINCH", Const, 0},
+ {"SIGXCPU", Const, 0},
+ {"SIGXFSZ", Const, 0},
+ {"SIOCADDDLCI", Const, 0},
+ {"SIOCADDMULTI", Const, 0},
+ {"SIOCADDRT", Const, 0},
+ {"SIOCAIFADDR", Const, 0},
+ {"SIOCAIFGROUP", Const, 0},
+ {"SIOCALIFADDR", Const, 0},
+ {"SIOCARPIPLL", Const, 0},
+ {"SIOCATMARK", Const, 0},
+ {"SIOCAUTOADDR", Const, 0},
+ {"SIOCAUTONETMASK", Const, 0},
+ {"SIOCBRDGADD", Const, 1},
+ {"SIOCBRDGADDS", Const, 1},
+ {"SIOCBRDGARL", Const, 1},
+ {"SIOCBRDGDADDR", Const, 1},
+ {"SIOCBRDGDEL", Const, 1},
+ {"SIOCBRDGDELS", Const, 1},
+ {"SIOCBRDGFLUSH", Const, 1},
+ {"SIOCBRDGFRL", Const, 1},
+ {"SIOCBRDGGCACHE", Const, 1},
+ {"SIOCBRDGGFD", Const, 1},
+ {"SIOCBRDGGHT", Const, 1},
+ {"SIOCBRDGGIFFLGS", Const, 1},
+ {"SIOCBRDGGMA", Const, 1},
+ {"SIOCBRDGGPARAM", Const, 1},
+ {"SIOCBRDGGPRI", Const, 1},
+ {"SIOCBRDGGRL", Const, 1},
+ {"SIOCBRDGGSIFS", Const, 1},
+ {"SIOCBRDGGTO", Const, 1},
+ {"SIOCBRDGIFS", Const, 1},
+ {"SIOCBRDGRTS", Const, 1},
+ {"SIOCBRDGSADDR", Const, 1},
+ {"SIOCBRDGSCACHE", Const, 1},
+ {"SIOCBRDGSFD", Const, 1},
+ {"SIOCBRDGSHT", Const, 1},
+ {"SIOCBRDGSIFCOST", Const, 1},
+ {"SIOCBRDGSIFFLGS", Const, 1},
+ {"SIOCBRDGSIFPRIO", Const, 1},
+ {"SIOCBRDGSMA", Const, 1},
+ {"SIOCBRDGSPRI", Const, 1},
+ {"SIOCBRDGSPROTO", Const, 1},
+ {"SIOCBRDGSTO", Const, 1},
+ {"SIOCBRDGSTXHC", Const, 1},
+ {"SIOCDARP", Const, 0},
+ {"SIOCDELDLCI", Const, 0},
+ {"SIOCDELMULTI", Const, 0},
+ {"SIOCDELRT", Const, 0},
+ {"SIOCDEVPRIVATE", Const, 0},
+ {"SIOCDIFADDR", Const, 0},
+ {"SIOCDIFGROUP", Const, 0},
+ {"SIOCDIFPHYADDR", Const, 0},
+ {"SIOCDLIFADDR", Const, 0},
+ {"SIOCDRARP", Const, 0},
+ {"SIOCGARP", Const, 0},
+ {"SIOCGDRVSPEC", Const, 0},
+ {"SIOCGETKALIVE", Const, 1},
+ {"SIOCGETLABEL", Const, 1},
+ {"SIOCGETPFLOW", Const, 1},
+ {"SIOCGETPFSYNC", Const, 1},
+ {"SIOCGETSGCNT", Const, 0},
+ {"SIOCGETVIFCNT", Const, 0},
+ {"SIOCGETVLAN", Const, 0},
+ {"SIOCGHIWAT", Const, 0},
+ {"SIOCGIFADDR", Const, 0},
+ {"SIOCGIFADDRPREF", Const, 1},
+ {"SIOCGIFALIAS", Const, 1},
+ {"SIOCGIFALTMTU", Const, 0},
+ {"SIOCGIFASYNCMAP", Const, 0},
+ {"SIOCGIFBOND", Const, 0},
+ {"SIOCGIFBR", Const, 0},
+ {"SIOCGIFBRDADDR", Const, 0},
+ {"SIOCGIFCAP", Const, 0},
+ {"SIOCGIFCONF", Const, 0},
+ {"SIOCGIFCOUNT", Const, 0},
+ {"SIOCGIFDATA", Const, 1},
+ {"SIOCGIFDESCR", Const, 0},
+ {"SIOCGIFDEVMTU", Const, 0},
+ {"SIOCGIFDLT", Const, 1},
+ {"SIOCGIFDSTADDR", Const, 0},
+ {"SIOCGIFENCAP", Const, 0},
+ {"SIOCGIFFIB", Const, 1},
+ {"SIOCGIFFLAGS", Const, 0},
+ {"SIOCGIFGATTR", Const, 1},
+ {"SIOCGIFGENERIC", Const, 0},
+ {"SIOCGIFGMEMB", Const, 0},
+ {"SIOCGIFGROUP", Const, 0},
+ {"SIOCGIFHARDMTU", Const, 3},
+ {"SIOCGIFHWADDR", Const, 0},
+ {"SIOCGIFINDEX", Const, 0},
+ {"SIOCGIFKPI", Const, 0},
+ {"SIOCGIFMAC", Const, 0},
+ {"SIOCGIFMAP", Const, 0},
+ {"SIOCGIFMEDIA", Const, 0},
+ {"SIOCGIFMEM", Const, 0},
+ {"SIOCGIFMETRIC", Const, 0},
+ {"SIOCGIFMTU", Const, 0},
+ {"SIOCGIFNAME", Const, 0},
+ {"SIOCGIFNETMASK", Const, 0},
+ {"SIOCGIFPDSTADDR", Const, 0},
+ {"SIOCGIFPFLAGS", Const, 0},
+ {"SIOCGIFPHYS", Const, 0},
+ {"SIOCGIFPRIORITY", Const, 1},
+ {"SIOCGIFPSRCADDR", Const, 0},
+ {"SIOCGIFRDOMAIN", Const, 1},
+ {"SIOCGIFRTLABEL", Const, 1},
+ {"SIOCGIFSLAVE", Const, 0},
+ {"SIOCGIFSTATUS", Const, 0},
+ {"SIOCGIFTIMESLOT", Const, 1},
+ {"SIOCGIFTXQLEN", Const, 0},
+ {"SIOCGIFVLAN", Const, 0},
+ {"SIOCGIFWAKEFLAGS", Const, 0},
+ {"SIOCGIFXFLAGS", Const, 1},
+ {"SIOCGLIFADDR", Const, 0},
+ {"SIOCGLIFPHYADDR", Const, 0},
+ {"SIOCGLIFPHYRTABLE", Const, 1},
+ {"SIOCGLIFPHYTTL", Const, 3},
+ {"SIOCGLINKSTR", Const, 1},
+ {"SIOCGLOWAT", Const, 0},
+ {"SIOCGPGRP", Const, 0},
+ {"SIOCGPRIVATE_0", Const, 0},
+ {"SIOCGPRIVATE_1", Const, 0},
+ {"SIOCGRARP", Const, 0},
+ {"SIOCGSPPPPARAMS", Const, 3},
+ {"SIOCGSTAMP", Const, 0},
+ {"SIOCGSTAMPNS", Const, 0},
+ {"SIOCGVH", Const, 1},
+ {"SIOCGVNETID", Const, 3},
+ {"SIOCIFCREATE", Const, 0},
+ {"SIOCIFCREATE2", Const, 0},
+ {"SIOCIFDESTROY", Const, 0},
+ {"SIOCIFGCLONERS", Const, 0},
+ {"SIOCINITIFADDR", Const, 1},
+ {"SIOCPROTOPRIVATE", Const, 0},
+ {"SIOCRSLVMULTI", Const, 0},
+ {"SIOCRTMSG", Const, 0},
+ {"SIOCSARP", Const, 0},
+ {"SIOCSDRVSPEC", Const, 0},
+ {"SIOCSETKALIVE", Const, 1},
+ {"SIOCSETLABEL", Const, 1},
+ {"SIOCSETPFLOW", Const, 1},
+ {"SIOCSETPFSYNC", Const, 1},
+ {"SIOCSETVLAN", Const, 0},
+ {"SIOCSHIWAT", Const, 0},
+ {"SIOCSIFADDR", Const, 0},
+ {"SIOCSIFADDRPREF", Const, 1},
+ {"SIOCSIFALTMTU", Const, 0},
+ {"SIOCSIFASYNCMAP", Const, 0},
+ {"SIOCSIFBOND", Const, 0},
+ {"SIOCSIFBR", Const, 0},
+ {"SIOCSIFBRDADDR", Const, 0},
+ {"SIOCSIFCAP", Const, 0},
+ {"SIOCSIFDESCR", Const, 0},
+ {"SIOCSIFDSTADDR", Const, 0},
+ {"SIOCSIFENCAP", Const, 0},
+ {"SIOCSIFFIB", Const, 1},
+ {"SIOCSIFFLAGS", Const, 0},
+ {"SIOCSIFGATTR", Const, 1},
+ {"SIOCSIFGENERIC", Const, 0},
+ {"SIOCSIFHWADDR", Const, 0},
+ {"SIOCSIFHWBROADCAST", Const, 0},
+ {"SIOCSIFKPI", Const, 0},
+ {"SIOCSIFLINK", Const, 0},
+ {"SIOCSIFLLADDR", Const, 0},
+ {"SIOCSIFMAC", Const, 0},
+ {"SIOCSIFMAP", Const, 0},
+ {"SIOCSIFMEDIA", Const, 0},
+ {"SIOCSIFMEM", Const, 0},
+ {"SIOCSIFMETRIC", Const, 0},
+ {"SIOCSIFMTU", Const, 0},
+ {"SIOCSIFNAME", Const, 0},
+ {"SIOCSIFNETMASK", Const, 0},
+ {"SIOCSIFPFLAGS", Const, 0},
+ {"SIOCSIFPHYADDR", Const, 0},
+ {"SIOCSIFPHYS", Const, 0},
+ {"SIOCSIFPRIORITY", Const, 1},
+ {"SIOCSIFRDOMAIN", Const, 1},
+ {"SIOCSIFRTLABEL", Const, 1},
+ {"SIOCSIFRVNET", Const, 0},
+ {"SIOCSIFSLAVE", Const, 0},
+ {"SIOCSIFTIMESLOT", Const, 1},
+ {"SIOCSIFTXQLEN", Const, 0},
+ {"SIOCSIFVLAN", Const, 0},
+ {"SIOCSIFVNET", Const, 0},
+ {"SIOCSIFXFLAGS", Const, 1},
+ {"SIOCSLIFPHYADDR", Const, 0},
+ {"SIOCSLIFPHYRTABLE", Const, 1},
+ {"SIOCSLIFPHYTTL", Const, 3},
+ {"SIOCSLINKSTR", Const, 1},
+ {"SIOCSLOWAT", Const, 0},
+ {"SIOCSPGRP", Const, 0},
+ {"SIOCSRARP", Const, 0},
+ {"SIOCSSPPPPARAMS", Const, 3},
+ {"SIOCSVH", Const, 1},
+ {"SIOCSVNETID", Const, 3},
+ {"SIOCZIFDATA", Const, 1},
+ {"SIO_GET_EXTENSION_FUNCTION_POINTER", Const, 1},
+ {"SIO_GET_INTERFACE_LIST", Const, 0},
+ {"SIO_KEEPALIVE_VALS", Const, 3},
+ {"SIO_UDP_CONNRESET", Const, 4},
+ {"SOCK_CLOEXEC", Const, 0},
+ {"SOCK_DCCP", Const, 0},
+ {"SOCK_DGRAM", Const, 0},
+ {"SOCK_FLAGS_MASK", Const, 1},
+ {"SOCK_MAXADDRLEN", Const, 0},
+ {"SOCK_NONBLOCK", Const, 0},
+ {"SOCK_NOSIGPIPE", Const, 1},
+ {"SOCK_PACKET", Const, 0},
+ {"SOCK_RAW", Const, 0},
+ {"SOCK_RDM", Const, 0},
+ {"SOCK_SEQPACKET", Const, 0},
+ {"SOCK_STREAM", Const, 0},
+ {"SOL_AAL", Const, 0},
+ {"SOL_ATM", Const, 0},
+ {"SOL_DECNET", Const, 0},
+ {"SOL_ICMPV6", Const, 0},
+ {"SOL_IP", Const, 0},
+ {"SOL_IPV6", Const, 0},
+ {"SOL_IRDA", Const, 0},
+ {"SOL_PACKET", Const, 0},
+ {"SOL_RAW", Const, 0},
+ {"SOL_SOCKET", Const, 0},
+ {"SOL_TCP", Const, 0},
+ {"SOL_X25", Const, 0},
+ {"SOMAXCONN", Const, 0},
+ {"SO_ACCEPTCONN", Const, 0},
+ {"SO_ACCEPTFILTER", Const, 0},
+ {"SO_ATTACH_FILTER", Const, 0},
+ {"SO_BINDANY", Const, 1},
+ {"SO_BINDTODEVICE", Const, 0},
+ {"SO_BINTIME", Const, 0},
+ {"SO_BROADCAST", Const, 0},
+ {"SO_BSDCOMPAT", Const, 0},
+ {"SO_DEBUG", Const, 0},
+ {"SO_DETACH_FILTER", Const, 0},
+ {"SO_DOMAIN", Const, 0},
+ {"SO_DONTROUTE", Const, 0},
+ {"SO_DONTTRUNC", Const, 0},
+ {"SO_ERROR", Const, 0},
+ {"SO_KEEPALIVE", Const, 0},
+ {"SO_LABEL", Const, 0},
+ {"SO_LINGER", Const, 0},
+ {"SO_LINGER_SEC", Const, 0},
+ {"SO_LISTENINCQLEN", Const, 0},
+ {"SO_LISTENQLEN", Const, 0},
+ {"SO_LISTENQLIMIT", Const, 0},
+ {"SO_MARK", Const, 0},
+ {"SO_NETPROC", Const, 1},
+ {"SO_NKE", Const, 0},
+ {"SO_NOADDRERR", Const, 0},
+ {"SO_NOHEADER", Const, 1},
+ {"SO_NOSIGPIPE", Const, 0},
+ {"SO_NOTIFYCONFLICT", Const, 0},
+ {"SO_NO_CHECK", Const, 0},
+ {"SO_NO_DDP", Const, 0},
+ {"SO_NO_OFFLOAD", Const, 0},
+ {"SO_NP_EXTENSIONS", Const, 0},
+ {"SO_NREAD", Const, 0},
+ {"SO_NUMRCVPKT", Const, 16},
+ {"SO_NWRITE", Const, 0},
+ {"SO_OOBINLINE", Const, 0},
+ {"SO_OVERFLOWED", Const, 1},
+ {"SO_PASSCRED", Const, 0},
+ {"SO_PASSSEC", Const, 0},
+ {"SO_PEERCRED", Const, 0},
+ {"SO_PEERLABEL", Const, 0},
+ {"SO_PEERNAME", Const, 0},
+ {"SO_PEERSEC", Const, 0},
+ {"SO_PRIORITY", Const, 0},
+ {"SO_PROTOCOL", Const, 0},
+ {"SO_PROTOTYPE", Const, 1},
+ {"SO_RANDOMPORT", Const, 0},
+ {"SO_RCVBUF", Const, 0},
+ {"SO_RCVBUFFORCE", Const, 0},
+ {"SO_RCVLOWAT", Const, 0},
+ {"SO_RCVTIMEO", Const, 0},
+ {"SO_RESTRICTIONS", Const, 0},
+ {"SO_RESTRICT_DENYIN", Const, 0},
+ {"SO_RESTRICT_DENYOUT", Const, 0},
+ {"SO_RESTRICT_DENYSET", Const, 0},
+ {"SO_REUSEADDR", Const, 0},
+ {"SO_REUSEPORT", Const, 0},
+ {"SO_REUSESHAREUID", Const, 0},
+ {"SO_RTABLE", Const, 1},
+ {"SO_RXQ_OVFL", Const, 0},
+ {"SO_SECURITY_AUTHENTICATION", Const, 0},
+ {"SO_SECURITY_ENCRYPTION_NETWORK", Const, 0},
+ {"SO_SECURITY_ENCRYPTION_TRANSPORT", Const, 0},
+ {"SO_SETFIB", Const, 0},
+ {"SO_SNDBUF", Const, 0},
+ {"SO_SNDBUFFORCE", Const, 0},
+ {"SO_SNDLOWAT", Const, 0},
+ {"SO_SNDTIMEO", Const, 0},
+ {"SO_SPLICE", Const, 1},
+ {"SO_TIMESTAMP", Const, 0},
+ {"SO_TIMESTAMPING", Const, 0},
+ {"SO_TIMESTAMPNS", Const, 0},
+ {"SO_TIMESTAMP_MONOTONIC", Const, 0},
+ {"SO_TYPE", Const, 0},
+ {"SO_UPCALLCLOSEWAIT", Const, 0},
+ {"SO_UPDATE_ACCEPT_CONTEXT", Const, 0},
+ {"SO_UPDATE_CONNECT_CONTEXT", Const, 1},
+ {"SO_USELOOPBACK", Const, 0},
+ {"SO_USER_COOKIE", Const, 1},
+ {"SO_VENDOR", Const, 3},
+ {"SO_WANTMORE", Const, 0},
+ {"SO_WANTOOBFLAG", Const, 0},
+ {"SSLExtraCertChainPolicyPara", Type, 0},
+ {"SSLExtraCertChainPolicyPara.AuthType", Field, 0},
+ {"SSLExtraCertChainPolicyPara.Checks", Field, 0},
+ {"SSLExtraCertChainPolicyPara.ServerName", Field, 0},
+ {"SSLExtraCertChainPolicyPara.Size", Field, 0},
+ {"STANDARD_RIGHTS_ALL", Const, 0},
+ {"STANDARD_RIGHTS_EXECUTE", Const, 0},
+ {"STANDARD_RIGHTS_READ", Const, 0},
+ {"STANDARD_RIGHTS_REQUIRED", Const, 0},
+ {"STANDARD_RIGHTS_WRITE", Const, 0},
+ {"STARTF_USESHOWWINDOW", Const, 0},
+ {"STARTF_USESTDHANDLES", Const, 0},
+ {"STD_ERROR_HANDLE", Const, 0},
+ {"STD_INPUT_HANDLE", Const, 0},
+ {"STD_OUTPUT_HANDLE", Const, 0},
+ {"SUBLANG_ENGLISH_US", Const, 0},
+ {"SW_FORCEMINIMIZE", Const, 0},
+ {"SW_HIDE", Const, 0},
+ {"SW_MAXIMIZE", Const, 0},
+ {"SW_MINIMIZE", Const, 0},
+ {"SW_NORMAL", Const, 0},
+ {"SW_RESTORE", Const, 0},
+ {"SW_SHOW", Const, 0},
+ {"SW_SHOWDEFAULT", Const, 0},
+ {"SW_SHOWMAXIMIZED", Const, 0},
+ {"SW_SHOWMINIMIZED", Const, 0},
+ {"SW_SHOWMINNOACTIVE", Const, 0},
+ {"SW_SHOWNA", Const, 0},
+ {"SW_SHOWNOACTIVATE", Const, 0},
+ {"SW_SHOWNORMAL", Const, 0},
+ {"SYMBOLIC_LINK_FLAG_DIRECTORY", Const, 4},
+ {"SYNCHRONIZE", Const, 0},
+ {"SYSCTL_VERSION", Const, 1},
+ {"SYSCTL_VERS_0", Const, 1},
+ {"SYSCTL_VERS_1", Const, 1},
+ {"SYSCTL_VERS_MASK", Const, 1},
+ {"SYS_ABORT2", Const, 0},
+ {"SYS_ACCEPT", Const, 0},
+ {"SYS_ACCEPT4", Const, 0},
+ {"SYS_ACCEPT_NOCANCEL", Const, 0},
+ {"SYS_ACCESS", Const, 0},
+ {"SYS_ACCESS_EXTENDED", Const, 0},
+ {"SYS_ACCT", Const, 0},
+ {"SYS_ADD_KEY", Const, 0},
+ {"SYS_ADD_PROFIL", Const, 0},
+ {"SYS_ADJFREQ", Const, 1},
+ {"SYS_ADJTIME", Const, 0},
+ {"SYS_ADJTIMEX", Const, 0},
+ {"SYS_AFS_SYSCALL", Const, 0},
+ {"SYS_AIO_CANCEL", Const, 0},
+ {"SYS_AIO_ERROR", Const, 0},
+ {"SYS_AIO_FSYNC", Const, 0},
+ {"SYS_AIO_MLOCK", Const, 14},
+ {"SYS_AIO_READ", Const, 0},
+ {"SYS_AIO_RETURN", Const, 0},
+ {"SYS_AIO_SUSPEND", Const, 0},
+ {"SYS_AIO_SUSPEND_NOCANCEL", Const, 0},
+ {"SYS_AIO_WAITCOMPLETE", Const, 14},
+ {"SYS_AIO_WRITE", Const, 0},
+ {"SYS_ALARM", Const, 0},
+ {"SYS_ARCH_PRCTL", Const, 0},
+ {"SYS_ARM_FADVISE64_64", Const, 0},
+ {"SYS_ARM_SYNC_FILE_RANGE", Const, 0},
+ {"SYS_ATGETMSG", Const, 0},
+ {"SYS_ATPGETREQ", Const, 0},
+ {"SYS_ATPGETRSP", Const, 0},
+ {"SYS_ATPSNDREQ", Const, 0},
+ {"SYS_ATPSNDRSP", Const, 0},
+ {"SYS_ATPUTMSG", Const, 0},
+ {"SYS_ATSOCKET", Const, 0},
+ {"SYS_AUDIT", Const, 0},
+ {"SYS_AUDITCTL", Const, 0},
+ {"SYS_AUDITON", Const, 0},
+ {"SYS_AUDIT_SESSION_JOIN", Const, 0},
+ {"SYS_AUDIT_SESSION_PORT", Const, 0},
+ {"SYS_AUDIT_SESSION_SELF", Const, 0},
+ {"SYS_BDFLUSH", Const, 0},
+ {"SYS_BIND", Const, 0},
+ {"SYS_BINDAT", Const, 3},
+ {"SYS_BREAK", Const, 0},
+ {"SYS_BRK", Const, 0},
+ {"SYS_BSDTHREAD_CREATE", Const, 0},
+ {"SYS_BSDTHREAD_REGISTER", Const, 0},
+ {"SYS_BSDTHREAD_TERMINATE", Const, 0},
+ {"SYS_CAPGET", Const, 0},
+ {"SYS_CAPSET", Const, 0},
+ {"SYS_CAP_ENTER", Const, 0},
+ {"SYS_CAP_FCNTLS_GET", Const, 1},
+ {"SYS_CAP_FCNTLS_LIMIT", Const, 1},
+ {"SYS_CAP_GETMODE", Const, 0},
+ {"SYS_CAP_GETRIGHTS", Const, 0},
+ {"SYS_CAP_IOCTLS_GET", Const, 1},
+ {"SYS_CAP_IOCTLS_LIMIT", Const, 1},
+ {"SYS_CAP_NEW", Const, 0},
+ {"SYS_CAP_RIGHTS_GET", Const, 1},
+ {"SYS_CAP_RIGHTS_LIMIT", Const, 1},
+ {"SYS_CHDIR", Const, 0},
+ {"SYS_CHFLAGS", Const, 0},
+ {"SYS_CHFLAGSAT", Const, 3},
+ {"SYS_CHMOD", Const, 0},
+ {"SYS_CHMOD_EXTENDED", Const, 0},
+ {"SYS_CHOWN", Const, 0},
+ {"SYS_CHOWN32", Const, 0},
+ {"SYS_CHROOT", Const, 0},
+ {"SYS_CHUD", Const, 0},
+ {"SYS_CLOCK_ADJTIME", Const, 0},
+ {"SYS_CLOCK_GETCPUCLOCKID2", Const, 1},
+ {"SYS_CLOCK_GETRES", Const, 0},
+ {"SYS_CLOCK_GETTIME", Const, 0},
+ {"SYS_CLOCK_NANOSLEEP", Const, 0},
+ {"SYS_CLOCK_SETTIME", Const, 0},
+ {"SYS_CLONE", Const, 0},
+ {"SYS_CLOSE", Const, 0},
+ {"SYS_CLOSEFROM", Const, 0},
+ {"SYS_CLOSE_NOCANCEL", Const, 0},
+ {"SYS_CONNECT", Const, 0},
+ {"SYS_CONNECTAT", Const, 3},
+ {"SYS_CONNECT_NOCANCEL", Const, 0},
+ {"SYS_COPYFILE", Const, 0},
+ {"SYS_CPUSET", Const, 0},
+ {"SYS_CPUSET_GETAFFINITY", Const, 0},
+ {"SYS_CPUSET_GETID", Const, 0},
+ {"SYS_CPUSET_SETAFFINITY", Const, 0},
+ {"SYS_CPUSET_SETID", Const, 0},
+ {"SYS_CREAT", Const, 0},
+ {"SYS_CREATE_MODULE", Const, 0},
+ {"SYS_CSOPS", Const, 0},
+ {"SYS_CSOPS_AUDITTOKEN", Const, 16},
+ {"SYS_DELETE", Const, 0},
+ {"SYS_DELETE_MODULE", Const, 0},
+ {"SYS_DUP", Const, 0},
+ {"SYS_DUP2", Const, 0},
+ {"SYS_DUP3", Const, 0},
+ {"SYS_EACCESS", Const, 0},
+ {"SYS_EPOLL_CREATE", Const, 0},
+ {"SYS_EPOLL_CREATE1", Const, 0},
+ {"SYS_EPOLL_CTL", Const, 0},
+ {"SYS_EPOLL_CTL_OLD", Const, 0},
+ {"SYS_EPOLL_PWAIT", Const, 0},
+ {"SYS_EPOLL_WAIT", Const, 0},
+ {"SYS_EPOLL_WAIT_OLD", Const, 0},
+ {"SYS_EVENTFD", Const, 0},
+ {"SYS_EVENTFD2", Const, 0},
+ {"SYS_EXCHANGEDATA", Const, 0},
+ {"SYS_EXECVE", Const, 0},
+ {"SYS_EXIT", Const, 0},
+ {"SYS_EXIT_GROUP", Const, 0},
+ {"SYS_EXTATTRCTL", Const, 0},
+ {"SYS_EXTATTR_DELETE_FD", Const, 0},
+ {"SYS_EXTATTR_DELETE_FILE", Const, 0},
+ {"SYS_EXTATTR_DELETE_LINK", Const, 0},
+ {"SYS_EXTATTR_GET_FD", Const, 0},
+ {"SYS_EXTATTR_GET_FILE", Const, 0},
+ {"SYS_EXTATTR_GET_LINK", Const, 0},
+ {"SYS_EXTATTR_LIST_FD", Const, 0},
+ {"SYS_EXTATTR_LIST_FILE", Const, 0},
+ {"SYS_EXTATTR_LIST_LINK", Const, 0},
+ {"SYS_EXTATTR_SET_FD", Const, 0},
+ {"SYS_EXTATTR_SET_FILE", Const, 0},
+ {"SYS_EXTATTR_SET_LINK", Const, 0},
+ {"SYS_FACCESSAT", Const, 0},
+ {"SYS_FADVISE64", Const, 0},
+ {"SYS_FADVISE64_64", Const, 0},
+ {"SYS_FALLOCATE", Const, 0},
+ {"SYS_FANOTIFY_INIT", Const, 0},
+ {"SYS_FANOTIFY_MARK", Const, 0},
+ {"SYS_FCHDIR", Const, 0},
+ {"SYS_FCHFLAGS", Const, 0},
+ {"SYS_FCHMOD", Const, 0},
+ {"SYS_FCHMODAT", Const, 0},
+ {"SYS_FCHMOD_EXTENDED", Const, 0},
+ {"SYS_FCHOWN", Const, 0},
+ {"SYS_FCHOWN32", Const, 0},
+ {"SYS_FCHOWNAT", Const, 0},
+ {"SYS_FCHROOT", Const, 1},
+ {"SYS_FCNTL", Const, 0},
+ {"SYS_FCNTL64", Const, 0},
+ {"SYS_FCNTL_NOCANCEL", Const, 0},
+ {"SYS_FDATASYNC", Const, 0},
+ {"SYS_FEXECVE", Const, 0},
+ {"SYS_FFCLOCK_GETCOUNTER", Const, 0},
+ {"SYS_FFCLOCK_GETESTIMATE", Const, 0},
+ {"SYS_FFCLOCK_SETESTIMATE", Const, 0},
+ {"SYS_FFSCTL", Const, 0},
+ {"SYS_FGETATTRLIST", Const, 0},
+ {"SYS_FGETXATTR", Const, 0},
+ {"SYS_FHOPEN", Const, 0},
+ {"SYS_FHSTAT", Const, 0},
+ {"SYS_FHSTATFS", Const, 0},
+ {"SYS_FILEPORT_MAKEFD", Const, 0},
+ {"SYS_FILEPORT_MAKEPORT", Const, 0},
+ {"SYS_FKTRACE", Const, 1},
+ {"SYS_FLISTXATTR", Const, 0},
+ {"SYS_FLOCK", Const, 0},
+ {"SYS_FORK", Const, 0},
+ {"SYS_FPATHCONF", Const, 0},
+ {"SYS_FREEBSD6_FTRUNCATE", Const, 0},
+ {"SYS_FREEBSD6_LSEEK", Const, 0},
+ {"SYS_FREEBSD6_MMAP", Const, 0},
+ {"SYS_FREEBSD6_PREAD", Const, 0},
+ {"SYS_FREEBSD6_PWRITE", Const, 0},
+ {"SYS_FREEBSD6_TRUNCATE", Const, 0},
+ {"SYS_FREMOVEXATTR", Const, 0},
+ {"SYS_FSCTL", Const, 0},
+ {"SYS_FSETATTRLIST", Const, 0},
+ {"SYS_FSETXATTR", Const, 0},
+ {"SYS_FSGETPATH", Const, 0},
+ {"SYS_FSTAT", Const, 0},
+ {"SYS_FSTAT64", Const, 0},
+ {"SYS_FSTAT64_EXTENDED", Const, 0},
+ {"SYS_FSTATAT", Const, 0},
+ {"SYS_FSTATAT64", Const, 0},
+ {"SYS_FSTATFS", Const, 0},
+ {"SYS_FSTATFS64", Const, 0},
+ {"SYS_FSTATV", Const, 0},
+ {"SYS_FSTATVFS1", Const, 1},
+ {"SYS_FSTAT_EXTENDED", Const, 0},
+ {"SYS_FSYNC", Const, 0},
+ {"SYS_FSYNC_NOCANCEL", Const, 0},
+ {"SYS_FSYNC_RANGE", Const, 1},
+ {"SYS_FTIME", Const, 0},
+ {"SYS_FTRUNCATE", Const, 0},
+ {"SYS_FTRUNCATE64", Const, 0},
+ {"SYS_FUTEX", Const, 0},
+ {"SYS_FUTIMENS", Const, 1},
+ {"SYS_FUTIMES", Const, 0},
+ {"SYS_FUTIMESAT", Const, 0},
+ {"SYS_GETATTRLIST", Const, 0},
+ {"SYS_GETAUDIT", Const, 0},
+ {"SYS_GETAUDIT_ADDR", Const, 0},
+ {"SYS_GETAUID", Const, 0},
+ {"SYS_GETCONTEXT", Const, 0},
+ {"SYS_GETCPU", Const, 0},
+ {"SYS_GETCWD", Const, 0},
+ {"SYS_GETDENTS", Const, 0},
+ {"SYS_GETDENTS64", Const, 0},
+ {"SYS_GETDIRENTRIES", Const, 0},
+ {"SYS_GETDIRENTRIES64", Const, 0},
+ {"SYS_GETDIRENTRIESATTR", Const, 0},
+ {"SYS_GETDTABLECOUNT", Const, 1},
+ {"SYS_GETDTABLESIZE", Const, 0},
+ {"SYS_GETEGID", Const, 0},
+ {"SYS_GETEGID32", Const, 0},
+ {"SYS_GETEUID", Const, 0},
+ {"SYS_GETEUID32", Const, 0},
+ {"SYS_GETFH", Const, 0},
+ {"SYS_GETFSSTAT", Const, 0},
+ {"SYS_GETFSSTAT64", Const, 0},
+ {"SYS_GETGID", Const, 0},
+ {"SYS_GETGID32", Const, 0},
+ {"SYS_GETGROUPS", Const, 0},
+ {"SYS_GETGROUPS32", Const, 0},
+ {"SYS_GETHOSTUUID", Const, 0},
+ {"SYS_GETITIMER", Const, 0},
+ {"SYS_GETLCID", Const, 0},
+ {"SYS_GETLOGIN", Const, 0},
+ {"SYS_GETLOGINCLASS", Const, 0},
+ {"SYS_GETPEERNAME", Const, 0},
+ {"SYS_GETPGID", Const, 0},
+ {"SYS_GETPGRP", Const, 0},
+ {"SYS_GETPID", Const, 0},
+ {"SYS_GETPMSG", Const, 0},
+ {"SYS_GETPPID", Const, 0},
+ {"SYS_GETPRIORITY", Const, 0},
+ {"SYS_GETRESGID", Const, 0},
+ {"SYS_GETRESGID32", Const, 0},
+ {"SYS_GETRESUID", Const, 0},
+ {"SYS_GETRESUID32", Const, 0},
+ {"SYS_GETRLIMIT", Const, 0},
+ {"SYS_GETRTABLE", Const, 1},
+ {"SYS_GETRUSAGE", Const, 0},
+ {"SYS_GETSGROUPS", Const, 0},
+ {"SYS_GETSID", Const, 0},
+ {"SYS_GETSOCKNAME", Const, 0},
+ {"SYS_GETSOCKOPT", Const, 0},
+ {"SYS_GETTHRID", Const, 1},
+ {"SYS_GETTID", Const, 0},
+ {"SYS_GETTIMEOFDAY", Const, 0},
+ {"SYS_GETUID", Const, 0},
+ {"SYS_GETUID32", Const, 0},
+ {"SYS_GETVFSSTAT", Const, 1},
+ {"SYS_GETWGROUPS", Const, 0},
+ {"SYS_GETXATTR", Const, 0},
+ {"SYS_GET_KERNEL_SYMS", Const, 0},
+ {"SYS_GET_MEMPOLICY", Const, 0},
+ {"SYS_GET_ROBUST_LIST", Const, 0},
+ {"SYS_GET_THREAD_AREA", Const, 0},
+ {"SYS_GSSD_SYSCALL", Const, 14},
+ {"SYS_GTTY", Const, 0},
+ {"SYS_IDENTITYSVC", Const, 0},
+ {"SYS_IDLE", Const, 0},
+ {"SYS_INITGROUPS", Const, 0},
+ {"SYS_INIT_MODULE", Const, 0},
+ {"SYS_INOTIFY_ADD_WATCH", Const, 0},
+ {"SYS_INOTIFY_INIT", Const, 0},
+ {"SYS_INOTIFY_INIT1", Const, 0},
+ {"SYS_INOTIFY_RM_WATCH", Const, 0},
+ {"SYS_IOCTL", Const, 0},
+ {"SYS_IOPERM", Const, 0},
+ {"SYS_IOPL", Const, 0},
+ {"SYS_IOPOLICYSYS", Const, 0},
+ {"SYS_IOPRIO_GET", Const, 0},
+ {"SYS_IOPRIO_SET", Const, 0},
+ {"SYS_IO_CANCEL", Const, 0},
+ {"SYS_IO_DESTROY", Const, 0},
+ {"SYS_IO_GETEVENTS", Const, 0},
+ {"SYS_IO_SETUP", Const, 0},
+ {"SYS_IO_SUBMIT", Const, 0},
+ {"SYS_IPC", Const, 0},
+ {"SYS_ISSETUGID", Const, 0},
+ {"SYS_JAIL", Const, 0},
+ {"SYS_JAIL_ATTACH", Const, 0},
+ {"SYS_JAIL_GET", Const, 0},
+ {"SYS_JAIL_REMOVE", Const, 0},
+ {"SYS_JAIL_SET", Const, 0},
+ {"SYS_KAS_INFO", Const, 16},
+ {"SYS_KDEBUG_TRACE", Const, 0},
+ {"SYS_KENV", Const, 0},
+ {"SYS_KEVENT", Const, 0},
+ {"SYS_KEVENT64", Const, 0},
+ {"SYS_KEXEC_LOAD", Const, 0},
+ {"SYS_KEYCTL", Const, 0},
+ {"SYS_KILL", Const, 0},
+ {"SYS_KLDFIND", Const, 0},
+ {"SYS_KLDFIRSTMOD", Const, 0},
+ {"SYS_KLDLOAD", Const, 0},
+ {"SYS_KLDNEXT", Const, 0},
+ {"SYS_KLDSTAT", Const, 0},
+ {"SYS_KLDSYM", Const, 0},
+ {"SYS_KLDUNLOAD", Const, 0},
+ {"SYS_KLDUNLOADF", Const, 0},
+ {"SYS_KMQ_NOTIFY", Const, 14},
+ {"SYS_KMQ_OPEN", Const, 14},
+ {"SYS_KMQ_SETATTR", Const, 14},
+ {"SYS_KMQ_TIMEDRECEIVE", Const, 14},
+ {"SYS_KMQ_TIMEDSEND", Const, 14},
+ {"SYS_KMQ_UNLINK", Const, 14},
+ {"SYS_KQUEUE", Const, 0},
+ {"SYS_KQUEUE1", Const, 1},
+ {"SYS_KSEM_CLOSE", Const, 14},
+ {"SYS_KSEM_DESTROY", Const, 14},
+ {"SYS_KSEM_GETVALUE", Const, 14},
+ {"SYS_KSEM_INIT", Const, 14},
+ {"SYS_KSEM_OPEN", Const, 14},
+ {"SYS_KSEM_POST", Const, 14},
+ {"SYS_KSEM_TIMEDWAIT", Const, 14},
+ {"SYS_KSEM_TRYWAIT", Const, 14},
+ {"SYS_KSEM_UNLINK", Const, 14},
+ {"SYS_KSEM_WAIT", Const, 14},
+ {"SYS_KTIMER_CREATE", Const, 0},
+ {"SYS_KTIMER_DELETE", Const, 0},
+ {"SYS_KTIMER_GETOVERRUN", Const, 0},
+ {"SYS_KTIMER_GETTIME", Const, 0},
+ {"SYS_KTIMER_SETTIME", Const, 0},
+ {"SYS_KTRACE", Const, 0},
+ {"SYS_LCHFLAGS", Const, 0},
+ {"SYS_LCHMOD", Const, 0},
+ {"SYS_LCHOWN", Const, 0},
+ {"SYS_LCHOWN32", Const, 0},
+ {"SYS_LEDGER", Const, 16},
+ {"SYS_LGETFH", Const, 0},
+ {"SYS_LGETXATTR", Const, 0},
+ {"SYS_LINK", Const, 0},
+ {"SYS_LINKAT", Const, 0},
+ {"SYS_LIO_LISTIO", Const, 0},
+ {"SYS_LISTEN", Const, 0},
+ {"SYS_LISTXATTR", Const, 0},
+ {"SYS_LLISTXATTR", Const, 0},
+ {"SYS_LOCK", Const, 0},
+ {"SYS_LOOKUP_DCOOKIE", Const, 0},
+ {"SYS_LPATHCONF", Const, 0},
+ {"SYS_LREMOVEXATTR", Const, 0},
+ {"SYS_LSEEK", Const, 0},
+ {"SYS_LSETXATTR", Const, 0},
+ {"SYS_LSTAT", Const, 0},
+ {"SYS_LSTAT64", Const, 0},
+ {"SYS_LSTAT64_EXTENDED", Const, 0},
+ {"SYS_LSTATV", Const, 0},
+ {"SYS_LSTAT_EXTENDED", Const, 0},
+ {"SYS_LUTIMES", Const, 0},
+ {"SYS_MAC_SYSCALL", Const, 0},
+ {"SYS_MADVISE", Const, 0},
+ {"SYS_MADVISE1", Const, 0},
+ {"SYS_MAXSYSCALL", Const, 0},
+ {"SYS_MBIND", Const, 0},
+ {"SYS_MIGRATE_PAGES", Const, 0},
+ {"SYS_MINCORE", Const, 0},
+ {"SYS_MINHERIT", Const, 0},
+ {"SYS_MKCOMPLEX", Const, 0},
+ {"SYS_MKDIR", Const, 0},
+ {"SYS_MKDIRAT", Const, 0},
+ {"SYS_MKDIR_EXTENDED", Const, 0},
+ {"SYS_MKFIFO", Const, 0},
+ {"SYS_MKFIFOAT", Const, 0},
+ {"SYS_MKFIFO_EXTENDED", Const, 0},
+ {"SYS_MKNOD", Const, 0},
+ {"SYS_MKNODAT", Const, 0},
+ {"SYS_MLOCK", Const, 0},
+ {"SYS_MLOCKALL", Const, 0},
+ {"SYS_MMAP", Const, 0},
+ {"SYS_MMAP2", Const, 0},
+ {"SYS_MODCTL", Const, 1},
+ {"SYS_MODFIND", Const, 0},
+ {"SYS_MODFNEXT", Const, 0},
+ {"SYS_MODIFY_LDT", Const, 0},
+ {"SYS_MODNEXT", Const, 0},
+ {"SYS_MODSTAT", Const, 0},
+ {"SYS_MODWATCH", Const, 0},
+ {"SYS_MOUNT", Const, 0},
+ {"SYS_MOVE_PAGES", Const, 0},
+ {"SYS_MPROTECT", Const, 0},
+ {"SYS_MPX", Const, 0},
+ {"SYS_MQUERY", Const, 1},
+ {"SYS_MQ_GETSETATTR", Const, 0},
+ {"SYS_MQ_NOTIFY", Const, 0},
+ {"SYS_MQ_OPEN", Const, 0},
+ {"SYS_MQ_TIMEDRECEIVE", Const, 0},
+ {"SYS_MQ_TIMEDSEND", Const, 0},
+ {"SYS_MQ_UNLINK", Const, 0},
+ {"SYS_MREMAP", Const, 0},
+ {"SYS_MSGCTL", Const, 0},
+ {"SYS_MSGGET", Const, 0},
+ {"SYS_MSGRCV", Const, 0},
+ {"SYS_MSGRCV_NOCANCEL", Const, 0},
+ {"SYS_MSGSND", Const, 0},
+ {"SYS_MSGSND_NOCANCEL", Const, 0},
+ {"SYS_MSGSYS", Const, 0},
+ {"SYS_MSYNC", Const, 0},
+ {"SYS_MSYNC_NOCANCEL", Const, 0},
+ {"SYS_MUNLOCK", Const, 0},
+ {"SYS_MUNLOCKALL", Const, 0},
+ {"SYS_MUNMAP", Const, 0},
+ {"SYS_NAME_TO_HANDLE_AT", Const, 0},
+ {"SYS_NANOSLEEP", Const, 0},
+ {"SYS_NEWFSTATAT", Const, 0},
+ {"SYS_NFSCLNT", Const, 0},
+ {"SYS_NFSSERVCTL", Const, 0},
+ {"SYS_NFSSVC", Const, 0},
+ {"SYS_NFSTAT", Const, 0},
+ {"SYS_NICE", Const, 0},
+ {"SYS_NLM_SYSCALL", Const, 14},
+ {"SYS_NLSTAT", Const, 0},
+ {"SYS_NMOUNT", Const, 0},
+ {"SYS_NSTAT", Const, 0},
+ {"SYS_NTP_ADJTIME", Const, 0},
+ {"SYS_NTP_GETTIME", Const, 0},
+ {"SYS_NUMA_GETAFFINITY", Const, 14},
+ {"SYS_NUMA_SETAFFINITY", Const, 14},
+ {"SYS_OABI_SYSCALL_BASE", Const, 0},
+ {"SYS_OBREAK", Const, 0},
+ {"SYS_OLDFSTAT", Const, 0},
+ {"SYS_OLDLSTAT", Const, 0},
+ {"SYS_OLDOLDUNAME", Const, 0},
+ {"SYS_OLDSTAT", Const, 0},
+ {"SYS_OLDUNAME", Const, 0},
+ {"SYS_OPEN", Const, 0},
+ {"SYS_OPENAT", Const, 0},
+ {"SYS_OPENBSD_POLL", Const, 0},
+ {"SYS_OPEN_BY_HANDLE_AT", Const, 0},
+ {"SYS_OPEN_DPROTECTED_NP", Const, 16},
+ {"SYS_OPEN_EXTENDED", Const, 0},
+ {"SYS_OPEN_NOCANCEL", Const, 0},
+ {"SYS_OVADVISE", Const, 0},
+ {"SYS_PACCEPT", Const, 1},
+ {"SYS_PATHCONF", Const, 0},
+ {"SYS_PAUSE", Const, 0},
+ {"SYS_PCICONFIG_IOBASE", Const, 0},
+ {"SYS_PCICONFIG_READ", Const, 0},
+ {"SYS_PCICONFIG_WRITE", Const, 0},
+ {"SYS_PDFORK", Const, 0},
+ {"SYS_PDGETPID", Const, 0},
+ {"SYS_PDKILL", Const, 0},
+ {"SYS_PERF_EVENT_OPEN", Const, 0},
+ {"SYS_PERSONALITY", Const, 0},
+ {"SYS_PID_HIBERNATE", Const, 0},
+ {"SYS_PID_RESUME", Const, 0},
+ {"SYS_PID_SHUTDOWN_SOCKETS", Const, 0},
+ {"SYS_PID_SUSPEND", Const, 0},
+ {"SYS_PIPE", Const, 0},
+ {"SYS_PIPE2", Const, 0},
+ {"SYS_PIVOT_ROOT", Const, 0},
+ {"SYS_PMC_CONTROL", Const, 1},
+ {"SYS_PMC_GET_INFO", Const, 1},
+ {"SYS_POLL", Const, 0},
+ {"SYS_POLLTS", Const, 1},
+ {"SYS_POLL_NOCANCEL", Const, 0},
+ {"SYS_POSIX_FADVISE", Const, 0},
+ {"SYS_POSIX_FALLOCATE", Const, 0},
+ {"SYS_POSIX_OPENPT", Const, 0},
+ {"SYS_POSIX_SPAWN", Const, 0},
+ {"SYS_PPOLL", Const, 0},
+ {"SYS_PRCTL", Const, 0},
+ {"SYS_PREAD", Const, 0},
+ {"SYS_PREAD64", Const, 0},
+ {"SYS_PREADV", Const, 0},
+ {"SYS_PREAD_NOCANCEL", Const, 0},
+ {"SYS_PRLIMIT64", Const, 0},
+ {"SYS_PROCCTL", Const, 3},
+ {"SYS_PROCESS_POLICY", Const, 0},
+ {"SYS_PROCESS_VM_READV", Const, 0},
+ {"SYS_PROCESS_VM_WRITEV", Const, 0},
+ {"SYS_PROC_INFO", Const, 0},
+ {"SYS_PROF", Const, 0},
+ {"SYS_PROFIL", Const, 0},
+ {"SYS_PSELECT", Const, 0},
+ {"SYS_PSELECT6", Const, 0},
+ {"SYS_PSET_ASSIGN", Const, 1},
+ {"SYS_PSET_CREATE", Const, 1},
+ {"SYS_PSET_DESTROY", Const, 1},
+ {"SYS_PSYNCH_CVBROAD", Const, 0},
+ {"SYS_PSYNCH_CVCLRPREPOST", Const, 0},
+ {"SYS_PSYNCH_CVSIGNAL", Const, 0},
+ {"SYS_PSYNCH_CVWAIT", Const, 0},
+ {"SYS_PSYNCH_MUTEXDROP", Const, 0},
+ {"SYS_PSYNCH_MUTEXWAIT", Const, 0},
+ {"SYS_PSYNCH_RW_DOWNGRADE", Const, 0},
+ {"SYS_PSYNCH_RW_LONGRDLOCK", Const, 0},
+ {"SYS_PSYNCH_RW_RDLOCK", Const, 0},
+ {"SYS_PSYNCH_RW_UNLOCK", Const, 0},
+ {"SYS_PSYNCH_RW_UNLOCK2", Const, 0},
+ {"SYS_PSYNCH_RW_UPGRADE", Const, 0},
+ {"SYS_PSYNCH_RW_WRLOCK", Const, 0},
+ {"SYS_PSYNCH_RW_YIELDWRLOCK", Const, 0},
+ {"SYS_PTRACE", Const, 0},
+ {"SYS_PUTPMSG", Const, 0},
+ {"SYS_PWRITE", Const, 0},
+ {"SYS_PWRITE64", Const, 0},
+ {"SYS_PWRITEV", Const, 0},
+ {"SYS_PWRITE_NOCANCEL", Const, 0},
+ {"SYS_QUERY_MODULE", Const, 0},
+ {"SYS_QUOTACTL", Const, 0},
+ {"SYS_RASCTL", Const, 1},
+ {"SYS_RCTL_ADD_RULE", Const, 0},
+ {"SYS_RCTL_GET_LIMITS", Const, 0},
+ {"SYS_RCTL_GET_RACCT", Const, 0},
+ {"SYS_RCTL_GET_RULES", Const, 0},
+ {"SYS_RCTL_REMOVE_RULE", Const, 0},
+ {"SYS_READ", Const, 0},
+ {"SYS_READAHEAD", Const, 0},
+ {"SYS_READDIR", Const, 0},
+ {"SYS_READLINK", Const, 0},
+ {"SYS_READLINKAT", Const, 0},
+ {"SYS_READV", Const, 0},
+ {"SYS_READV_NOCANCEL", Const, 0},
+ {"SYS_READ_NOCANCEL", Const, 0},
+ {"SYS_REBOOT", Const, 0},
+ {"SYS_RECV", Const, 0},
+ {"SYS_RECVFROM", Const, 0},
+ {"SYS_RECVFROM_NOCANCEL", Const, 0},
+ {"SYS_RECVMMSG", Const, 0},
+ {"SYS_RECVMSG", Const, 0},
+ {"SYS_RECVMSG_NOCANCEL", Const, 0},
+ {"SYS_REMAP_FILE_PAGES", Const, 0},
+ {"SYS_REMOVEXATTR", Const, 0},
+ {"SYS_RENAME", Const, 0},
+ {"SYS_RENAMEAT", Const, 0},
+ {"SYS_REQUEST_KEY", Const, 0},
+ {"SYS_RESTART_SYSCALL", Const, 0},
+ {"SYS_REVOKE", Const, 0},
+ {"SYS_RFORK", Const, 0},
+ {"SYS_RMDIR", Const, 0},
+ {"SYS_RTPRIO", Const, 0},
+ {"SYS_RTPRIO_THREAD", Const, 0},
+ {"SYS_RT_SIGACTION", Const, 0},
+ {"SYS_RT_SIGPENDING", Const, 0},
+ {"SYS_RT_SIGPROCMASK", Const, 0},
+ {"SYS_RT_SIGQUEUEINFO", Const, 0},
+ {"SYS_RT_SIGRETURN", Const, 0},
+ {"SYS_RT_SIGSUSPEND", Const, 0},
+ {"SYS_RT_SIGTIMEDWAIT", Const, 0},
+ {"SYS_RT_TGSIGQUEUEINFO", Const, 0},
+ {"SYS_SBRK", Const, 0},
+ {"SYS_SCHED_GETAFFINITY", Const, 0},
+ {"SYS_SCHED_GETPARAM", Const, 0},
+ {"SYS_SCHED_GETSCHEDULER", Const, 0},
+ {"SYS_SCHED_GET_PRIORITY_MAX", Const, 0},
+ {"SYS_SCHED_GET_PRIORITY_MIN", Const, 0},
+ {"SYS_SCHED_RR_GET_INTERVAL", Const, 0},
+ {"SYS_SCHED_SETAFFINITY", Const, 0},
+ {"SYS_SCHED_SETPARAM", Const, 0},
+ {"SYS_SCHED_SETSCHEDULER", Const, 0},
+ {"SYS_SCHED_YIELD", Const, 0},
+ {"SYS_SCTP_GENERIC_RECVMSG", Const, 0},
+ {"SYS_SCTP_GENERIC_SENDMSG", Const, 0},
+ {"SYS_SCTP_GENERIC_SENDMSG_IOV", Const, 0},
+ {"SYS_SCTP_PEELOFF", Const, 0},
+ {"SYS_SEARCHFS", Const, 0},
+ {"SYS_SECURITY", Const, 0},
+ {"SYS_SELECT", Const, 0},
+ {"SYS_SELECT_NOCANCEL", Const, 0},
+ {"SYS_SEMCONFIG", Const, 1},
+ {"SYS_SEMCTL", Const, 0},
+ {"SYS_SEMGET", Const, 0},
+ {"SYS_SEMOP", Const, 0},
+ {"SYS_SEMSYS", Const, 0},
+ {"SYS_SEMTIMEDOP", Const, 0},
+ {"SYS_SEM_CLOSE", Const, 0},
+ {"SYS_SEM_DESTROY", Const, 0},
+ {"SYS_SEM_GETVALUE", Const, 0},
+ {"SYS_SEM_INIT", Const, 0},
+ {"SYS_SEM_OPEN", Const, 0},
+ {"SYS_SEM_POST", Const, 0},
+ {"SYS_SEM_TRYWAIT", Const, 0},
+ {"SYS_SEM_UNLINK", Const, 0},
+ {"SYS_SEM_WAIT", Const, 0},
+ {"SYS_SEM_WAIT_NOCANCEL", Const, 0},
+ {"SYS_SEND", Const, 0},
+ {"SYS_SENDFILE", Const, 0},
+ {"SYS_SENDFILE64", Const, 0},
+ {"SYS_SENDMMSG", Const, 0},
+ {"SYS_SENDMSG", Const, 0},
+ {"SYS_SENDMSG_NOCANCEL", Const, 0},
+ {"SYS_SENDTO", Const, 0},
+ {"SYS_SENDTO_NOCANCEL", Const, 0},
+ {"SYS_SETATTRLIST", Const, 0},
+ {"SYS_SETAUDIT", Const, 0},
+ {"SYS_SETAUDIT_ADDR", Const, 0},
+ {"SYS_SETAUID", Const, 0},
+ {"SYS_SETCONTEXT", Const, 0},
+ {"SYS_SETDOMAINNAME", Const, 0},
+ {"SYS_SETEGID", Const, 0},
+ {"SYS_SETEUID", Const, 0},
+ {"SYS_SETFIB", Const, 0},
+ {"SYS_SETFSGID", Const, 0},
+ {"SYS_SETFSGID32", Const, 0},
+ {"SYS_SETFSUID", Const, 0},
+ {"SYS_SETFSUID32", Const, 0},
+ {"SYS_SETGID", Const, 0},
+ {"SYS_SETGID32", Const, 0},
+ {"SYS_SETGROUPS", Const, 0},
+ {"SYS_SETGROUPS32", Const, 0},
+ {"SYS_SETHOSTNAME", Const, 0},
+ {"SYS_SETITIMER", Const, 0},
+ {"SYS_SETLCID", Const, 0},
+ {"SYS_SETLOGIN", Const, 0},
+ {"SYS_SETLOGINCLASS", Const, 0},
+ {"SYS_SETNS", Const, 0},
+ {"SYS_SETPGID", Const, 0},
+ {"SYS_SETPRIORITY", Const, 0},
+ {"SYS_SETPRIVEXEC", Const, 0},
+ {"SYS_SETREGID", Const, 0},
+ {"SYS_SETREGID32", Const, 0},
+ {"SYS_SETRESGID", Const, 0},
+ {"SYS_SETRESGID32", Const, 0},
+ {"SYS_SETRESUID", Const, 0},
+ {"SYS_SETRESUID32", Const, 0},
+ {"SYS_SETREUID", Const, 0},
+ {"SYS_SETREUID32", Const, 0},
+ {"SYS_SETRLIMIT", Const, 0},
+ {"SYS_SETRTABLE", Const, 1},
+ {"SYS_SETSGROUPS", Const, 0},
+ {"SYS_SETSID", Const, 0},
+ {"SYS_SETSOCKOPT", Const, 0},
+ {"SYS_SETTID", Const, 0},
+ {"SYS_SETTID_WITH_PID", Const, 0},
+ {"SYS_SETTIMEOFDAY", Const, 0},
+ {"SYS_SETUID", Const, 0},
+ {"SYS_SETUID32", Const, 0},
+ {"SYS_SETWGROUPS", Const, 0},
+ {"SYS_SETXATTR", Const, 0},
+ {"SYS_SET_MEMPOLICY", Const, 0},
+ {"SYS_SET_ROBUST_LIST", Const, 0},
+ {"SYS_SET_THREAD_AREA", Const, 0},
+ {"SYS_SET_TID_ADDRESS", Const, 0},
+ {"SYS_SGETMASK", Const, 0},
+ {"SYS_SHARED_REGION_CHECK_NP", Const, 0},
+ {"SYS_SHARED_REGION_MAP_AND_SLIDE_NP", Const, 0},
+ {"SYS_SHMAT", Const, 0},
+ {"SYS_SHMCTL", Const, 0},
+ {"SYS_SHMDT", Const, 0},
+ {"SYS_SHMGET", Const, 0},
+ {"SYS_SHMSYS", Const, 0},
+ {"SYS_SHM_OPEN", Const, 0},
+ {"SYS_SHM_UNLINK", Const, 0},
+ {"SYS_SHUTDOWN", Const, 0},
+ {"SYS_SIGACTION", Const, 0},
+ {"SYS_SIGALTSTACK", Const, 0},
+ {"SYS_SIGNAL", Const, 0},
+ {"SYS_SIGNALFD", Const, 0},
+ {"SYS_SIGNALFD4", Const, 0},
+ {"SYS_SIGPENDING", Const, 0},
+ {"SYS_SIGPROCMASK", Const, 0},
+ {"SYS_SIGQUEUE", Const, 0},
+ {"SYS_SIGQUEUEINFO", Const, 1},
+ {"SYS_SIGRETURN", Const, 0},
+ {"SYS_SIGSUSPEND", Const, 0},
+ {"SYS_SIGSUSPEND_NOCANCEL", Const, 0},
+ {"SYS_SIGTIMEDWAIT", Const, 0},
+ {"SYS_SIGWAIT", Const, 0},
+ {"SYS_SIGWAITINFO", Const, 0},
+ {"SYS_SOCKET", Const, 0},
+ {"SYS_SOCKETCALL", Const, 0},
+ {"SYS_SOCKETPAIR", Const, 0},
+ {"SYS_SPLICE", Const, 0},
+ {"SYS_SSETMASK", Const, 0},
+ {"SYS_SSTK", Const, 0},
+ {"SYS_STACK_SNAPSHOT", Const, 0},
+ {"SYS_STAT", Const, 0},
+ {"SYS_STAT64", Const, 0},
+ {"SYS_STAT64_EXTENDED", Const, 0},
+ {"SYS_STATFS", Const, 0},
+ {"SYS_STATFS64", Const, 0},
+ {"SYS_STATV", Const, 0},
+ {"SYS_STATVFS1", Const, 1},
+ {"SYS_STAT_EXTENDED", Const, 0},
+ {"SYS_STIME", Const, 0},
+ {"SYS_STTY", Const, 0},
+ {"SYS_SWAPCONTEXT", Const, 0},
+ {"SYS_SWAPCTL", Const, 1},
+ {"SYS_SWAPOFF", Const, 0},
+ {"SYS_SWAPON", Const, 0},
+ {"SYS_SYMLINK", Const, 0},
+ {"SYS_SYMLINKAT", Const, 0},
+ {"SYS_SYNC", Const, 0},
+ {"SYS_SYNCFS", Const, 0},
+ {"SYS_SYNC_FILE_RANGE", Const, 0},
+ {"SYS_SYSARCH", Const, 0},
+ {"SYS_SYSCALL", Const, 0},
+ {"SYS_SYSCALL_BASE", Const, 0},
+ {"SYS_SYSFS", Const, 0},
+ {"SYS_SYSINFO", Const, 0},
+ {"SYS_SYSLOG", Const, 0},
+ {"SYS_TEE", Const, 0},
+ {"SYS_TGKILL", Const, 0},
+ {"SYS_THREAD_SELFID", Const, 0},
+ {"SYS_THR_CREATE", Const, 0},
+ {"SYS_THR_EXIT", Const, 0},
+ {"SYS_THR_KILL", Const, 0},
+ {"SYS_THR_KILL2", Const, 0},
+ {"SYS_THR_NEW", Const, 0},
+ {"SYS_THR_SELF", Const, 0},
+ {"SYS_THR_SET_NAME", Const, 0},
+ {"SYS_THR_SUSPEND", Const, 0},
+ {"SYS_THR_WAKE", Const, 0},
+ {"SYS_TIME", Const, 0},
+ {"SYS_TIMERFD_CREATE", Const, 0},
+ {"SYS_TIMERFD_GETTIME", Const, 0},
+ {"SYS_TIMERFD_SETTIME", Const, 0},
+ {"SYS_TIMER_CREATE", Const, 0},
+ {"SYS_TIMER_DELETE", Const, 0},
+ {"SYS_TIMER_GETOVERRUN", Const, 0},
+ {"SYS_TIMER_GETTIME", Const, 0},
+ {"SYS_TIMER_SETTIME", Const, 0},
+ {"SYS_TIMES", Const, 0},
+ {"SYS_TKILL", Const, 0},
+ {"SYS_TRUNCATE", Const, 0},
+ {"SYS_TRUNCATE64", Const, 0},
+ {"SYS_TUXCALL", Const, 0},
+ {"SYS_UGETRLIMIT", Const, 0},
+ {"SYS_ULIMIT", Const, 0},
+ {"SYS_UMASK", Const, 0},
+ {"SYS_UMASK_EXTENDED", Const, 0},
+ {"SYS_UMOUNT", Const, 0},
+ {"SYS_UMOUNT2", Const, 0},
+ {"SYS_UNAME", Const, 0},
+ {"SYS_UNDELETE", Const, 0},
+ {"SYS_UNLINK", Const, 0},
+ {"SYS_UNLINKAT", Const, 0},
+ {"SYS_UNMOUNT", Const, 0},
+ {"SYS_UNSHARE", Const, 0},
+ {"SYS_USELIB", Const, 0},
+ {"SYS_USTAT", Const, 0},
+ {"SYS_UTIME", Const, 0},
+ {"SYS_UTIMENSAT", Const, 0},
+ {"SYS_UTIMES", Const, 0},
+ {"SYS_UTRACE", Const, 0},
+ {"SYS_UUIDGEN", Const, 0},
+ {"SYS_VADVISE", Const, 1},
+ {"SYS_VFORK", Const, 0},
+ {"SYS_VHANGUP", Const, 0},
+ {"SYS_VM86", Const, 0},
+ {"SYS_VM86OLD", Const, 0},
+ {"SYS_VMSPLICE", Const, 0},
+ {"SYS_VM_PRESSURE_MONITOR", Const, 0},
+ {"SYS_VSERVER", Const, 0},
+ {"SYS_WAIT4", Const, 0},
+ {"SYS_WAIT4_NOCANCEL", Const, 0},
+ {"SYS_WAIT6", Const, 1},
+ {"SYS_WAITEVENT", Const, 0},
+ {"SYS_WAITID", Const, 0},
+ {"SYS_WAITID_NOCANCEL", Const, 0},
+ {"SYS_WAITPID", Const, 0},
+ {"SYS_WATCHEVENT", Const, 0},
+ {"SYS_WORKQ_KERNRETURN", Const, 0},
+ {"SYS_WORKQ_OPEN", Const, 0},
+ {"SYS_WRITE", Const, 0},
+ {"SYS_WRITEV", Const, 0},
+ {"SYS_WRITEV_NOCANCEL", Const, 0},
+ {"SYS_WRITE_NOCANCEL", Const, 0},
+ {"SYS_YIELD", Const, 0},
+ {"SYS__LLSEEK", Const, 0},
+ {"SYS__LWP_CONTINUE", Const, 1},
+ {"SYS__LWP_CREATE", Const, 1},
+ {"SYS__LWP_CTL", Const, 1},
+ {"SYS__LWP_DETACH", Const, 1},
+ {"SYS__LWP_EXIT", Const, 1},
+ {"SYS__LWP_GETNAME", Const, 1},
+ {"SYS__LWP_GETPRIVATE", Const, 1},
+ {"SYS__LWP_KILL", Const, 1},
+ {"SYS__LWP_PARK", Const, 1},
+ {"SYS__LWP_SELF", Const, 1},
+ {"SYS__LWP_SETNAME", Const, 1},
+ {"SYS__LWP_SETPRIVATE", Const, 1},
+ {"SYS__LWP_SUSPEND", Const, 1},
+ {"SYS__LWP_UNPARK", Const, 1},
+ {"SYS__LWP_UNPARK_ALL", Const, 1},
+ {"SYS__LWP_WAIT", Const, 1},
+ {"SYS__LWP_WAKEUP", Const, 1},
+ {"SYS__NEWSELECT", Const, 0},
+ {"SYS__PSET_BIND", Const, 1},
+ {"SYS__SCHED_GETAFFINITY", Const, 1},
+ {"SYS__SCHED_GETPARAM", Const, 1},
+ {"SYS__SCHED_SETAFFINITY", Const, 1},
+ {"SYS__SCHED_SETPARAM", Const, 1},
+ {"SYS__SYSCTL", Const, 0},
+ {"SYS__UMTX_LOCK", Const, 0},
+ {"SYS__UMTX_OP", Const, 0},
+ {"SYS__UMTX_UNLOCK", Const, 0},
+ {"SYS___ACL_ACLCHECK_FD", Const, 0},
+ {"SYS___ACL_ACLCHECK_FILE", Const, 0},
+ {"SYS___ACL_ACLCHECK_LINK", Const, 0},
+ {"SYS___ACL_DELETE_FD", Const, 0},
+ {"SYS___ACL_DELETE_FILE", Const, 0},
+ {"SYS___ACL_DELETE_LINK", Const, 0},
+ {"SYS___ACL_GET_FD", Const, 0},
+ {"SYS___ACL_GET_FILE", Const, 0},
+ {"SYS___ACL_GET_LINK", Const, 0},
+ {"SYS___ACL_SET_FD", Const, 0},
+ {"SYS___ACL_SET_FILE", Const, 0},
+ {"SYS___ACL_SET_LINK", Const, 0},
+ {"SYS___CAP_RIGHTS_GET", Const, 14},
+ {"SYS___CLONE", Const, 1},
+ {"SYS___DISABLE_THREADSIGNAL", Const, 0},
+ {"SYS___GETCWD", Const, 0},
+ {"SYS___GETLOGIN", Const, 1},
+ {"SYS___GET_TCB", Const, 1},
+ {"SYS___MAC_EXECVE", Const, 0},
+ {"SYS___MAC_GETFSSTAT", Const, 0},
+ {"SYS___MAC_GET_FD", Const, 0},
+ {"SYS___MAC_GET_FILE", Const, 0},
+ {"SYS___MAC_GET_LCID", Const, 0},
+ {"SYS___MAC_GET_LCTX", Const, 0},
+ {"SYS___MAC_GET_LINK", Const, 0},
+ {"SYS___MAC_GET_MOUNT", Const, 0},
+ {"SYS___MAC_GET_PID", Const, 0},
+ {"SYS___MAC_GET_PROC", Const, 0},
+ {"SYS___MAC_MOUNT", Const, 0},
+ {"SYS___MAC_SET_FD", Const, 0},
+ {"SYS___MAC_SET_FILE", Const, 0},
+ {"SYS___MAC_SET_LCTX", Const, 0},
+ {"SYS___MAC_SET_LINK", Const, 0},
+ {"SYS___MAC_SET_PROC", Const, 0},
+ {"SYS___MAC_SYSCALL", Const, 0},
+ {"SYS___OLD_SEMWAIT_SIGNAL", Const, 0},
+ {"SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL", Const, 0},
+ {"SYS___POSIX_CHOWN", Const, 1},
+ {"SYS___POSIX_FCHOWN", Const, 1},
+ {"SYS___POSIX_LCHOWN", Const, 1},
+ {"SYS___POSIX_RENAME", Const, 1},
+ {"SYS___PTHREAD_CANCELED", Const, 0},
+ {"SYS___PTHREAD_CHDIR", Const, 0},
+ {"SYS___PTHREAD_FCHDIR", Const, 0},
+ {"SYS___PTHREAD_KILL", Const, 0},
+ {"SYS___PTHREAD_MARKCANCEL", Const, 0},
+ {"SYS___PTHREAD_SIGMASK", Const, 0},
+ {"SYS___QUOTACTL", Const, 1},
+ {"SYS___SEMCTL", Const, 1},
+ {"SYS___SEMWAIT_SIGNAL", Const, 0},
+ {"SYS___SEMWAIT_SIGNAL_NOCANCEL", Const, 0},
+ {"SYS___SETLOGIN", Const, 1},
+ {"SYS___SETUGID", Const, 0},
+ {"SYS___SET_TCB", Const, 1},
+ {"SYS___SIGACTION_SIGTRAMP", Const, 1},
+ {"SYS___SIGTIMEDWAIT", Const, 1},
+ {"SYS___SIGWAIT", Const, 0},
+ {"SYS___SIGWAIT_NOCANCEL", Const, 0},
+ {"SYS___SYSCTL", Const, 0},
+ {"SYS___TFORK", Const, 1},
+ {"SYS___THREXIT", Const, 1},
+ {"SYS___THRSIGDIVERT", Const, 1},
+ {"SYS___THRSLEEP", Const, 1},
+ {"SYS___THRWAKEUP", Const, 1},
+ {"S_ARCH1", Const, 1},
+ {"S_ARCH2", Const, 1},
+ {"S_BLKSIZE", Const, 0},
+ {"S_IEXEC", Const, 0},
+ {"S_IFBLK", Const, 0},
+ {"S_IFCHR", Const, 0},
+ {"S_IFDIR", Const, 0},
+ {"S_IFIFO", Const, 0},
+ {"S_IFLNK", Const, 0},
+ {"S_IFMT", Const, 0},
+ {"S_IFREG", Const, 0},
+ {"S_IFSOCK", Const, 0},
+ {"S_IFWHT", Const, 0},
+ {"S_IREAD", Const, 0},
+ {"S_IRGRP", Const, 0},
+ {"S_IROTH", Const, 0},
+ {"S_IRUSR", Const, 0},
+ {"S_IRWXG", Const, 0},
+ {"S_IRWXO", Const, 0},
+ {"S_IRWXU", Const, 0},
+ {"S_ISGID", Const, 0},
+ {"S_ISTXT", Const, 0},
+ {"S_ISUID", Const, 0},
+ {"S_ISVTX", Const, 0},
+ {"S_IWGRP", Const, 0},
+ {"S_IWOTH", Const, 0},
+ {"S_IWRITE", Const, 0},
+ {"S_IWUSR", Const, 0},
+ {"S_IXGRP", Const, 0},
+ {"S_IXOTH", Const, 0},
+ {"S_IXUSR", Const, 0},
+ {"S_LOGIN_SET", Const, 1},
+ {"SecurityAttributes", Type, 0},
+ {"SecurityAttributes.InheritHandle", Field, 0},
+ {"SecurityAttributes.Length", Field, 0},
+ {"SecurityAttributes.SecurityDescriptor", Field, 0},
+ {"Seek", Func, 0},
+ {"Select", Func, 0},
+ {"Sendfile", Func, 0},
+ {"Sendmsg", Func, 0},
+ {"SendmsgN", Func, 3},
+ {"Sendto", Func, 0},
+ {"Servent", Type, 0},
+ {"Servent.Aliases", Field, 0},
+ {"Servent.Name", Field, 0},
+ {"Servent.Port", Field, 0},
+ {"Servent.Proto", Field, 0},
+ {"SetBpf", Func, 0},
+ {"SetBpfBuflen", Func, 0},
+ {"SetBpfDatalink", Func, 0},
+ {"SetBpfHeadercmpl", Func, 0},
+ {"SetBpfImmediate", Func, 0},
+ {"SetBpfInterface", Func, 0},
+ {"SetBpfPromisc", Func, 0},
+ {"SetBpfTimeout", Func, 0},
+ {"SetCurrentDirectory", Func, 0},
+ {"SetEndOfFile", Func, 0},
+ {"SetEnvironmentVariable", Func, 0},
+ {"SetFileAttributes", Func, 0},
+ {"SetFileCompletionNotificationModes", Func, 2},
+ {"SetFilePointer", Func, 0},
+ {"SetFileTime", Func, 0},
+ {"SetHandleInformation", Func, 0},
+ {"SetKevent", Func, 0},
+ {"SetLsfPromisc", Func, 0},
+ {"SetNonblock", Func, 0},
+ {"Setdomainname", Func, 0},
+ {"Setegid", Func, 0},
+ {"Setenv", Func, 0},
+ {"Seteuid", Func, 0},
+ {"Setfsgid", Func, 0},
+ {"Setfsuid", Func, 0},
+ {"Setgid", Func, 0},
+ {"Setgroups", Func, 0},
+ {"Sethostname", Func, 0},
+ {"Setlogin", Func, 0},
+ {"Setpgid", Func, 0},
+ {"Setpriority", Func, 0},
+ {"Setprivexec", Func, 0},
+ {"Setregid", Func, 0},
+ {"Setresgid", Func, 0},
+ {"Setresuid", Func, 0},
+ {"Setreuid", Func, 0},
+ {"Setrlimit", Func, 0},
+ {"Setsid", Func, 0},
+ {"Setsockopt", Func, 0},
+ {"SetsockoptByte", Func, 0},
+ {"SetsockoptICMPv6Filter", Func, 2},
+ {"SetsockoptIPMreq", Func, 0},
+ {"SetsockoptIPMreqn", Func, 0},
+ {"SetsockoptIPv6Mreq", Func, 0},
+ {"SetsockoptInet4Addr", Func, 0},
+ {"SetsockoptInt", Func, 0},
+ {"SetsockoptLinger", Func, 0},
+ {"SetsockoptString", Func, 0},
+ {"SetsockoptTimeval", Func, 0},
+ {"Settimeofday", Func, 0},
+ {"Setuid", Func, 0},
+ {"Setxattr", Func, 1},
+ {"Shutdown", Func, 0},
+ {"SidTypeAlias", Const, 0},
+ {"SidTypeComputer", Const, 0},
+ {"SidTypeDeletedAccount", Const, 0},
+ {"SidTypeDomain", Const, 0},
+ {"SidTypeGroup", Const, 0},
+ {"SidTypeInvalid", Const, 0},
+ {"SidTypeLabel", Const, 0},
+ {"SidTypeUnknown", Const, 0},
+ {"SidTypeUser", Const, 0},
+ {"SidTypeWellKnownGroup", Const, 0},
+ {"Signal", Type, 0},
+ {"SizeofBpfHdr", Const, 0},
+ {"SizeofBpfInsn", Const, 0},
+ {"SizeofBpfProgram", Const, 0},
+ {"SizeofBpfStat", Const, 0},
+ {"SizeofBpfVersion", Const, 0},
+ {"SizeofBpfZbuf", Const, 0},
+ {"SizeofBpfZbufHeader", Const, 0},
+ {"SizeofCmsghdr", Const, 0},
+ {"SizeofICMPv6Filter", Const, 2},
+ {"SizeofIPMreq", Const, 0},
+ {"SizeofIPMreqn", Const, 0},
+ {"SizeofIPv6MTUInfo", Const, 2},
+ {"SizeofIPv6Mreq", Const, 0},
+ {"SizeofIfAddrmsg", Const, 0},
+ {"SizeofIfAnnounceMsghdr", Const, 1},
+ {"SizeofIfData", Const, 0},
+ {"SizeofIfInfomsg", Const, 0},
+ {"SizeofIfMsghdr", Const, 0},
+ {"SizeofIfaMsghdr", Const, 0},
+ {"SizeofIfmaMsghdr", Const, 0},
+ {"SizeofIfmaMsghdr2", Const, 0},
+ {"SizeofInet4Pktinfo", Const, 0},
+ {"SizeofInet6Pktinfo", Const, 0},
+ {"SizeofInotifyEvent", Const, 0},
+ {"SizeofLinger", Const, 0},
+ {"SizeofMsghdr", Const, 0},
+ {"SizeofNlAttr", Const, 0},
+ {"SizeofNlMsgerr", Const, 0},
+ {"SizeofNlMsghdr", Const, 0},
+ {"SizeofRtAttr", Const, 0},
+ {"SizeofRtGenmsg", Const, 0},
+ {"SizeofRtMetrics", Const, 0},
+ {"SizeofRtMsg", Const, 0},
+ {"SizeofRtMsghdr", Const, 0},
+ {"SizeofRtNexthop", Const, 0},
+ {"SizeofSockFilter", Const, 0},
+ {"SizeofSockFprog", Const, 0},
+ {"SizeofSockaddrAny", Const, 0},
+ {"SizeofSockaddrDatalink", Const, 0},
+ {"SizeofSockaddrInet4", Const, 0},
+ {"SizeofSockaddrInet6", Const, 0},
+ {"SizeofSockaddrLinklayer", Const, 0},
+ {"SizeofSockaddrNetlink", Const, 0},
+ {"SizeofSockaddrUnix", Const, 0},
+ {"SizeofTCPInfo", Const, 1},
+ {"SizeofUcred", Const, 0},
+ {"SlicePtrFromStrings", Func, 1},
+ {"SockFilter", Type, 0},
+ {"SockFilter.Code", Field, 0},
+ {"SockFilter.Jf", Field, 0},
+ {"SockFilter.Jt", Field, 0},
+ {"SockFilter.K", Field, 0},
+ {"SockFprog", Type, 0},
+ {"SockFprog.Filter", Field, 0},
+ {"SockFprog.Len", Field, 0},
+ {"SockFprog.Pad_cgo_0", Field, 0},
+ {"Sockaddr", Type, 0},
+ {"SockaddrDatalink", Type, 0},
+ {"SockaddrDatalink.Alen", Field, 0},
+ {"SockaddrDatalink.Data", Field, 0},
+ {"SockaddrDatalink.Family", Field, 0},
+ {"SockaddrDatalink.Index", Field, 0},
+ {"SockaddrDatalink.Len", Field, 0},
+ {"SockaddrDatalink.Nlen", Field, 0},
+ {"SockaddrDatalink.Slen", Field, 0},
+ {"SockaddrDatalink.Type", Field, 0},
+ {"SockaddrGen", Type, 0},
+ {"SockaddrInet4", Type, 0},
+ {"SockaddrInet4.Addr", Field, 0},
+ {"SockaddrInet4.Port", Field, 0},
+ {"SockaddrInet6", Type, 0},
+ {"SockaddrInet6.Addr", Field, 0},
+ {"SockaddrInet6.Port", Field, 0},
+ {"SockaddrInet6.ZoneId", Field, 0},
+ {"SockaddrLinklayer", Type, 0},
+ {"SockaddrLinklayer.Addr", Field, 0},
+ {"SockaddrLinklayer.Halen", Field, 0},
+ {"SockaddrLinklayer.Hatype", Field, 0},
+ {"SockaddrLinklayer.Ifindex", Field, 0},
+ {"SockaddrLinklayer.Pkttype", Field, 0},
+ {"SockaddrLinklayer.Protocol", Field, 0},
+ {"SockaddrNetlink", Type, 0},
+ {"SockaddrNetlink.Family", Field, 0},
+ {"SockaddrNetlink.Groups", Field, 0},
+ {"SockaddrNetlink.Pad", Field, 0},
+ {"SockaddrNetlink.Pid", Field, 0},
+ {"SockaddrUnix", Type, 0},
+ {"SockaddrUnix.Name", Field, 0},
+ {"Socket", Func, 0},
+ {"SocketControlMessage", Type, 0},
+ {"SocketControlMessage.Data", Field, 0},
+ {"SocketControlMessage.Header", Field, 0},
+ {"SocketDisableIPv6", Var, 0},
+ {"Socketpair", Func, 0},
+ {"Splice", Func, 0},
+ {"StartProcess", Func, 0},
+ {"StartupInfo", Type, 0},
+ {"StartupInfo.Cb", Field, 0},
+ {"StartupInfo.Desktop", Field, 0},
+ {"StartupInfo.FillAttribute", Field, 0},
+ {"StartupInfo.Flags", Field, 0},
+ {"StartupInfo.ShowWindow", Field, 0},
+ {"StartupInfo.StdErr", Field, 0},
+ {"StartupInfo.StdInput", Field, 0},
+ {"StartupInfo.StdOutput", Field, 0},
+ {"StartupInfo.Title", Field, 0},
+ {"StartupInfo.X", Field, 0},
+ {"StartupInfo.XCountChars", Field, 0},
+ {"StartupInfo.XSize", Field, 0},
+ {"StartupInfo.Y", Field, 0},
+ {"StartupInfo.YCountChars", Field, 0},
+ {"StartupInfo.YSize", Field, 0},
+ {"Stat", Func, 0},
+ {"Stat_t", Type, 0},
+ {"Stat_t.Atim", Field, 0},
+ {"Stat_t.Atim_ext", Field, 12},
+ {"Stat_t.Atimespec", Field, 0},
+ {"Stat_t.Birthtimespec", Field, 0},
+ {"Stat_t.Blksize", Field, 0},
+ {"Stat_t.Blocks", Field, 0},
+ {"Stat_t.Btim_ext", Field, 12},
+ {"Stat_t.Ctim", Field, 0},
+ {"Stat_t.Ctim_ext", Field, 12},
+ {"Stat_t.Ctimespec", Field, 0},
+ {"Stat_t.Dev", Field, 0},
+ {"Stat_t.Flags", Field, 0},
+ {"Stat_t.Gen", Field, 0},
+ {"Stat_t.Gid", Field, 0},
+ {"Stat_t.Ino", Field, 0},
+ {"Stat_t.Lspare", Field, 0},
+ {"Stat_t.Lspare0", Field, 2},
+ {"Stat_t.Lspare1", Field, 2},
+ {"Stat_t.Mode", Field, 0},
+ {"Stat_t.Mtim", Field, 0},
+ {"Stat_t.Mtim_ext", Field, 12},
+ {"Stat_t.Mtimespec", Field, 0},
+ {"Stat_t.Nlink", Field, 0},
+ {"Stat_t.Pad_cgo_0", Field, 0},
+ {"Stat_t.Pad_cgo_1", Field, 0},
+ {"Stat_t.Pad_cgo_2", Field, 0},
+ {"Stat_t.Padding0", Field, 12},
+ {"Stat_t.Padding1", Field, 12},
+ {"Stat_t.Qspare", Field, 0},
+ {"Stat_t.Rdev", Field, 0},
+ {"Stat_t.Size", Field, 0},
+ {"Stat_t.Spare", Field, 2},
+ {"Stat_t.Uid", Field, 0},
+ {"Stat_t.X__pad0", Field, 0},
+ {"Stat_t.X__pad1", Field, 0},
+ {"Stat_t.X__pad2", Field, 0},
+ {"Stat_t.X__st_birthtim", Field, 2},
+ {"Stat_t.X__st_ino", Field, 0},
+ {"Stat_t.X__unused", Field, 0},
+ {"Statfs", Func, 0},
+ {"Statfs_t", Type, 0},
+ {"Statfs_t.Asyncreads", Field, 0},
+ {"Statfs_t.Asyncwrites", Field, 0},
+ {"Statfs_t.Bavail", Field, 0},
+ {"Statfs_t.Bfree", Field, 0},
+ {"Statfs_t.Blocks", Field, 0},
+ {"Statfs_t.Bsize", Field, 0},
+ {"Statfs_t.Charspare", Field, 0},
+ {"Statfs_t.F_asyncreads", Field, 2},
+ {"Statfs_t.F_asyncwrites", Field, 2},
+ {"Statfs_t.F_bavail", Field, 2},
+ {"Statfs_t.F_bfree", Field, 2},
+ {"Statfs_t.F_blocks", Field, 2},
+ {"Statfs_t.F_bsize", Field, 2},
+ {"Statfs_t.F_ctime", Field, 2},
+ {"Statfs_t.F_favail", Field, 2},
+ {"Statfs_t.F_ffree", Field, 2},
+ {"Statfs_t.F_files", Field, 2},
+ {"Statfs_t.F_flags", Field, 2},
+ {"Statfs_t.F_fsid", Field, 2},
+ {"Statfs_t.F_fstypename", Field, 2},
+ {"Statfs_t.F_iosize", Field, 2},
+ {"Statfs_t.F_mntfromname", Field, 2},
+ {"Statfs_t.F_mntfromspec", Field, 3},
+ {"Statfs_t.F_mntonname", Field, 2},
+ {"Statfs_t.F_namemax", Field, 2},
+ {"Statfs_t.F_owner", Field, 2},
+ {"Statfs_t.F_spare", Field, 2},
+ {"Statfs_t.F_syncreads", Field, 2},
+ {"Statfs_t.F_syncwrites", Field, 2},
+ {"Statfs_t.Ffree", Field, 0},
+ {"Statfs_t.Files", Field, 0},
+ {"Statfs_t.Flags", Field, 0},
+ {"Statfs_t.Frsize", Field, 0},
+ {"Statfs_t.Fsid", Field, 0},
+ {"Statfs_t.Fssubtype", Field, 0},
+ {"Statfs_t.Fstypename", Field, 0},
+ {"Statfs_t.Iosize", Field, 0},
+ {"Statfs_t.Mntfromname", Field, 0},
+ {"Statfs_t.Mntonname", Field, 0},
+ {"Statfs_t.Mount_info", Field, 2},
+ {"Statfs_t.Namelen", Field, 0},
+ {"Statfs_t.Namemax", Field, 0},
+ {"Statfs_t.Owner", Field, 0},
+ {"Statfs_t.Pad_cgo_0", Field, 0},
+ {"Statfs_t.Pad_cgo_1", Field, 2},
+ {"Statfs_t.Reserved", Field, 0},
+ {"Statfs_t.Spare", Field, 0},
+ {"Statfs_t.Syncreads", Field, 0},
+ {"Statfs_t.Syncwrites", Field, 0},
+ {"Statfs_t.Type", Field, 0},
+ {"Statfs_t.Version", Field, 0},
+ {"Stderr", Var, 0},
+ {"Stdin", Var, 0},
+ {"Stdout", Var, 0},
+ {"StringBytePtr", Func, 0},
+ {"StringByteSlice", Func, 0},
+ {"StringSlicePtr", Func, 0},
+ {"StringToSid", Func, 0},
+ {"StringToUTF16", Func, 0},
+ {"StringToUTF16Ptr", Func, 0},
+ {"Symlink", Func, 0},
+ {"Sync", Func, 0},
+ {"SyncFileRange", Func, 0},
+ {"SysProcAttr", Type, 0},
+ {"SysProcAttr.AdditionalInheritedHandles", Field, 17},
+ {"SysProcAttr.AmbientCaps", Field, 9},
+ {"SysProcAttr.CgroupFD", Field, 20},
+ {"SysProcAttr.Chroot", Field, 0},
+ {"SysProcAttr.Cloneflags", Field, 2},
+ {"SysProcAttr.CmdLine", Field, 0},
+ {"SysProcAttr.CreationFlags", Field, 1},
+ {"SysProcAttr.Credential", Field, 0},
+ {"SysProcAttr.Ctty", Field, 1},
+ {"SysProcAttr.Foreground", Field, 5},
+ {"SysProcAttr.GidMappings", Field, 4},
+ {"SysProcAttr.GidMappingsEnableSetgroups", Field, 5},
+ {"SysProcAttr.HideWindow", Field, 0},
+ {"SysProcAttr.Jail", Field, 21},
+ {"SysProcAttr.NoInheritHandles", Field, 16},
+ {"SysProcAttr.Noctty", Field, 0},
+ {"SysProcAttr.ParentProcess", Field, 17},
+ {"SysProcAttr.Pdeathsig", Field, 0},
+ {"SysProcAttr.Pgid", Field, 5},
+ {"SysProcAttr.PidFD", Field, 22},
+ {"SysProcAttr.ProcessAttributes", Field, 13},
+ {"SysProcAttr.Ptrace", Field, 0},
+ {"SysProcAttr.Setctty", Field, 0},
+ {"SysProcAttr.Setpgid", Field, 0},
+ {"SysProcAttr.Setsid", Field, 0},
+ {"SysProcAttr.ThreadAttributes", Field, 13},
+ {"SysProcAttr.Token", Field, 10},
+ {"SysProcAttr.UidMappings", Field, 4},
+ {"SysProcAttr.Unshareflags", Field, 7},
+ {"SysProcAttr.UseCgroupFD", Field, 20},
+ {"SysProcIDMap", Type, 4},
+ {"SysProcIDMap.ContainerID", Field, 4},
+ {"SysProcIDMap.HostID", Field, 4},
+ {"SysProcIDMap.Size", Field, 4},
+ {"Syscall", Func, 0},
+ {"Syscall12", Func, 0},
+ {"Syscall15", Func, 0},
+ {"Syscall18", Func, 12},
+ {"Syscall6", Func, 0},
+ {"Syscall9", Func, 0},
+ {"SyscallN", Func, 18},
+ {"Sysctl", Func, 0},
+ {"SysctlUint32", Func, 0},
+ {"Sysctlnode", Type, 2},
+ {"Sysctlnode.Flags", Field, 2},
+ {"Sysctlnode.Name", Field, 2},
+ {"Sysctlnode.Num", Field, 2},
+ {"Sysctlnode.Un", Field, 2},
+ {"Sysctlnode.Ver", Field, 2},
+ {"Sysctlnode.X__rsvd", Field, 2},
+ {"Sysctlnode.X_sysctl_desc", Field, 2},
+ {"Sysctlnode.X_sysctl_func", Field, 2},
+ {"Sysctlnode.X_sysctl_parent", Field, 2},
+ {"Sysctlnode.X_sysctl_size", Field, 2},
+ {"Sysinfo", Func, 0},
+ {"Sysinfo_t", Type, 0},
+ {"Sysinfo_t.Bufferram", Field, 0},
+ {"Sysinfo_t.Freehigh", Field, 0},
+ {"Sysinfo_t.Freeram", Field, 0},
+ {"Sysinfo_t.Freeswap", Field, 0},
+ {"Sysinfo_t.Loads", Field, 0},
+ {"Sysinfo_t.Pad", Field, 0},
+ {"Sysinfo_t.Pad_cgo_0", Field, 0},
+ {"Sysinfo_t.Pad_cgo_1", Field, 0},
+ {"Sysinfo_t.Procs", Field, 0},
+ {"Sysinfo_t.Sharedram", Field, 0},
+ {"Sysinfo_t.Totalhigh", Field, 0},
+ {"Sysinfo_t.Totalram", Field, 0},
+ {"Sysinfo_t.Totalswap", Field, 0},
+ {"Sysinfo_t.Unit", Field, 0},
+ {"Sysinfo_t.Uptime", Field, 0},
+ {"Sysinfo_t.X_f", Field, 0},
+ {"Systemtime", Type, 0},
+ {"Systemtime.Day", Field, 0},
+ {"Systemtime.DayOfWeek", Field, 0},
+ {"Systemtime.Hour", Field, 0},
+ {"Systemtime.Milliseconds", Field, 0},
+ {"Systemtime.Minute", Field, 0},
+ {"Systemtime.Month", Field, 0},
+ {"Systemtime.Second", Field, 0},
+ {"Systemtime.Year", Field, 0},
+ {"TCGETS", Const, 0},
+ {"TCIFLUSH", Const, 1},
+ {"TCIOFLUSH", Const, 1},
+ {"TCOFLUSH", Const, 1},
+ {"TCPInfo", Type, 1},
+ {"TCPInfo.Advmss", Field, 1},
+ {"TCPInfo.Ato", Field, 1},
+ {"TCPInfo.Backoff", Field, 1},
+ {"TCPInfo.Ca_state", Field, 1},
+ {"TCPInfo.Fackets", Field, 1},
+ {"TCPInfo.Last_ack_recv", Field, 1},
+ {"TCPInfo.Last_ack_sent", Field, 1},
+ {"TCPInfo.Last_data_recv", Field, 1},
+ {"TCPInfo.Last_data_sent", Field, 1},
+ {"TCPInfo.Lost", Field, 1},
+ {"TCPInfo.Options", Field, 1},
+ {"TCPInfo.Pad_cgo_0", Field, 1},
+ {"TCPInfo.Pmtu", Field, 1},
+ {"TCPInfo.Probes", Field, 1},
+ {"TCPInfo.Rcv_mss", Field, 1},
+ {"TCPInfo.Rcv_rtt", Field, 1},
+ {"TCPInfo.Rcv_space", Field, 1},
+ {"TCPInfo.Rcv_ssthresh", Field, 1},
+ {"TCPInfo.Reordering", Field, 1},
+ {"TCPInfo.Retrans", Field, 1},
+ {"TCPInfo.Retransmits", Field, 1},
+ {"TCPInfo.Rto", Field, 1},
+ {"TCPInfo.Rtt", Field, 1},
+ {"TCPInfo.Rttvar", Field, 1},
+ {"TCPInfo.Sacked", Field, 1},
+ {"TCPInfo.Snd_cwnd", Field, 1},
+ {"TCPInfo.Snd_mss", Field, 1},
+ {"TCPInfo.Snd_ssthresh", Field, 1},
+ {"TCPInfo.State", Field, 1},
+ {"TCPInfo.Total_retrans", Field, 1},
+ {"TCPInfo.Unacked", Field, 1},
+ {"TCPKeepalive", Type, 3},
+ {"TCPKeepalive.Interval", Field, 3},
+ {"TCPKeepalive.OnOff", Field, 3},
+ {"TCPKeepalive.Time", Field, 3},
+ {"TCP_CA_NAME_MAX", Const, 0},
+ {"TCP_CONGCTL", Const, 1},
+ {"TCP_CONGESTION", Const, 0},
+ {"TCP_CONNECTIONTIMEOUT", Const, 0},
+ {"TCP_CORK", Const, 0},
+ {"TCP_DEFER_ACCEPT", Const, 0},
+ {"TCP_ENABLE_ECN", Const, 16},
+ {"TCP_INFO", Const, 0},
+ {"TCP_KEEPALIVE", Const, 0},
+ {"TCP_KEEPCNT", Const, 0},
+ {"TCP_KEEPIDLE", Const, 0},
+ {"TCP_KEEPINIT", Const, 1},
+ {"TCP_KEEPINTVL", Const, 0},
+ {"TCP_LINGER2", Const, 0},
+ {"TCP_MAXBURST", Const, 0},
+ {"TCP_MAXHLEN", Const, 0},
+ {"TCP_MAXOLEN", Const, 0},
+ {"TCP_MAXSEG", Const, 0},
+ {"TCP_MAXWIN", Const, 0},
+ {"TCP_MAX_SACK", Const, 0},
+ {"TCP_MAX_WINSHIFT", Const, 0},
+ {"TCP_MD5SIG", Const, 0},
+ {"TCP_MD5SIG_MAXKEYLEN", Const, 0},
+ {"TCP_MINMSS", Const, 0},
+ {"TCP_MINMSSOVERLOAD", Const, 0},
+ {"TCP_MSS", Const, 0},
+ {"TCP_NODELAY", Const, 0},
+ {"TCP_NOOPT", Const, 0},
+ {"TCP_NOPUSH", Const, 0},
+ {"TCP_NOTSENT_LOWAT", Const, 16},
+ {"TCP_NSTATES", Const, 1},
+ {"TCP_QUICKACK", Const, 0},
+ {"TCP_RXT_CONNDROPTIME", Const, 0},
+ {"TCP_RXT_FINDROP", Const, 0},
+ {"TCP_SACK_ENABLE", Const, 1},
+ {"TCP_SENDMOREACKS", Const, 16},
+ {"TCP_SYNCNT", Const, 0},
+ {"TCP_VENDOR", Const, 3},
+ {"TCP_WINDOW_CLAMP", Const, 0},
+ {"TCSAFLUSH", Const, 1},
+ {"TCSETS", Const, 0},
+ {"TF_DISCONNECT", Const, 0},
+ {"TF_REUSE_SOCKET", Const, 0},
+ {"TF_USE_DEFAULT_WORKER", Const, 0},
+ {"TF_USE_KERNEL_APC", Const, 0},
+ {"TF_USE_SYSTEM_THREAD", Const, 0},
+ {"TF_WRITE_BEHIND", Const, 0},
+ {"TH32CS_INHERIT", Const, 4},
+ {"TH32CS_SNAPALL", Const, 4},
+ {"TH32CS_SNAPHEAPLIST", Const, 4},
+ {"TH32CS_SNAPMODULE", Const, 4},
+ {"TH32CS_SNAPMODULE32", Const, 4},
+ {"TH32CS_SNAPPROCESS", Const, 4},
+ {"TH32CS_SNAPTHREAD", Const, 4},
+ {"TIME_ZONE_ID_DAYLIGHT", Const, 0},
+ {"TIME_ZONE_ID_STANDARD", Const, 0},
+ {"TIME_ZONE_ID_UNKNOWN", Const, 0},
+ {"TIOCCBRK", Const, 0},
+ {"TIOCCDTR", Const, 0},
+ {"TIOCCONS", Const, 0},
+ {"TIOCDCDTIMESTAMP", Const, 0},
+ {"TIOCDRAIN", Const, 0},
+ {"TIOCDSIMICROCODE", Const, 0},
+ {"TIOCEXCL", Const, 0},
+ {"TIOCEXT", Const, 0},
+ {"TIOCFLAG_CDTRCTS", Const, 1},
+ {"TIOCFLAG_CLOCAL", Const, 1},
+ {"TIOCFLAG_CRTSCTS", Const, 1},
+ {"TIOCFLAG_MDMBUF", Const, 1},
+ {"TIOCFLAG_PPS", Const, 1},
+ {"TIOCFLAG_SOFTCAR", Const, 1},
+ {"TIOCFLUSH", Const, 0},
+ {"TIOCGDEV", Const, 0},
+ {"TIOCGDRAINWAIT", Const, 0},
+ {"TIOCGETA", Const, 0},
+ {"TIOCGETD", Const, 0},
+ {"TIOCGFLAGS", Const, 1},
+ {"TIOCGICOUNT", Const, 0},
+ {"TIOCGLCKTRMIOS", Const, 0},
+ {"TIOCGLINED", Const, 1},
+ {"TIOCGPGRP", Const, 0},
+ {"TIOCGPTN", Const, 0},
+ {"TIOCGQSIZE", Const, 1},
+ {"TIOCGRANTPT", Const, 1},
+ {"TIOCGRS485", Const, 0},
+ {"TIOCGSERIAL", Const, 0},
+ {"TIOCGSID", Const, 0},
+ {"TIOCGSIZE", Const, 1},
+ {"TIOCGSOFTCAR", Const, 0},
+ {"TIOCGTSTAMP", Const, 1},
+ {"TIOCGWINSZ", Const, 0},
+ {"TIOCINQ", Const, 0},
+ {"TIOCIXOFF", Const, 0},
+ {"TIOCIXON", Const, 0},
+ {"TIOCLINUX", Const, 0},
+ {"TIOCMBIC", Const, 0},
+ {"TIOCMBIS", Const, 0},
+ {"TIOCMGDTRWAIT", Const, 0},
+ {"TIOCMGET", Const, 0},
+ {"TIOCMIWAIT", Const, 0},
+ {"TIOCMODG", Const, 0},
+ {"TIOCMODS", Const, 0},
+ {"TIOCMSDTRWAIT", Const, 0},
+ {"TIOCMSET", Const, 0},
+ {"TIOCM_CAR", Const, 0},
+ {"TIOCM_CD", Const, 0},
+ {"TIOCM_CTS", Const, 0},
+ {"TIOCM_DCD", Const, 0},
+ {"TIOCM_DSR", Const, 0},
+ {"TIOCM_DTR", Const, 0},
+ {"TIOCM_LE", Const, 0},
+ {"TIOCM_RI", Const, 0},
+ {"TIOCM_RNG", Const, 0},
+ {"TIOCM_RTS", Const, 0},
+ {"TIOCM_SR", Const, 0},
+ {"TIOCM_ST", Const, 0},
+ {"TIOCNOTTY", Const, 0},
+ {"TIOCNXCL", Const, 0},
+ {"TIOCOUTQ", Const, 0},
+ {"TIOCPKT", Const, 0},
+ {"TIOCPKT_DATA", Const, 0},
+ {"TIOCPKT_DOSTOP", Const, 0},
+ {"TIOCPKT_FLUSHREAD", Const, 0},
+ {"TIOCPKT_FLUSHWRITE", Const, 0},
+ {"TIOCPKT_IOCTL", Const, 0},
+ {"TIOCPKT_NOSTOP", Const, 0},
+ {"TIOCPKT_START", Const, 0},
+ {"TIOCPKT_STOP", Const, 0},
+ {"TIOCPTMASTER", Const, 0},
+ {"TIOCPTMGET", Const, 1},
+ {"TIOCPTSNAME", Const, 1},
+ {"TIOCPTYGNAME", Const, 0},
+ {"TIOCPTYGRANT", Const, 0},
+ {"TIOCPTYUNLK", Const, 0},
+ {"TIOCRCVFRAME", Const, 1},
+ {"TIOCREMOTE", Const, 0},
+ {"TIOCSBRK", Const, 0},
+ {"TIOCSCONS", Const, 0},
+ {"TIOCSCTTY", Const, 0},
+ {"TIOCSDRAINWAIT", Const, 0},
+ {"TIOCSDTR", Const, 0},
+ {"TIOCSERCONFIG", Const, 0},
+ {"TIOCSERGETLSR", Const, 0},
+ {"TIOCSERGETMULTI", Const, 0},
+ {"TIOCSERGSTRUCT", Const, 0},
+ {"TIOCSERGWILD", Const, 0},
+ {"TIOCSERSETMULTI", Const, 0},
+ {"TIOCSERSWILD", Const, 0},
+ {"TIOCSER_TEMT", Const, 0},
+ {"TIOCSETA", Const, 0},
+ {"TIOCSETAF", Const, 0},
+ {"TIOCSETAW", Const, 0},
+ {"TIOCSETD", Const, 0},
+ {"TIOCSFLAGS", Const, 1},
+ {"TIOCSIG", Const, 0},
+ {"TIOCSLCKTRMIOS", Const, 0},
+ {"TIOCSLINED", Const, 1},
+ {"TIOCSPGRP", Const, 0},
+ {"TIOCSPTLCK", Const, 0},
+ {"TIOCSQSIZE", Const, 1},
+ {"TIOCSRS485", Const, 0},
+ {"TIOCSSERIAL", Const, 0},
+ {"TIOCSSIZE", Const, 1},
+ {"TIOCSSOFTCAR", Const, 0},
+ {"TIOCSTART", Const, 0},
+ {"TIOCSTAT", Const, 0},
+ {"TIOCSTI", Const, 0},
+ {"TIOCSTOP", Const, 0},
+ {"TIOCSTSTAMP", Const, 1},
+ {"TIOCSWINSZ", Const, 0},
+ {"TIOCTIMESTAMP", Const, 0},
+ {"TIOCUCNTL", Const, 0},
+ {"TIOCVHANGUP", Const, 0},
+ {"TIOCXMTFRAME", Const, 1},
+ {"TOKEN_ADJUST_DEFAULT", Const, 0},
+ {"TOKEN_ADJUST_GROUPS", Const, 0},
+ {"TOKEN_ADJUST_PRIVILEGES", Const, 0},
+ {"TOKEN_ADJUST_SESSIONID", Const, 11},
+ {"TOKEN_ALL_ACCESS", Const, 0},
+ {"TOKEN_ASSIGN_PRIMARY", Const, 0},
+ {"TOKEN_DUPLICATE", Const, 0},
+ {"TOKEN_EXECUTE", Const, 0},
+ {"TOKEN_IMPERSONATE", Const, 0},
+ {"TOKEN_QUERY", Const, 0},
+ {"TOKEN_QUERY_SOURCE", Const, 0},
+ {"TOKEN_READ", Const, 0},
+ {"TOKEN_WRITE", Const, 0},
+ {"TOSTOP", Const, 0},
+ {"TRUNCATE_EXISTING", Const, 0},
+ {"TUNATTACHFILTER", Const, 0},
+ {"TUNDETACHFILTER", Const, 0},
+ {"TUNGETFEATURES", Const, 0},
+ {"TUNGETIFF", Const, 0},
+ {"TUNGETSNDBUF", Const, 0},
+ {"TUNGETVNETHDRSZ", Const, 0},
+ {"TUNSETDEBUG", Const, 0},
+ {"TUNSETGROUP", Const, 0},
+ {"TUNSETIFF", Const, 0},
+ {"TUNSETLINK", Const, 0},
+ {"TUNSETNOCSUM", Const, 0},
+ {"TUNSETOFFLOAD", Const, 0},
+ {"TUNSETOWNER", Const, 0},
+ {"TUNSETPERSIST", Const, 0},
+ {"TUNSETSNDBUF", Const, 0},
+ {"TUNSETTXFILTER", Const, 0},
+ {"TUNSETVNETHDRSZ", Const, 0},
+ {"Tee", Func, 0},
+ {"TerminateProcess", Func, 0},
+ {"Termios", Type, 0},
+ {"Termios.Cc", Field, 0},
+ {"Termios.Cflag", Field, 0},
+ {"Termios.Iflag", Field, 0},
+ {"Termios.Ispeed", Field, 0},
+ {"Termios.Lflag", Field, 0},
+ {"Termios.Line", Field, 0},
+ {"Termios.Oflag", Field, 0},
+ {"Termios.Ospeed", Field, 0},
+ {"Termios.Pad_cgo_0", Field, 0},
+ {"Tgkill", Func, 0},
+ {"Time", Func, 0},
+ {"Time_t", Type, 0},
+ {"Times", Func, 0},
+ {"Timespec", Type, 0},
+ {"Timespec.Nsec", Field, 0},
+ {"Timespec.Pad_cgo_0", Field, 2},
+ {"Timespec.Sec", Field, 0},
+ {"TimespecToNsec", Func, 0},
+ {"Timeval", Type, 0},
+ {"Timeval.Pad_cgo_0", Field, 0},
+ {"Timeval.Sec", Field, 0},
+ {"Timeval.Usec", Field, 0},
+ {"Timeval32", Type, 0},
+ {"Timeval32.Sec", Field, 0},
+ {"Timeval32.Usec", Field, 0},
+ {"TimevalToNsec", Func, 0},
+ {"Timex", Type, 0},
+ {"Timex.Calcnt", Field, 0},
+ {"Timex.Constant", Field, 0},
+ {"Timex.Errcnt", Field, 0},
+ {"Timex.Esterror", Field, 0},
+ {"Timex.Freq", Field, 0},
+ {"Timex.Jitcnt", Field, 0},
+ {"Timex.Jitter", Field, 0},
+ {"Timex.Maxerror", Field, 0},
+ {"Timex.Modes", Field, 0},
+ {"Timex.Offset", Field, 0},
+ {"Timex.Pad_cgo_0", Field, 0},
+ {"Timex.Pad_cgo_1", Field, 0},
+ {"Timex.Pad_cgo_2", Field, 0},
+ {"Timex.Pad_cgo_3", Field, 0},
+ {"Timex.Ppsfreq", Field, 0},
+ {"Timex.Precision", Field, 0},
+ {"Timex.Shift", Field, 0},
+ {"Timex.Stabil", Field, 0},
+ {"Timex.Status", Field, 0},
+ {"Timex.Stbcnt", Field, 0},
+ {"Timex.Tai", Field, 0},
+ {"Timex.Tick", Field, 0},
+ {"Timex.Time", Field, 0},
+ {"Timex.Tolerance", Field, 0},
+ {"Timezoneinformation", Type, 0},
+ {"Timezoneinformation.Bias", Field, 0},
+ {"Timezoneinformation.DaylightBias", Field, 0},
+ {"Timezoneinformation.DaylightDate", Field, 0},
+ {"Timezoneinformation.DaylightName", Field, 0},
+ {"Timezoneinformation.StandardBias", Field, 0},
+ {"Timezoneinformation.StandardDate", Field, 0},
+ {"Timezoneinformation.StandardName", Field, 0},
+ {"Tms", Type, 0},
+ {"Tms.Cstime", Field, 0},
+ {"Tms.Cutime", Field, 0},
+ {"Tms.Stime", Field, 0},
+ {"Tms.Utime", Field, 0},
+ {"Token", Type, 0},
+ {"TokenAccessInformation", Const, 0},
+ {"TokenAuditPolicy", Const, 0},
+ {"TokenDefaultDacl", Const, 0},
+ {"TokenElevation", Const, 0},
+ {"TokenElevationType", Const, 0},
+ {"TokenGroups", Const, 0},
+ {"TokenGroupsAndPrivileges", Const, 0},
+ {"TokenHasRestrictions", Const, 0},
+ {"TokenImpersonationLevel", Const, 0},
+ {"TokenIntegrityLevel", Const, 0},
+ {"TokenLinkedToken", Const, 0},
+ {"TokenLogonSid", Const, 0},
+ {"TokenMandatoryPolicy", Const, 0},
+ {"TokenOrigin", Const, 0},
+ {"TokenOwner", Const, 0},
+ {"TokenPrimaryGroup", Const, 0},
+ {"TokenPrivileges", Const, 0},
+ {"TokenRestrictedSids", Const, 0},
+ {"TokenSandBoxInert", Const, 0},
+ {"TokenSessionId", Const, 0},
+ {"TokenSessionReference", Const, 0},
+ {"TokenSource", Const, 0},
+ {"TokenStatistics", Const, 0},
+ {"TokenType", Const, 0},
+ {"TokenUIAccess", Const, 0},
+ {"TokenUser", Const, 0},
+ {"TokenVirtualizationAllowed", Const, 0},
+ {"TokenVirtualizationEnabled", Const, 0},
+ {"Tokenprimarygroup", Type, 0},
+ {"Tokenprimarygroup.PrimaryGroup", Field, 0},
+ {"Tokenuser", Type, 0},
+ {"Tokenuser.User", Field, 0},
+ {"TranslateAccountName", Func, 0},
+ {"TranslateName", Func, 0},
+ {"TransmitFile", Func, 0},
+ {"TransmitFileBuffers", Type, 0},
+ {"TransmitFileBuffers.Head", Field, 0},
+ {"TransmitFileBuffers.HeadLength", Field, 0},
+ {"TransmitFileBuffers.Tail", Field, 0},
+ {"TransmitFileBuffers.TailLength", Field, 0},
+ {"Truncate", Func, 0},
+ {"UNIX_PATH_MAX", Const, 12},
+ {"USAGE_MATCH_TYPE_AND", Const, 0},
+ {"USAGE_MATCH_TYPE_OR", Const, 0},
+ {"UTF16FromString", Func, 1},
+ {"UTF16PtrFromString", Func, 1},
+ {"UTF16ToString", Func, 0},
+ {"Ucred", Type, 0},
+ {"Ucred.Gid", Field, 0},
+ {"Ucred.Pid", Field, 0},
+ {"Ucred.Uid", Field, 0},
+ {"Umask", Func, 0},
+ {"Uname", Func, 0},
+ {"Undelete", Func, 0},
+ {"UnixCredentials", Func, 0},
+ {"UnixRights", Func, 0},
+ {"Unlink", Func, 0},
+ {"Unlinkat", Func, 0},
+ {"UnmapViewOfFile", Func, 0},
+ {"Unmount", Func, 0},
+ {"Unsetenv", Func, 4},
+ {"Unshare", Func, 0},
+ {"UserInfo10", Type, 0},
+ {"UserInfo10.Comment", Field, 0},
+ {"UserInfo10.FullName", Field, 0},
+ {"UserInfo10.Name", Field, 0},
+ {"UserInfo10.UsrComment", Field, 0},
+ {"Ustat", Func, 0},
+ {"Ustat_t", Type, 0},
+ {"Ustat_t.Fname", Field, 0},
+ {"Ustat_t.Fpack", Field, 0},
+ {"Ustat_t.Pad_cgo_0", Field, 0},
+ {"Ustat_t.Pad_cgo_1", Field, 0},
+ {"Ustat_t.Tfree", Field, 0},
+ {"Ustat_t.Tinode", Field, 0},
+ {"Utimbuf", Type, 0},
+ {"Utimbuf.Actime", Field, 0},
+ {"Utimbuf.Modtime", Field, 0},
+ {"Utime", Func, 0},
+ {"Utimes", Func, 0},
+ {"UtimesNano", Func, 1},
+ {"Utsname", Type, 0},
+ {"Utsname.Domainname", Field, 0},
+ {"Utsname.Machine", Field, 0},
+ {"Utsname.Nodename", Field, 0},
+ {"Utsname.Release", Field, 0},
+ {"Utsname.Sysname", Field, 0},
+ {"Utsname.Version", Field, 0},
+ {"VDISCARD", Const, 0},
+ {"VDSUSP", Const, 1},
+ {"VEOF", Const, 0},
+ {"VEOL", Const, 0},
+ {"VEOL2", Const, 0},
+ {"VERASE", Const, 0},
+ {"VERASE2", Const, 1},
+ {"VINTR", Const, 0},
+ {"VKILL", Const, 0},
+ {"VLNEXT", Const, 0},
+ {"VMIN", Const, 0},
+ {"VQUIT", Const, 0},
+ {"VREPRINT", Const, 0},
+ {"VSTART", Const, 0},
+ {"VSTATUS", Const, 1},
+ {"VSTOP", Const, 0},
+ {"VSUSP", Const, 0},
+ {"VSWTC", Const, 0},
+ {"VT0", Const, 1},
+ {"VT1", Const, 1},
+ {"VTDLY", Const, 1},
+ {"VTIME", Const, 0},
+ {"VWERASE", Const, 0},
+ {"VirtualLock", Func, 0},
+ {"VirtualUnlock", Func, 0},
+ {"WAIT_ABANDONED", Const, 0},
+ {"WAIT_FAILED", Const, 0},
+ {"WAIT_OBJECT_0", Const, 0},
+ {"WAIT_TIMEOUT", Const, 0},
+ {"WALL", Const, 0},
+ {"WALLSIG", Const, 1},
+ {"WALTSIG", Const, 1},
+ {"WCLONE", Const, 0},
+ {"WCONTINUED", Const, 0},
+ {"WCOREFLAG", Const, 0},
+ {"WEXITED", Const, 0},
+ {"WLINUXCLONE", Const, 0},
+ {"WNOHANG", Const, 0},
+ {"WNOTHREAD", Const, 0},
+ {"WNOWAIT", Const, 0},
+ {"WNOZOMBIE", Const, 1},
+ {"WOPTSCHECKED", Const, 1},
+ {"WORDSIZE", Const, 0},
+ {"WSABuf", Type, 0},
+ {"WSABuf.Buf", Field, 0},
+ {"WSABuf.Len", Field, 0},
+ {"WSACleanup", Func, 0},
+ {"WSADESCRIPTION_LEN", Const, 0},
+ {"WSAData", Type, 0},
+ {"WSAData.Description", Field, 0},
+ {"WSAData.HighVersion", Field, 0},
+ {"WSAData.MaxSockets", Field, 0},
+ {"WSAData.MaxUdpDg", Field, 0},
+ {"WSAData.SystemStatus", Field, 0},
+ {"WSAData.VendorInfo", Field, 0},
+ {"WSAData.Version", Field, 0},
+ {"WSAEACCES", Const, 2},
+ {"WSAECONNABORTED", Const, 9},
+ {"WSAECONNRESET", Const, 3},
+ {"WSAENOPROTOOPT", Const, 23},
+ {"WSAEnumProtocols", Func, 2},
+ {"WSAID_CONNECTEX", Var, 1},
+ {"WSAIoctl", Func, 0},
+ {"WSAPROTOCOL_LEN", Const, 2},
+ {"WSAProtocolChain", Type, 2},
+ {"WSAProtocolChain.ChainEntries", Field, 2},
+ {"WSAProtocolChain.ChainLen", Field, 2},
+ {"WSAProtocolInfo", Type, 2},
+ {"WSAProtocolInfo.AddressFamily", Field, 2},
+ {"WSAProtocolInfo.CatalogEntryId", Field, 2},
+ {"WSAProtocolInfo.MaxSockAddr", Field, 2},
+ {"WSAProtocolInfo.MessageSize", Field, 2},
+ {"WSAProtocolInfo.MinSockAddr", Field, 2},
+ {"WSAProtocolInfo.NetworkByteOrder", Field, 2},
+ {"WSAProtocolInfo.Protocol", Field, 2},
+ {"WSAProtocolInfo.ProtocolChain", Field, 2},
+ {"WSAProtocolInfo.ProtocolMaxOffset", Field, 2},
+ {"WSAProtocolInfo.ProtocolName", Field, 2},
+ {"WSAProtocolInfo.ProviderFlags", Field, 2},
+ {"WSAProtocolInfo.ProviderId", Field, 2},
+ {"WSAProtocolInfo.ProviderReserved", Field, 2},
+ {"WSAProtocolInfo.SecurityScheme", Field, 2},
+ {"WSAProtocolInfo.ServiceFlags1", Field, 2},
+ {"WSAProtocolInfo.ServiceFlags2", Field, 2},
+ {"WSAProtocolInfo.ServiceFlags3", Field, 2},
+ {"WSAProtocolInfo.ServiceFlags4", Field, 2},
+ {"WSAProtocolInfo.SocketType", Field, 2},
+ {"WSAProtocolInfo.Version", Field, 2},
+ {"WSARecv", Func, 0},
+ {"WSARecvFrom", Func, 0},
+ {"WSASYS_STATUS_LEN", Const, 0},
+ {"WSASend", Func, 0},
+ {"WSASendTo", Func, 0},
+ {"WSASendto", Func, 0},
+ {"WSAStartup", Func, 0},
+ {"WSTOPPED", Const, 0},
+ {"WTRAPPED", Const, 1},
+ {"WUNTRACED", Const, 0},
+ {"Wait4", Func, 0},
+ {"WaitForSingleObject", Func, 0},
+ {"WaitStatus", Type, 0},
+ {"WaitStatus.ExitCode", Field, 0},
+ {"Win32FileAttributeData", Type, 0},
+ {"Win32FileAttributeData.CreationTime", Field, 0},
+ {"Win32FileAttributeData.FileAttributes", Field, 0},
+ {"Win32FileAttributeData.FileSizeHigh", Field, 0},
+ {"Win32FileAttributeData.FileSizeLow", Field, 0},
+ {"Win32FileAttributeData.LastAccessTime", Field, 0},
+ {"Win32FileAttributeData.LastWriteTime", Field, 0},
+ {"Win32finddata", Type, 0},
+ {"Win32finddata.AlternateFileName", Field, 0},
+ {"Win32finddata.CreationTime", Field, 0},
+ {"Win32finddata.FileAttributes", Field, 0},
+ {"Win32finddata.FileName", Field, 0},
+ {"Win32finddata.FileSizeHigh", Field, 0},
+ {"Win32finddata.FileSizeLow", Field, 0},
+ {"Win32finddata.LastAccessTime", Field, 0},
+ {"Win32finddata.LastWriteTime", Field, 0},
+ {"Win32finddata.Reserved0", Field, 0},
+ {"Win32finddata.Reserved1", Field, 0},
+ {"Write", Func, 0},
+ {"WriteConsole", Func, 1},
+ {"WriteFile", Func, 0},
+ {"X509_ASN_ENCODING", Const, 0},
+ {"XCASE", Const, 0},
+ {"XP1_CONNECTIONLESS", Const, 2},
+ {"XP1_CONNECT_DATA", Const, 2},
+ {"XP1_DISCONNECT_DATA", Const, 2},
+ {"XP1_EXPEDITED_DATA", Const, 2},
+ {"XP1_GRACEFUL_CLOSE", Const, 2},
+ {"XP1_GUARANTEED_DELIVERY", Const, 2},
+ {"XP1_GUARANTEED_ORDER", Const, 2},
+ {"XP1_IFS_HANDLES", Const, 2},
+ {"XP1_MESSAGE_ORIENTED", Const, 2},
+ {"XP1_MULTIPOINT_CONTROL_PLANE", Const, 2},
+ {"XP1_MULTIPOINT_DATA_PLANE", Const, 2},
+ {"XP1_PARTIAL_MESSAGE", Const, 2},
+ {"XP1_PSEUDO_STREAM", Const, 2},
+ {"XP1_QOS_SUPPORTED", Const, 2},
+ {"XP1_SAN_SUPPORT_SDP", Const, 2},
+ {"XP1_SUPPORT_BROADCAST", Const, 2},
+ {"XP1_SUPPORT_MULTIPOINT", Const, 2},
+ {"XP1_UNI_RECV", Const, 2},
+ {"XP1_UNI_SEND", Const, 2},
+ },
+ "syscall/js": {
+ {"CopyBytesToGo", Func, 0},
+ {"CopyBytesToJS", Func, 0},
+ {"Error", Type, 0},
+ {"Func", Type, 0},
+ {"FuncOf", Func, 0},
+ {"Global", Func, 0},
+ {"Null", Func, 0},
+ {"Type", Type, 0},
+ {"TypeBoolean", Const, 0},
+ {"TypeFunction", Const, 0},
+ {"TypeNull", Const, 0},
+ {"TypeNumber", Const, 0},
+ {"TypeObject", Const, 0},
+ {"TypeString", Const, 0},
+ {"TypeSymbol", Const, 0},
+ {"TypeUndefined", Const, 0},
+ {"Undefined", Func, 0},
+ {"Value", Type, 0},
+ {"ValueError", Type, 0},
+ {"ValueOf", Func, 0},
+ },
+ "testing": {
+ {"(*B).Cleanup", Method, 14},
+ {"(*B).Elapsed", Method, 20},
+ {"(*B).Error", Method, 0},
+ {"(*B).Errorf", Method, 0},
+ {"(*B).Fail", Method, 0},
+ {"(*B).FailNow", Method, 0},
+ {"(*B).Failed", Method, 0},
+ {"(*B).Fatal", Method, 0},
+ {"(*B).Fatalf", Method, 0},
+ {"(*B).Helper", Method, 9},
+ {"(*B).Log", Method, 0},
+ {"(*B).Logf", Method, 0},
+ {"(*B).Name", Method, 8},
+ {"(*B).ReportAllocs", Method, 1},
+ {"(*B).ReportMetric", Method, 13},
+ {"(*B).ResetTimer", Method, 0},
+ {"(*B).Run", Method, 7},
+ {"(*B).RunParallel", Method, 3},
+ {"(*B).SetBytes", Method, 0},
+ {"(*B).SetParallelism", Method, 3},
+ {"(*B).Setenv", Method, 17},
+ {"(*B).Skip", Method, 1},
+ {"(*B).SkipNow", Method, 1},
+ {"(*B).Skipf", Method, 1},
+ {"(*B).Skipped", Method, 1},
+ {"(*B).StartTimer", Method, 0},
+ {"(*B).StopTimer", Method, 0},
+ {"(*B).TempDir", Method, 15},
+ {"(*F).Add", Method, 18},
+ {"(*F).Cleanup", Method, 18},
+ {"(*F).Error", Method, 18},
+ {"(*F).Errorf", Method, 18},
+ {"(*F).Fail", Method, 18},
+ {"(*F).FailNow", Method, 18},
+ {"(*F).Failed", Method, 18},
+ {"(*F).Fatal", Method, 18},
+ {"(*F).Fatalf", Method, 18},
+ {"(*F).Fuzz", Method, 18},
+ {"(*F).Helper", Method, 18},
+ {"(*F).Log", Method, 18},
+ {"(*F).Logf", Method, 18},
+ {"(*F).Name", Method, 18},
+ {"(*F).Setenv", Method, 18},
+ {"(*F).Skip", Method, 18},
+ {"(*F).SkipNow", Method, 18},
+ {"(*F).Skipf", Method, 18},
+ {"(*F).Skipped", Method, 18},
+ {"(*F).TempDir", Method, 18},
+ {"(*M).Run", Method, 4},
+ {"(*PB).Next", Method, 3},
+ {"(*T).Cleanup", Method, 14},
+ {"(*T).Deadline", Method, 15},
+ {"(*T).Error", Method, 0},
+ {"(*T).Errorf", Method, 0},
+ {"(*T).Fail", Method, 0},
+ {"(*T).FailNow", Method, 0},
+ {"(*T).Failed", Method, 0},
+ {"(*T).Fatal", Method, 0},
+ {"(*T).Fatalf", Method, 0},
+ {"(*T).Helper", Method, 9},
+ {"(*T).Log", Method, 0},
+ {"(*T).Logf", Method, 0},
+ {"(*T).Name", Method, 8},
+ {"(*T).Parallel", Method, 0},
+ {"(*T).Run", Method, 7},
+ {"(*T).Setenv", Method, 17},
+ {"(*T).Skip", Method, 1},
+ {"(*T).SkipNow", Method, 1},
+ {"(*T).Skipf", Method, 1},
+ {"(*T).Skipped", Method, 1},
+ {"(*T).TempDir", Method, 15},
+ {"(BenchmarkResult).AllocedBytesPerOp", Method, 1},
+ {"(BenchmarkResult).AllocsPerOp", Method, 1},
+ {"(BenchmarkResult).MemString", Method, 1},
+ {"(BenchmarkResult).NsPerOp", Method, 0},
+ {"(BenchmarkResult).String", Method, 0},
+ {"AllocsPerRun", Func, 1},
+ {"B", Type, 0},
+ {"B.N", Field, 0},
+ {"Benchmark", Func, 0},
+ {"BenchmarkResult", Type, 0},
+ {"BenchmarkResult.Bytes", Field, 0},
+ {"BenchmarkResult.Extra", Field, 13},
+ {"BenchmarkResult.MemAllocs", Field, 1},
+ {"BenchmarkResult.MemBytes", Field, 1},
+ {"BenchmarkResult.N", Field, 0},
+ {"BenchmarkResult.T", Field, 0},
+ {"Cover", Type, 2},
+ {"Cover.Blocks", Field, 2},
+ {"Cover.Counters", Field, 2},
+ {"Cover.CoveredPackages", Field, 2},
+ {"Cover.Mode", Field, 2},
+ {"CoverBlock", Type, 2},
+ {"CoverBlock.Col0", Field, 2},
+ {"CoverBlock.Col1", Field, 2},
+ {"CoverBlock.Line0", Field, 2},
+ {"CoverBlock.Line1", Field, 2},
+ {"CoverBlock.Stmts", Field, 2},
+ {"CoverMode", Func, 8},
+ {"Coverage", Func, 4},
+ {"F", Type, 18},
+ {"Init", Func, 13},
+ {"InternalBenchmark", Type, 0},
+ {"InternalBenchmark.F", Field, 0},
+ {"InternalBenchmark.Name", Field, 0},
+ {"InternalExample", Type, 0},
+ {"InternalExample.F", Field, 0},
+ {"InternalExample.Name", Field, 0},
+ {"InternalExample.Output", Field, 0},
+ {"InternalExample.Unordered", Field, 7},
+ {"InternalFuzzTarget", Type, 18},
+ {"InternalFuzzTarget.Fn", Field, 18},
+ {"InternalFuzzTarget.Name", Field, 18},
+ {"InternalTest", Type, 0},
+ {"InternalTest.F", Field, 0},
+ {"InternalTest.Name", Field, 0},
+ {"M", Type, 4},
+ {"Main", Func, 0},
+ {"MainStart", Func, 4},
+ {"PB", Type, 3},
+ {"RegisterCover", Func, 2},
+ {"RunBenchmarks", Func, 0},
+ {"RunExamples", Func, 0},
+ {"RunTests", Func, 0},
+ {"Short", Func, 0},
+ {"T", Type, 0},
+ {"TB", Type, 2},
+ {"Testing", Func, 21},
+ {"Verbose", Func, 1},
+ },
+ "testing/fstest": {
+ {"(MapFS).Glob", Method, 16},
+ {"(MapFS).Open", Method, 16},
+ {"(MapFS).ReadDir", Method, 16},
+ {"(MapFS).ReadFile", Method, 16},
+ {"(MapFS).Stat", Method, 16},
+ {"(MapFS).Sub", Method, 16},
+ {"MapFS", Type, 16},
+ {"MapFile", Type, 16},
+ {"MapFile.Data", Field, 16},
+ {"MapFile.ModTime", Field, 16},
+ {"MapFile.Mode", Field, 16},
+ {"MapFile.Sys", Field, 16},
+ {"TestFS", Func, 16},
+ },
+ "testing/iotest": {
+ {"DataErrReader", Func, 0},
+ {"ErrReader", Func, 16},
+ {"ErrTimeout", Var, 0},
+ {"HalfReader", Func, 0},
+ {"NewReadLogger", Func, 0},
+ {"NewWriteLogger", Func, 0},
+ {"OneByteReader", Func, 0},
+ {"TestReader", Func, 16},
+ {"TimeoutReader", Func, 0},
+ {"TruncateWriter", Func, 0},
+ },
+ "testing/quick": {
+ {"(*CheckEqualError).Error", Method, 0},
+ {"(*CheckError).Error", Method, 0},
+ {"(SetupError).Error", Method, 0},
+ {"Check", Func, 0},
+ {"CheckEqual", Func, 0},
+ {"CheckEqualError", Type, 0},
+ {"CheckEqualError.CheckError", Field, 0},
+ {"CheckEqualError.Out1", Field, 0},
+ {"CheckEqualError.Out2", Field, 0},
+ {"CheckError", Type, 0},
+ {"CheckError.Count", Field, 0},
+ {"CheckError.In", Field, 0},
+ {"Config", Type, 0},
+ {"Config.MaxCount", Field, 0},
+ {"Config.MaxCountScale", Field, 0},
+ {"Config.Rand", Field, 0},
+ {"Config.Values", Field, 0},
+ {"Generator", Type, 0},
+ {"SetupError", Type, 0},
+ {"Value", Func, 0},
+ },
+ "testing/slogtest": {
+ {"Run", Func, 22},
+ {"TestHandler", Func, 21},
+ },
+ "text/scanner": {
+ {"(*Position).IsValid", Method, 0},
+ {"(*Scanner).Init", Method, 0},
+ {"(*Scanner).IsValid", Method, 0},
+ {"(*Scanner).Next", Method, 0},
+ {"(*Scanner).Peek", Method, 0},
+ {"(*Scanner).Pos", Method, 0},
+ {"(*Scanner).Scan", Method, 0},
+ {"(*Scanner).TokenText", Method, 0},
+ {"(Position).String", Method, 0},
+ {"(Scanner).String", Method, 0},
+ {"Char", Const, 0},
+ {"Comment", Const, 0},
+ {"EOF", Const, 0},
+ {"Float", Const, 0},
+ {"GoTokens", Const, 0},
+ {"GoWhitespace", Const, 0},
+ {"Ident", Const, 0},
+ {"Int", Const, 0},
+ {"Position", Type, 0},
+ {"Position.Column", Field, 0},
+ {"Position.Filename", Field, 0},
+ {"Position.Line", Field, 0},
+ {"Position.Offset", Field, 0},
+ {"RawString", Const, 0},
+ {"ScanChars", Const, 0},
+ {"ScanComments", Const, 0},
+ {"ScanFloats", Const, 0},
+ {"ScanIdents", Const, 0},
+ {"ScanInts", Const, 0},
+ {"ScanRawStrings", Const, 0},
+ {"ScanStrings", Const, 0},
+ {"Scanner", Type, 0},
+ {"Scanner.Error", Field, 0},
+ {"Scanner.ErrorCount", Field, 0},
+ {"Scanner.IsIdentRune", Field, 4},
+ {"Scanner.Mode", Field, 0},
+ {"Scanner.Position", Field, 0},
+ {"Scanner.Whitespace", Field, 0},
+ {"SkipComments", Const, 0},
+ {"String", Const, 0},
+ {"TokenString", Func, 0},
+ },
+ "text/tabwriter": {
+ {"(*Writer).Flush", Method, 0},
+ {"(*Writer).Init", Method, 0},
+ {"(*Writer).Write", Method, 0},
+ {"AlignRight", Const, 0},
+ {"Debug", Const, 0},
+ {"DiscardEmptyColumns", Const, 0},
+ {"Escape", Const, 0},
+ {"FilterHTML", Const, 0},
+ {"NewWriter", Func, 0},
+ {"StripEscape", Const, 0},
+ {"TabIndent", Const, 0},
+ {"Writer", Type, 0},
+ },
+ "text/template": {
+ {"(*Template).AddParseTree", Method, 0},
+ {"(*Template).Clone", Method, 0},
+ {"(*Template).DefinedTemplates", Method, 5},
+ {"(*Template).Delims", Method, 0},
+ {"(*Template).Execute", Method, 0},
+ {"(*Template).ExecuteTemplate", Method, 0},
+ {"(*Template).Funcs", Method, 0},
+ {"(*Template).Lookup", Method, 0},
+ {"(*Template).Name", Method, 0},
+ {"(*Template).New", Method, 0},
+ {"(*Template).Option", Method, 5},
+ {"(*Template).Parse", Method, 0},
+ {"(*Template).ParseFS", Method, 16},
+ {"(*Template).ParseFiles", Method, 0},
+ {"(*Template).ParseGlob", Method, 0},
+ {"(*Template).Templates", Method, 0},
+ {"(ExecError).Error", Method, 6},
+ {"(ExecError).Unwrap", Method, 13},
+ {"(Template).Copy", Method, 2},
+ {"(Template).ErrorContext", Method, 1},
+ {"ExecError", Type, 6},
+ {"ExecError.Err", Field, 6},
+ {"ExecError.Name", Field, 6},
+ {"FuncMap", Type, 0},
+ {"HTMLEscape", Func, 0},
+ {"HTMLEscapeString", Func, 0},
+ {"HTMLEscaper", Func, 0},
+ {"IsTrue", Func, 6},
+ {"JSEscape", Func, 0},
+ {"JSEscapeString", Func, 0},
+ {"JSEscaper", Func, 0},
+ {"Must", Func, 0},
+ {"New", Func, 0},
+ {"ParseFS", Func, 16},
+ {"ParseFiles", Func, 0},
+ {"ParseGlob", Func, 0},
+ {"Template", Type, 0},
+ {"Template.Tree", Field, 0},
+ {"URLQueryEscaper", Func, 0},
+ },
+ "text/template/parse": {
+ {"(*ActionNode).Copy", Method, 0},
+ {"(*ActionNode).String", Method, 0},
+ {"(*BoolNode).Copy", Method, 0},
+ {"(*BoolNode).String", Method, 0},
+ {"(*BranchNode).Copy", Method, 4},
+ {"(*BranchNode).String", Method, 0},
+ {"(*BreakNode).Copy", Method, 18},
+ {"(*BreakNode).String", Method, 18},
+ {"(*ChainNode).Add", Method, 1},
+ {"(*ChainNode).Copy", Method, 1},
+ {"(*ChainNode).String", Method, 1},
+ {"(*CommandNode).Copy", Method, 0},
+ {"(*CommandNode).String", Method, 0},
+ {"(*CommentNode).Copy", Method, 16},
+ {"(*CommentNode).String", Method, 16},
+ {"(*ContinueNode).Copy", Method, 18},
+ {"(*ContinueNode).String", Method, 18},
+ {"(*DotNode).Copy", Method, 0},
+ {"(*DotNode).String", Method, 0},
+ {"(*DotNode).Type", Method, 0},
+ {"(*FieldNode).Copy", Method, 0},
+ {"(*FieldNode).String", Method, 0},
+ {"(*IdentifierNode).Copy", Method, 0},
+ {"(*IdentifierNode).SetPos", Method, 1},
+ {"(*IdentifierNode).SetTree", Method, 4},
+ {"(*IdentifierNode).String", Method, 0},
+ {"(*IfNode).Copy", Method, 0},
+ {"(*IfNode).String", Method, 0},
+ {"(*ListNode).Copy", Method, 0},
+ {"(*ListNode).CopyList", Method, 0},
+ {"(*ListNode).String", Method, 0},
+ {"(*NilNode).Copy", Method, 1},
+ {"(*NilNode).String", Method, 1},
+ {"(*NilNode).Type", Method, 1},
+ {"(*NumberNode).Copy", Method, 0},
+ {"(*NumberNode).String", Method, 0},
+ {"(*PipeNode).Copy", Method, 0},
+ {"(*PipeNode).CopyPipe", Method, 0},
+ {"(*PipeNode).String", Method, 0},
+ {"(*RangeNode).Copy", Method, 0},
+ {"(*RangeNode).String", Method, 0},
+ {"(*StringNode).Copy", Method, 0},
+ {"(*StringNode).String", Method, 0},
+ {"(*TemplateNode).Copy", Method, 0},
+ {"(*TemplateNode).String", Method, 0},
+ {"(*TextNode).Copy", Method, 0},
+ {"(*TextNode).String", Method, 0},
+ {"(*Tree).Copy", Method, 2},
+ {"(*Tree).ErrorContext", Method, 1},
+ {"(*Tree).Parse", Method, 0},
+ {"(*VariableNode).Copy", Method, 0},
+ {"(*VariableNode).String", Method, 0},
+ {"(*WithNode).Copy", Method, 0},
+ {"(*WithNode).String", Method, 0},
+ {"(ActionNode).Position", Method, 1},
+ {"(ActionNode).Type", Method, 0},
+ {"(BoolNode).Position", Method, 1},
+ {"(BoolNode).Type", Method, 0},
+ {"(BranchNode).Position", Method, 1},
+ {"(BranchNode).Type", Method, 0},
+ {"(BreakNode).Position", Method, 18},
+ {"(BreakNode).Type", Method, 18},
+ {"(ChainNode).Position", Method, 1},
+ {"(ChainNode).Type", Method, 1},
+ {"(CommandNode).Position", Method, 1},
+ {"(CommandNode).Type", Method, 0},
+ {"(CommentNode).Position", Method, 16},
+ {"(CommentNode).Type", Method, 16},
+ {"(ContinueNode).Position", Method, 18},
+ {"(ContinueNode).Type", Method, 18},
+ {"(DotNode).Position", Method, 1},
+ {"(FieldNode).Position", Method, 1},
+ {"(FieldNode).Type", Method, 0},
+ {"(IdentifierNode).Position", Method, 1},
+ {"(IdentifierNode).Type", Method, 0},
+ {"(IfNode).Position", Method, 1},
+ {"(IfNode).Type", Method, 0},
+ {"(ListNode).Position", Method, 1},
+ {"(ListNode).Type", Method, 0},
+ {"(NilNode).Position", Method, 1},
+ {"(NodeType).Type", Method, 0},
+ {"(NumberNode).Position", Method, 1},
+ {"(NumberNode).Type", Method, 0},
+ {"(PipeNode).Position", Method, 1},
+ {"(PipeNode).Type", Method, 0},
+ {"(Pos).Position", Method, 1},
+ {"(RangeNode).Position", Method, 1},
+ {"(RangeNode).Type", Method, 0},
+ {"(StringNode).Position", Method, 1},
+ {"(StringNode).Type", Method, 0},
+ {"(TemplateNode).Position", Method, 1},
+ {"(TemplateNode).Type", Method, 0},
+ {"(TextNode).Position", Method, 1},
+ {"(TextNode).Type", Method, 0},
+ {"(VariableNode).Position", Method, 1},
+ {"(VariableNode).Type", Method, 0},
+ {"(WithNode).Position", Method, 1},
+ {"(WithNode).Type", Method, 0},
+ {"ActionNode", Type, 0},
+ {"ActionNode.Line", Field, 0},
+ {"ActionNode.NodeType", Field, 0},
+ {"ActionNode.Pipe", Field, 0},
+ {"ActionNode.Pos", Field, 1},
+ {"BoolNode", Type, 0},
+ {"BoolNode.NodeType", Field, 0},
+ {"BoolNode.Pos", Field, 1},
+ {"BoolNode.True", Field, 0},
+ {"BranchNode", Type, 0},
+ {"BranchNode.ElseList", Field, 0},
+ {"BranchNode.Line", Field, 0},
+ {"BranchNode.List", Field, 0},
+ {"BranchNode.NodeType", Field, 0},
+ {"BranchNode.Pipe", Field, 0},
+ {"BranchNode.Pos", Field, 1},
+ {"BreakNode", Type, 18},
+ {"BreakNode.Line", Field, 18},
+ {"BreakNode.NodeType", Field, 18},
+ {"BreakNode.Pos", Field, 18},
+ {"ChainNode", Type, 1},
+ {"ChainNode.Field", Field, 1},
+ {"ChainNode.Node", Field, 1},
+ {"ChainNode.NodeType", Field, 1},
+ {"ChainNode.Pos", Field, 1},
+ {"CommandNode", Type, 0},
+ {"CommandNode.Args", Field, 0},
+ {"CommandNode.NodeType", Field, 0},
+ {"CommandNode.Pos", Field, 1},
+ {"CommentNode", Type, 16},
+ {"CommentNode.NodeType", Field, 16},
+ {"CommentNode.Pos", Field, 16},
+ {"CommentNode.Text", Field, 16},
+ {"ContinueNode", Type, 18},
+ {"ContinueNode.Line", Field, 18},
+ {"ContinueNode.NodeType", Field, 18},
+ {"ContinueNode.Pos", Field, 18},
+ {"DotNode", Type, 0},
+ {"DotNode.NodeType", Field, 4},
+ {"DotNode.Pos", Field, 1},
+ {"FieldNode", Type, 0},
+ {"FieldNode.Ident", Field, 0},
+ {"FieldNode.NodeType", Field, 0},
+ {"FieldNode.Pos", Field, 1},
+ {"IdentifierNode", Type, 0},
+ {"IdentifierNode.Ident", Field, 0},
+ {"IdentifierNode.NodeType", Field, 0},
+ {"IdentifierNode.Pos", Field, 1},
+ {"IfNode", Type, 0},
+ {"IfNode.BranchNode", Field, 0},
+ {"IsEmptyTree", Func, 0},
+ {"ListNode", Type, 0},
+ {"ListNode.NodeType", Field, 0},
+ {"ListNode.Nodes", Field, 0},
+ {"ListNode.Pos", Field, 1},
+ {"Mode", Type, 16},
+ {"New", Func, 0},
+ {"NewIdentifier", Func, 0},
+ {"NilNode", Type, 1},
+ {"NilNode.NodeType", Field, 4},
+ {"NilNode.Pos", Field, 1},
+ {"Node", Type, 0},
+ {"NodeAction", Const, 0},
+ {"NodeBool", Const, 0},
+ {"NodeBreak", Const, 18},
+ {"NodeChain", Const, 1},
+ {"NodeCommand", Const, 0},
+ {"NodeComment", Const, 16},
+ {"NodeContinue", Const, 18},
+ {"NodeDot", Const, 0},
+ {"NodeField", Const, 0},
+ {"NodeIdentifier", Const, 0},
+ {"NodeIf", Const, 0},
+ {"NodeList", Const, 0},
+ {"NodeNil", Const, 1},
+ {"NodeNumber", Const, 0},
+ {"NodePipe", Const, 0},
+ {"NodeRange", Const, 0},
+ {"NodeString", Const, 0},
+ {"NodeTemplate", Const, 0},
+ {"NodeText", Const, 0},
+ {"NodeType", Type, 0},
+ {"NodeVariable", Const, 0},
+ {"NodeWith", Const, 0},
+ {"NumberNode", Type, 0},
+ {"NumberNode.Complex128", Field, 0},
+ {"NumberNode.Float64", Field, 0},
+ {"NumberNode.Int64", Field, 0},
+ {"NumberNode.IsComplex", Field, 0},
+ {"NumberNode.IsFloat", Field, 0},
+ {"NumberNode.IsInt", Field, 0},
+ {"NumberNode.IsUint", Field, 0},
+ {"NumberNode.NodeType", Field, 0},
+ {"NumberNode.Pos", Field, 1},
+ {"NumberNode.Text", Field, 0},
+ {"NumberNode.Uint64", Field, 0},
+ {"Parse", Func, 0},
+ {"ParseComments", Const, 16},
+ {"PipeNode", Type, 0},
+ {"PipeNode.Cmds", Field, 0},
+ {"PipeNode.Decl", Field, 0},
+ {"PipeNode.IsAssign", Field, 11},
+ {"PipeNode.Line", Field, 0},
+ {"PipeNode.NodeType", Field, 0},
+ {"PipeNode.Pos", Field, 1},
+ {"Pos", Type, 1},
+ {"RangeNode", Type, 0},
+ {"RangeNode.BranchNode", Field, 0},
+ {"SkipFuncCheck", Const, 17},
+ {"StringNode", Type, 0},
+ {"StringNode.NodeType", Field, 0},
+ {"StringNode.Pos", Field, 1},
+ {"StringNode.Quoted", Field, 0},
+ {"StringNode.Text", Field, 0},
+ {"TemplateNode", Type, 0},
+ {"TemplateNode.Line", Field, 0},
+ {"TemplateNode.Name", Field, 0},
+ {"TemplateNode.NodeType", Field, 0},
+ {"TemplateNode.Pipe", Field, 0},
+ {"TemplateNode.Pos", Field, 1},
+ {"TextNode", Type, 0},
+ {"TextNode.NodeType", Field, 0},
+ {"TextNode.Pos", Field, 1},
+ {"TextNode.Text", Field, 0},
+ {"Tree", Type, 0},
+ {"Tree.Mode", Field, 16},
+ {"Tree.Name", Field, 0},
+ {"Tree.ParseName", Field, 1},
+ {"Tree.Root", Field, 0},
+ {"VariableNode", Type, 0},
+ {"VariableNode.Ident", Field, 0},
+ {"VariableNode.NodeType", Field, 0},
+ {"VariableNode.Pos", Field, 1},
+ {"WithNode", Type, 0},
+ {"WithNode.BranchNode", Field, 0},
+ },
+ "time": {
+ {"(*Location).String", Method, 0},
+ {"(*ParseError).Error", Method, 0},
+ {"(*Ticker).Reset", Method, 15},
+ {"(*Ticker).Stop", Method, 0},
+ {"(*Time).GobDecode", Method, 0},
+ {"(*Time).UnmarshalBinary", Method, 2},
+ {"(*Time).UnmarshalJSON", Method, 0},
+ {"(*Time).UnmarshalText", Method, 2},
+ {"(*Timer).Reset", Method, 1},
+ {"(*Timer).Stop", Method, 0},
+ {"(Duration).Abs", Method, 19},
+ {"(Duration).Hours", Method, 0},
+ {"(Duration).Microseconds", Method, 13},
+ {"(Duration).Milliseconds", Method, 13},
+ {"(Duration).Minutes", Method, 0},
+ {"(Duration).Nanoseconds", Method, 0},
+ {"(Duration).Round", Method, 9},
+ {"(Duration).Seconds", Method, 0},
+ {"(Duration).String", Method, 0},
+ {"(Duration).Truncate", Method, 9},
+ {"(Month).String", Method, 0},
+ {"(Time).Add", Method, 0},
+ {"(Time).AddDate", Method, 0},
+ {"(Time).After", Method, 0},
+ {"(Time).AppendFormat", Method, 5},
+ {"(Time).Before", Method, 0},
+ {"(Time).Clock", Method, 0},
+ {"(Time).Compare", Method, 20},
+ {"(Time).Date", Method, 0},
+ {"(Time).Day", Method, 0},
+ {"(Time).Equal", Method, 0},
+ {"(Time).Format", Method, 0},
+ {"(Time).GoString", Method, 17},
+ {"(Time).GobEncode", Method, 0},
+ {"(Time).Hour", Method, 0},
+ {"(Time).ISOWeek", Method, 0},
+ {"(Time).In", Method, 0},
+ {"(Time).IsDST", Method, 17},
+ {"(Time).IsZero", Method, 0},
+ {"(Time).Local", Method, 0},
+ {"(Time).Location", Method, 0},
+ {"(Time).MarshalBinary", Method, 2},
+ {"(Time).MarshalJSON", Method, 0},
+ {"(Time).MarshalText", Method, 2},
+ {"(Time).Minute", Method, 0},
+ {"(Time).Month", Method, 0},
+ {"(Time).Nanosecond", Method, 0},
+ {"(Time).Round", Method, 1},
+ {"(Time).Second", Method, 0},
+ {"(Time).String", Method, 0},
+ {"(Time).Sub", Method, 0},
+ {"(Time).Truncate", Method, 1},
+ {"(Time).UTC", Method, 0},
+ {"(Time).Unix", Method, 0},
+ {"(Time).UnixMicro", Method, 17},
+ {"(Time).UnixMilli", Method, 17},
+ {"(Time).UnixNano", Method, 0},
+ {"(Time).Weekday", Method, 0},
+ {"(Time).Year", Method, 0},
+ {"(Time).YearDay", Method, 1},
+ {"(Time).Zone", Method, 0},
+ {"(Time).ZoneBounds", Method, 19},
+ {"(Weekday).String", Method, 0},
+ {"ANSIC", Const, 0},
+ {"After", Func, 0},
+ {"AfterFunc", Func, 0},
+ {"April", Const, 0},
+ {"August", Const, 0},
+ {"Date", Func, 0},
+ {"DateOnly", Const, 20},
+ {"DateTime", Const, 20},
+ {"December", Const, 0},
+ {"Duration", Type, 0},
+ {"February", Const, 0},
+ {"FixedZone", Func, 0},
+ {"Friday", Const, 0},
+ {"Hour", Const, 0},
+ {"January", Const, 0},
+ {"July", Const, 0},
+ {"June", Const, 0},
+ {"Kitchen", Const, 0},
+ {"Layout", Const, 17},
+ {"LoadLocation", Func, 0},
+ {"LoadLocationFromTZData", Func, 10},
+ {"Local", Var, 0},
+ {"Location", Type, 0},
+ {"March", Const, 0},
+ {"May", Const, 0},
+ {"Microsecond", Const, 0},
+ {"Millisecond", Const, 0},
+ {"Minute", Const, 0},
+ {"Monday", Const, 0},
+ {"Month", Type, 0},
+ {"Nanosecond", Const, 0},
+ {"NewTicker", Func, 0},
+ {"NewTimer", Func, 0},
+ {"November", Const, 0},
+ {"Now", Func, 0},
+ {"October", Const, 0},
+ {"Parse", Func, 0},
+ {"ParseDuration", Func, 0},
+ {"ParseError", Type, 0},
+ {"ParseError.Layout", Field, 0},
+ {"ParseError.LayoutElem", Field, 0},
+ {"ParseError.Message", Field, 0},
+ {"ParseError.Value", Field, 0},
+ {"ParseError.ValueElem", Field, 0},
+ {"ParseInLocation", Func, 1},
+ {"RFC1123", Const, 0},
+ {"RFC1123Z", Const, 0},
+ {"RFC3339", Const, 0},
+ {"RFC3339Nano", Const, 0},
+ {"RFC822", Const, 0},
+ {"RFC822Z", Const, 0},
+ {"RFC850", Const, 0},
+ {"RubyDate", Const, 0},
+ {"Saturday", Const, 0},
+ {"Second", Const, 0},
+ {"September", Const, 0},
+ {"Since", Func, 0},
+ {"Sleep", Func, 0},
+ {"Stamp", Const, 0},
+ {"StampMicro", Const, 0},
+ {"StampMilli", Const, 0},
+ {"StampNano", Const, 0},
+ {"Sunday", Const, 0},
+ {"Thursday", Const, 0},
+ {"Tick", Func, 0},
+ {"Ticker", Type, 0},
+ {"Ticker.C", Field, 0},
+ {"Time", Type, 0},
+ {"TimeOnly", Const, 20},
+ {"Timer", Type, 0},
+ {"Timer.C", Field, 0},
+ {"Tuesday", Const, 0},
+ {"UTC", Var, 0},
+ {"Unix", Func, 0},
+ {"UnixDate", Const, 0},
+ {"UnixMicro", Func, 17},
+ {"UnixMilli", Func, 17},
+ {"Until", Func, 8},
+ {"Wednesday", Const, 0},
+ {"Weekday", Type, 0},
+ },
+ "unicode": {
+ {"(SpecialCase).ToLower", Method, 0},
+ {"(SpecialCase).ToTitle", Method, 0},
+ {"(SpecialCase).ToUpper", Method, 0},
+ {"ASCII_Hex_Digit", Var, 0},
+ {"Adlam", Var, 7},
+ {"Ahom", Var, 5},
+ {"Anatolian_Hieroglyphs", Var, 5},
+ {"Arabic", Var, 0},
+ {"Armenian", Var, 0},
+ {"Avestan", Var, 0},
+ {"AzeriCase", Var, 0},
+ {"Balinese", Var, 0},
+ {"Bamum", Var, 0},
+ {"Bassa_Vah", Var, 4},
+ {"Batak", Var, 0},
+ {"Bengali", Var, 0},
+ {"Bhaiksuki", Var, 7},
+ {"Bidi_Control", Var, 0},
+ {"Bopomofo", Var, 0},
+ {"Brahmi", Var, 0},
+ {"Braille", Var, 0},
+ {"Buginese", Var, 0},
+ {"Buhid", Var, 0},
+ {"C", Var, 0},
+ {"Canadian_Aboriginal", Var, 0},
+ {"Carian", Var, 0},
+ {"CaseRange", Type, 0},
+ {"CaseRange.Delta", Field, 0},
+ {"CaseRange.Hi", Field, 0},
+ {"CaseRange.Lo", Field, 0},
+ {"CaseRanges", Var, 0},
+ {"Categories", Var, 0},
+ {"Caucasian_Albanian", Var, 4},
+ {"Cc", Var, 0},
+ {"Cf", Var, 0},
+ {"Chakma", Var, 1},
+ {"Cham", Var, 0},
+ {"Cherokee", Var, 0},
+ {"Chorasmian", Var, 16},
+ {"Co", Var, 0},
+ {"Common", Var, 0},
+ {"Coptic", Var, 0},
+ {"Cs", Var, 0},
+ {"Cuneiform", Var, 0},
+ {"Cypriot", Var, 0},
+ {"Cypro_Minoan", Var, 21},
+ {"Cyrillic", Var, 0},
+ {"Dash", Var, 0},
+ {"Deprecated", Var, 0},
+ {"Deseret", Var, 0},
+ {"Devanagari", Var, 0},
+ {"Diacritic", Var, 0},
+ {"Digit", Var, 0},
+ {"Dives_Akuru", Var, 16},
+ {"Dogra", Var, 13},
+ {"Duployan", Var, 4},
+ {"Egyptian_Hieroglyphs", Var, 0},
+ {"Elbasan", Var, 4},
+ {"Elymaic", Var, 14},
+ {"Ethiopic", Var, 0},
+ {"Extender", Var, 0},
+ {"FoldCategory", Var, 0},
+ {"FoldScript", Var, 0},
+ {"Georgian", Var, 0},
+ {"Glagolitic", Var, 0},
+ {"Gothic", Var, 0},
+ {"Grantha", Var, 4},
+ {"GraphicRanges", Var, 0},
+ {"Greek", Var, 0},
+ {"Gujarati", Var, 0},
+ {"Gunjala_Gondi", Var, 13},
+ {"Gurmukhi", Var, 0},
+ {"Han", Var, 0},
+ {"Hangul", Var, 0},
+ {"Hanifi_Rohingya", Var, 13},
+ {"Hanunoo", Var, 0},
+ {"Hatran", Var, 5},
+ {"Hebrew", Var, 0},
+ {"Hex_Digit", Var, 0},
+ {"Hiragana", Var, 0},
+ {"Hyphen", Var, 0},
+ {"IDS_Binary_Operator", Var, 0},
+ {"IDS_Trinary_Operator", Var, 0},
+ {"Ideographic", Var, 0},
+ {"Imperial_Aramaic", Var, 0},
+ {"In", Func, 2},
+ {"Inherited", Var, 0},
+ {"Inscriptional_Pahlavi", Var, 0},
+ {"Inscriptional_Parthian", Var, 0},
+ {"Is", Func, 0},
+ {"IsControl", Func, 0},
+ {"IsDigit", Func, 0},
+ {"IsGraphic", Func, 0},
+ {"IsLetter", Func, 0},
+ {"IsLower", Func, 0},
+ {"IsMark", Func, 0},
+ {"IsNumber", Func, 0},
+ {"IsOneOf", Func, 0},
+ {"IsPrint", Func, 0},
+ {"IsPunct", Func, 0},
+ {"IsSpace", Func, 0},
+ {"IsSymbol", Func, 0},
+ {"IsTitle", Func, 0},
+ {"IsUpper", Func, 0},
+ {"Javanese", Var, 0},
+ {"Join_Control", Var, 0},
+ {"Kaithi", Var, 0},
+ {"Kannada", Var, 0},
+ {"Katakana", Var, 0},
+ {"Kawi", Var, 21},
+ {"Kayah_Li", Var, 0},
+ {"Kharoshthi", Var, 0},
+ {"Khitan_Small_Script", Var, 16},
+ {"Khmer", Var, 0},
+ {"Khojki", Var, 4},
+ {"Khudawadi", Var, 4},
+ {"L", Var, 0},
+ {"Lao", Var, 0},
+ {"Latin", Var, 0},
+ {"Lepcha", Var, 0},
+ {"Letter", Var, 0},
+ {"Limbu", Var, 0},
+ {"Linear_A", Var, 4},
+ {"Linear_B", Var, 0},
+ {"Lisu", Var, 0},
+ {"Ll", Var, 0},
+ {"Lm", Var, 0},
+ {"Lo", Var, 0},
+ {"Logical_Order_Exception", Var, 0},
+ {"Lower", Var, 0},
+ {"LowerCase", Const, 0},
+ {"Lt", Var, 0},
+ {"Lu", Var, 0},
+ {"Lycian", Var, 0},
+ {"Lydian", Var, 0},
+ {"M", Var, 0},
+ {"Mahajani", Var, 4},
+ {"Makasar", Var, 13},
+ {"Malayalam", Var, 0},
+ {"Mandaic", Var, 0},
+ {"Manichaean", Var, 4},
+ {"Marchen", Var, 7},
+ {"Mark", Var, 0},
+ {"Masaram_Gondi", Var, 10},
+ {"MaxASCII", Const, 0},
+ {"MaxCase", Const, 0},
+ {"MaxLatin1", Const, 0},
+ {"MaxRune", Const, 0},
+ {"Mc", Var, 0},
+ {"Me", Var, 0},
+ {"Medefaidrin", Var, 13},
+ {"Meetei_Mayek", Var, 0},
+ {"Mende_Kikakui", Var, 4},
+ {"Meroitic_Cursive", Var, 1},
+ {"Meroitic_Hieroglyphs", Var, 1},
+ {"Miao", Var, 1},
+ {"Mn", Var, 0},
+ {"Modi", Var, 4},
+ {"Mongolian", Var, 0},
+ {"Mro", Var, 4},
+ {"Multani", Var, 5},
+ {"Myanmar", Var, 0},
+ {"N", Var, 0},
+ {"Nabataean", Var, 4},
+ {"Nag_Mundari", Var, 21},
+ {"Nandinagari", Var, 14},
+ {"Nd", Var, 0},
+ {"New_Tai_Lue", Var, 0},
+ {"Newa", Var, 7},
+ {"Nko", Var, 0},
+ {"Nl", Var, 0},
+ {"No", Var, 0},
+ {"Noncharacter_Code_Point", Var, 0},
+ {"Number", Var, 0},
+ {"Nushu", Var, 10},
+ {"Nyiakeng_Puachue_Hmong", Var, 14},
+ {"Ogham", Var, 0},
+ {"Ol_Chiki", Var, 0},
+ {"Old_Hungarian", Var, 5},
+ {"Old_Italic", Var, 0},
+ {"Old_North_Arabian", Var, 4},
+ {"Old_Permic", Var, 4},
+ {"Old_Persian", Var, 0},
+ {"Old_Sogdian", Var, 13},
+ {"Old_South_Arabian", Var, 0},
+ {"Old_Turkic", Var, 0},
+ {"Old_Uyghur", Var, 21},
+ {"Oriya", Var, 0},
+ {"Osage", Var, 7},
+ {"Osmanya", Var, 0},
+ {"Other", Var, 0},
+ {"Other_Alphabetic", Var, 0},
+ {"Other_Default_Ignorable_Code_Point", Var, 0},
+ {"Other_Grapheme_Extend", Var, 0},
+ {"Other_ID_Continue", Var, 0},
+ {"Other_ID_Start", Var, 0},
+ {"Other_Lowercase", Var, 0},
+ {"Other_Math", Var, 0},
+ {"Other_Uppercase", Var, 0},
+ {"P", Var, 0},
+ {"Pahawh_Hmong", Var, 4},
+ {"Palmyrene", Var, 4},
+ {"Pattern_Syntax", Var, 0},
+ {"Pattern_White_Space", Var, 0},
+ {"Pau_Cin_Hau", Var, 4},
+ {"Pc", Var, 0},
+ {"Pd", Var, 0},
+ {"Pe", Var, 0},
+ {"Pf", Var, 0},
+ {"Phags_Pa", Var, 0},
+ {"Phoenician", Var, 0},
+ {"Pi", Var, 0},
+ {"Po", Var, 0},
+ {"Prepended_Concatenation_Mark", Var, 7},
+ {"PrintRanges", Var, 0},
+ {"Properties", Var, 0},
+ {"Ps", Var, 0},
+ {"Psalter_Pahlavi", Var, 4},
+ {"Punct", Var, 0},
+ {"Quotation_Mark", Var, 0},
+ {"Radical", Var, 0},
+ {"Range16", Type, 0},
+ {"Range16.Hi", Field, 0},
+ {"Range16.Lo", Field, 0},
+ {"Range16.Stride", Field, 0},
+ {"Range32", Type, 0},
+ {"Range32.Hi", Field, 0},
+ {"Range32.Lo", Field, 0},
+ {"Range32.Stride", Field, 0},
+ {"RangeTable", Type, 0},
+ {"RangeTable.LatinOffset", Field, 1},
+ {"RangeTable.R16", Field, 0},
+ {"RangeTable.R32", Field, 0},
+ {"Regional_Indicator", Var, 10},
+ {"Rejang", Var, 0},
+ {"ReplacementChar", Const, 0},
+ {"Runic", Var, 0},
+ {"S", Var, 0},
+ {"STerm", Var, 0},
+ {"Samaritan", Var, 0},
+ {"Saurashtra", Var, 0},
+ {"Sc", Var, 0},
+ {"Scripts", Var, 0},
+ {"Sentence_Terminal", Var, 7},
+ {"Sharada", Var, 1},
+ {"Shavian", Var, 0},
+ {"Siddham", Var, 4},
+ {"SignWriting", Var, 5},
+ {"SimpleFold", Func, 0},
+ {"Sinhala", Var, 0},
+ {"Sk", Var, 0},
+ {"Sm", Var, 0},
+ {"So", Var, 0},
+ {"Soft_Dotted", Var, 0},
+ {"Sogdian", Var, 13},
+ {"Sora_Sompeng", Var, 1},
+ {"Soyombo", Var, 10},
+ {"Space", Var, 0},
+ {"SpecialCase", Type, 0},
+ {"Sundanese", Var, 0},
+ {"Syloti_Nagri", Var, 0},
+ {"Symbol", Var, 0},
+ {"Syriac", Var, 0},
+ {"Tagalog", Var, 0},
+ {"Tagbanwa", Var, 0},
+ {"Tai_Le", Var, 0},
+ {"Tai_Tham", Var, 0},
+ {"Tai_Viet", Var, 0},
+ {"Takri", Var, 1},
+ {"Tamil", Var, 0},
+ {"Tangsa", Var, 21},
+ {"Tangut", Var, 7},
+ {"Telugu", Var, 0},
+ {"Terminal_Punctuation", Var, 0},
+ {"Thaana", Var, 0},
+ {"Thai", Var, 0},
+ {"Tibetan", Var, 0},
+ {"Tifinagh", Var, 0},
+ {"Tirhuta", Var, 4},
+ {"Title", Var, 0},
+ {"TitleCase", Const, 0},
+ {"To", Func, 0},
+ {"ToLower", Func, 0},
+ {"ToTitle", Func, 0},
+ {"ToUpper", Func, 0},
+ {"Toto", Var, 21},
+ {"TurkishCase", Var, 0},
+ {"Ugaritic", Var, 0},
+ {"Unified_Ideograph", Var, 0},
+ {"Upper", Var, 0},
+ {"UpperCase", Const, 0},
+ {"UpperLower", Const, 0},
+ {"Vai", Var, 0},
+ {"Variation_Selector", Var, 0},
+ {"Version", Const, 0},
+ {"Vithkuqi", Var, 21},
+ {"Wancho", Var, 14},
+ {"Warang_Citi", Var, 4},
+ {"White_Space", Var, 0},
+ {"Yezidi", Var, 16},
+ {"Yi", Var, 0},
+ {"Z", Var, 0},
+ {"Zanabazar_Square", Var, 10},
+ {"Zl", Var, 0},
+ {"Zp", Var, 0},
+ {"Zs", Var, 0},
+ },
+ "unicode/utf16": {
+ {"AppendRune", Func, 20},
+ {"Decode", Func, 0},
+ {"DecodeRune", Func, 0},
+ {"Encode", Func, 0},
+ {"EncodeRune", Func, 0},
+ {"IsSurrogate", Func, 0},
+ {"RuneLen", Func, 23},
+ },
+ "unicode/utf8": {
+ {"AppendRune", Func, 18},
+ {"DecodeLastRune", Func, 0},
+ {"DecodeLastRuneInString", Func, 0},
+ {"DecodeRune", Func, 0},
+ {"DecodeRuneInString", Func, 0},
+ {"EncodeRune", Func, 0},
+ {"FullRune", Func, 0},
+ {"FullRuneInString", Func, 0},
+ {"MaxRune", Const, 0},
+ {"RuneCount", Func, 0},
+ {"RuneCountInString", Func, 0},
+ {"RuneError", Const, 0},
+ {"RuneLen", Func, 0},
+ {"RuneSelf", Const, 0},
+ {"RuneStart", Func, 0},
+ {"UTFMax", Const, 0},
+ {"Valid", Func, 0},
+ {"ValidRune", Func, 1},
+ {"ValidString", Func, 0},
+ },
+ "unique": {
+ {"(Handle).Value", Method, 23},
+ {"Handle", Type, 23},
+ {"Make", Func, 23},
+ },
+ "unsafe": {
+ {"Add", Func, 0},
+ {"Alignof", Func, 0},
+ {"Offsetof", Func, 0},
+ {"Pointer", Type, 0},
+ {"Sizeof", Func, 0},
+ {"Slice", Func, 0},
+ {"SliceData", Func, 0},
+ {"String", Func, 0},
+ {"StringData", Func, 0},
+ },
+}
diff --git a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go
new file mode 100644
index 00000000..98904017
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go
@@ -0,0 +1,97 @@
+// 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:generate go run generate.go
+
+// Package stdlib provides a table of all exported symbols in the
+// standard library, along with the version at which they first
+// appeared.
+package stdlib
+
+import (
+ "fmt"
+ "strings"
+)
+
+type Symbol struct {
+ Name string
+ Kind Kind
+ Version Version // Go version that first included the symbol
+}
+
+// A Kind indicates the kind of a symbol:
+// function, variable, constant, type, and so on.
+type Kind int8
+
+const (
+ Invalid Kind = iota // Example name:
+ Type // "Buffer"
+ Func // "Println"
+ Var // "EOF"
+ Const // "Pi"
+ Field // "Point.X"
+ Method // "(*Buffer).Grow"
+)
+
+func (kind Kind) String() string {
+ return [...]string{
+ Invalid: "invalid",
+ Type: "type",
+ Func: "func",
+ Var: "var",
+ Const: "const",
+ Field: "field",
+ Method: "method",
+ }[kind]
+}
+
+// A Version represents a version of Go of the form "go1.%d".
+type Version int8
+
+// String returns a version string of the form "go1.23", without allocating.
+func (v Version) String() string { return versions[v] }
+
+var versions [30]string // (increase constant as needed)
+
+func init() {
+ for i := range versions {
+ versions[i] = fmt.Sprintf("go1.%d", i)
+ }
+}
+
+// HasPackage reports whether the specified package path is part of
+// the standard library's public API.
+func HasPackage(path string) bool {
+ _, ok := PackageSymbols[path]
+ return ok
+}
+
+// SplitField splits the field symbol name into type and field
+// components. It must be called only on Field symbols.
+//
+// Example: "File.Package" -> ("File", "Package")
+func (sym *Symbol) SplitField() (typename, name string) {
+ if sym.Kind != Field {
+ panic("not a field")
+ }
+ typename, name, _ = strings.Cut(sym.Name, ".")
+ return
+}
+
+// SplitMethod splits the method symbol name into pointer, receiver,
+// and method components. It must be called only on Method symbols.
+//
+// Example: "(*Buffer).Grow" -> (true, "Buffer", "Grow")
+func (sym *Symbol) SplitMethod() (ptr bool, recv, name string) {
+ if sym.Kind != Method {
+ panic("not a method")
+ }
+ recv, name, _ = strings.Cut(sym.Name, ".")
+ recv = recv[len("(") : len(recv)-len(")")]
+ ptr = recv[0] == '*'
+ if ptr {
+ recv = recv[len("*"):]
+ }
+ return
+}
diff --git a/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go b/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go
new file mode 100644
index 00000000..ff9437a3
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go
@@ -0,0 +1,137 @@
+// 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 tokeninternal provides access to some internal features of the token
+// package.
+package tokeninternal
+
+import (
+ "fmt"
+ "go/token"
+ "sort"
+ "sync"
+ "unsafe"
+)
+
+// GetLines returns the table of line-start offsets from a token.File.
+func GetLines(file *token.File) []int {
+ // token.File has a Lines method on Go 1.21 and later.
+ if file, ok := (interface{})(file).(interface{ Lines() []int }); ok {
+ return file.Lines()
+ }
+
+ // This declaration must match that of token.File.
+ // This creates a risk of dependency skew.
+ // For now we check that the size of the two
+ // declarations is the same, on the (fragile) assumption
+ // that future changes would add fields.
+ type tokenFile119 struct {
+ _ string
+ _ int
+ _ int
+ mu sync.Mutex // we're not complete monsters
+ lines []int
+ _ []struct{}
+ }
+
+ if unsafe.Sizeof(*file) != unsafe.Sizeof(tokenFile119{}) {
+ panic("unexpected token.File size")
+ }
+ var ptr *tokenFile119
+ type uP = unsafe.Pointer
+ *(*uP)(uP(&ptr)) = uP(file)
+ ptr.mu.Lock()
+ defer ptr.mu.Unlock()
+ return ptr.lines
+}
+
+// AddExistingFiles adds the specified files to the FileSet if they
+// are not already present. It panics if any pair of files in the
+// resulting FileSet would overlap.
+func AddExistingFiles(fset *token.FileSet, files []*token.File) {
+ // Punch through the FileSet encapsulation.
+ type tokenFileSet struct {
+ // This type remained essentially consistent from go1.16 to go1.21.
+ mutex sync.RWMutex
+ base int
+ files []*token.File
+ _ *token.File // changed to atomic.Pointer[token.File] in go1.19
+ }
+
+ // If the size of token.FileSet changes, this will fail to compile.
+ const delta = int64(unsafe.Sizeof(tokenFileSet{})) - int64(unsafe.Sizeof(token.FileSet{}))
+ var _ [-delta * delta]int
+
+ type uP = unsafe.Pointer
+ var ptr *tokenFileSet
+ *(*uP)(uP(&ptr)) = uP(fset)
+ ptr.mutex.Lock()
+ defer ptr.mutex.Unlock()
+
+ // Merge and sort.
+ newFiles := append(ptr.files, files...)
+ sort.Slice(newFiles, func(i, j int) bool {
+ return newFiles[i].Base() < newFiles[j].Base()
+ })
+
+ // Reject overlapping files.
+ // Discard adjacent identical files.
+ out := newFiles[:0]
+ for i, file := range newFiles {
+ if i > 0 {
+ prev := newFiles[i-1]
+ if file == prev {
+ continue
+ }
+ if prev.Base()+prev.Size()+1 > file.Base() {
+ panic(fmt.Sprintf("file %s (%d-%d) overlaps with file %s (%d-%d)",
+ prev.Name(), prev.Base(), prev.Base()+prev.Size(),
+ file.Name(), file.Base(), file.Base()+file.Size()))
+ }
+ }
+ out = append(out, file)
+ }
+ newFiles = out
+
+ ptr.files = newFiles
+
+ // Advance FileSet.Base().
+ if len(newFiles) > 0 {
+ last := newFiles[len(newFiles)-1]
+ newBase := last.Base() + last.Size() + 1
+ if ptr.base < newBase {
+ ptr.base = newBase
+ }
+ }
+}
+
+// FileSetFor returns a new FileSet containing a sequence of new Files with
+// the same base, size, and line as the input files, for use in APIs that
+// require a FileSet.
+//
+// Precondition: the input files must be non-overlapping, and sorted in order
+// of their Base.
+func FileSetFor(files ...*token.File) *token.FileSet {
+ fset := token.NewFileSet()
+ for _, f := range files {
+ f2 := fset.AddFile(f.Name(), f.Base(), f.Size())
+ lines := GetLines(f)
+ f2.SetLines(lines)
+ }
+ return fset
+}
+
+// CloneFileSet creates a new FileSet holding all files in fset. It does not
+// create copies of the token.Files in fset: they are added to the resulting
+// FileSet unmodified.
+func CloneFileSet(fset *token.FileSet) *token.FileSet {
+ var files []*token.File
+ fset.Iterate(func(f *token.File) bool {
+ files = append(files, f)
+ return true
+ })
+ newFileSet := token.NewFileSet()
+ AddExistingFiles(newFileSet, files)
+ return newFileSet
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go
new file mode 100644
index 00000000..834e0538
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go
@@ -0,0 +1,1560 @@
+// 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.
+
+package typesinternal
+
+//go:generate stringer -type=ErrorCode
+
+type ErrorCode int
+
+// This file defines the error codes that can be produced during type-checking.
+// Collectively, these codes provide an identifier that may be used to
+// implement special handling for certain types of errors.
+//
+// Error codes should be fine-grained enough that the exact nature of the error
+// can be easily determined, but coarse enough that they are not an
+// implementation detail of the type checking algorithm. As a rule-of-thumb,
+// errors should be considered equivalent if there is a theoretical refactoring
+// of the type checker in which they are emitted in exactly one place. For
+// example, the type checker emits different error messages for "too many
+// arguments" and "too few arguments", but one can imagine an alternative type
+// checker where this check instead just emits a single "wrong number of
+// arguments", so these errors should have the same code.
+//
+// Error code names should be as brief as possible while retaining accuracy and
+// distinctiveness. In most cases names should start with an adjective
+// describing the nature of the error (e.g. "invalid", "unused", "misplaced"),
+// and end with a noun identifying the relevant language object. For example,
+// "DuplicateDecl" or "InvalidSliceExpr". For brevity, naming follows the
+// convention that "bad" implies a problem with syntax, and "invalid" implies a
+// problem with types.
+
+const (
+ // InvalidSyntaxTree occurs if an invalid syntax tree is provided
+ // to the type checker. It should never happen.
+ InvalidSyntaxTree ErrorCode = -1
+)
+
+const (
+ _ ErrorCode = iota
+
+ // Test is reserved for errors that only apply while in self-test mode.
+ Test
+
+ /* package names */
+
+ // BlankPkgName occurs when a package name is the blank identifier "_".
+ //
+ // Per the spec:
+ // "The PackageName must not be the blank identifier."
+ BlankPkgName
+
+ // MismatchedPkgName occurs when a file's package name doesn't match the
+ // package name already established by other files.
+ MismatchedPkgName
+
+ // InvalidPkgUse occurs when a package identifier is used outside of a
+ // selector expression.
+ //
+ // Example:
+ // import "fmt"
+ //
+ // var _ = fmt
+ InvalidPkgUse
+
+ /* imports */
+
+ // BadImportPath occurs when an import path is not valid.
+ BadImportPath
+
+ // BrokenImport occurs when importing a package fails.
+ //
+ // Example:
+ // import "amissingpackage"
+ BrokenImport
+
+ // ImportCRenamed occurs when the special import "C" is renamed. "C" is a
+ // pseudo-package, and must not be renamed.
+ //
+ // Example:
+ // import _ "C"
+ ImportCRenamed
+
+ // UnusedImport occurs when an import is unused.
+ //
+ // Example:
+ // import "fmt"
+ //
+ // func main() {}
+ UnusedImport
+
+ /* initialization */
+
+ // InvalidInitCycle occurs when an invalid cycle is detected within the
+ // initialization graph.
+ //
+ // Example:
+ // var x int = f()
+ //
+ // func f() int { return x }
+ InvalidInitCycle
+
+ /* decls */
+
+ // DuplicateDecl occurs when an identifier is declared multiple times.
+ //
+ // Example:
+ // var x = 1
+ // var x = 2
+ DuplicateDecl
+
+ // InvalidDeclCycle occurs when a declaration cycle is not valid.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // type T struct {
+ // a [n]int
+ // }
+ //
+ // var n = unsafe.Sizeof(T{})
+ InvalidDeclCycle
+
+ // InvalidTypeCycle occurs when a cycle in type definitions results in a
+ // type that is not well-defined.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // type T [unsafe.Sizeof(T{})]int
+ InvalidTypeCycle
+
+ /* decls > const */
+
+ // InvalidConstInit occurs when a const declaration has a non-constant
+ // initializer.
+ //
+ // Example:
+ // var x int
+ // const _ = x
+ InvalidConstInit
+
+ // InvalidConstVal occurs when a const value cannot be converted to its
+ // target type.
+ //
+ // TODO(findleyr): this error code and example are not very clear. Consider
+ // removing it.
+ //
+ // Example:
+ // const _ = 1 << "hello"
+ InvalidConstVal
+
+ // InvalidConstType occurs when the underlying type in a const declaration
+ // is not a valid constant type.
+ //
+ // Example:
+ // const c *int = 4
+ InvalidConstType
+
+ /* decls > var (+ other variable assignment codes) */
+
+ // UntypedNilUse occurs when the predeclared (untyped) value nil is used to
+ // initialize a variable declared without an explicit type.
+ //
+ // Example:
+ // var x = nil
+ UntypedNilUse
+
+ // WrongAssignCount occurs when the number of values on the right-hand side
+ // of an assignment or initialization expression does not match the number
+ // of variables on the left-hand side.
+ //
+ // Example:
+ // var x = 1, 2
+ WrongAssignCount
+
+ // UnassignableOperand occurs when the left-hand side of an assignment is
+ // not assignable.
+ //
+ // Example:
+ // func f() {
+ // const c = 1
+ // c = 2
+ // }
+ UnassignableOperand
+
+ // NoNewVar occurs when a short variable declaration (':=') does not declare
+ // new variables.
+ //
+ // Example:
+ // func f() {
+ // x := 1
+ // x := 2
+ // }
+ NoNewVar
+
+ // MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does
+ // not have single-valued left-hand or right-hand side.
+ //
+ // Per the spec:
+ // "In assignment operations, both the left- and right-hand expression lists
+ // must contain exactly one single-valued expression"
+ //
+ // Example:
+ // func f() int {
+ // x, y := 1, 2
+ // x, y += 1
+ // return x + y
+ // }
+ MultiValAssignOp
+
+ // InvalidIfaceAssign occurs when a value of type T is used as an
+ // interface, but T does not implement a method of the expected interface.
+ //
+ // Example:
+ // type I interface {
+ // f()
+ // }
+ //
+ // type T int
+ //
+ // var x I = T(1)
+ InvalidIfaceAssign
+
+ // InvalidChanAssign occurs when a chan assignment is invalid.
+ //
+ // Per the spec, a value x is assignable to a channel type T if:
+ // "x is a bidirectional channel value, T is a channel type, x's type V and
+ // T have identical element types, and at least one of V or T is not a
+ // defined type."
+ //
+ // Example:
+ // type T1 chan int
+ // type T2 chan int
+ //
+ // var x T1
+ // // Invalid assignment because both types are named
+ // var _ T2 = x
+ InvalidChanAssign
+
+ // IncompatibleAssign occurs when the type of the right-hand side expression
+ // in an assignment cannot be assigned to the type of the variable being
+ // assigned.
+ //
+ // Example:
+ // var x []int
+ // var _ int = x
+ IncompatibleAssign
+
+ // UnaddressableFieldAssign occurs when trying to assign to a struct field
+ // in a map value.
+ //
+ // Example:
+ // func f() {
+ // m := make(map[string]struct{i int})
+ // m["foo"].i = 42
+ // }
+ UnaddressableFieldAssign
+
+ /* decls > type (+ other type expression codes) */
+
+ // NotAType occurs when the identifier used as the underlying type in a type
+ // declaration or the right-hand side of a type alias does not denote a type.
+ //
+ // Example:
+ // var S = 2
+ //
+ // type T S
+ NotAType
+
+ // InvalidArrayLen occurs when an array length is not a constant value.
+ //
+ // Example:
+ // var n = 3
+ // var _ = [n]int{}
+ InvalidArrayLen
+
+ // BlankIfaceMethod occurs when a method name is '_'.
+ //
+ // Per the spec:
+ // "The name of each explicitly specified method must be unique and not
+ // blank."
+ //
+ // Example:
+ // type T interface {
+ // _(int)
+ // }
+ BlankIfaceMethod
+
+ // IncomparableMapKey occurs when a map key type does not support the == and
+ // != operators.
+ //
+ // Per the spec:
+ // "The comparison operators == and != must be fully defined for operands of
+ // the key type; thus the key type must not be a function, map, or slice."
+ //
+ // Example:
+ // var x map[T]int
+ //
+ // type T []int
+ IncomparableMapKey
+
+ // InvalidIfaceEmbed occurs when a non-interface type is embedded in an
+ // interface.
+ //
+ // Example:
+ // type T struct {}
+ //
+ // func (T) m()
+ //
+ // type I interface {
+ // T
+ // }
+ InvalidIfaceEmbed
+
+ // InvalidPtrEmbed occurs when an embedded field is of the pointer form *T,
+ // and T itself is itself a pointer, an unsafe.Pointer, or an interface.
+ //
+ // Per the spec:
+ // "An embedded field must be specified as a type name T or as a pointer to
+ // a non-interface type name *T, and T itself may not be a pointer type."
+ //
+ // Example:
+ // type T *int
+ //
+ // type S struct {
+ // *T
+ // }
+ InvalidPtrEmbed
+
+ /* decls > func and method */
+
+ // BadRecv occurs when a method declaration does not have exactly one
+ // receiver parameter.
+ //
+ // Example:
+ // func () _() {}
+ BadRecv
+
+ // InvalidRecv occurs when a receiver type expression is not of the form T
+ // or *T, or T is a pointer type.
+ //
+ // Example:
+ // type T struct {}
+ //
+ // func (**T) m() {}
+ InvalidRecv
+
+ // DuplicateFieldAndMethod occurs when an identifier appears as both a field
+ // and method name.
+ //
+ // Example:
+ // type T struct {
+ // m int
+ // }
+ //
+ // func (T) m() {}
+ DuplicateFieldAndMethod
+
+ // DuplicateMethod occurs when two methods on the same receiver type have
+ // the same name.
+ //
+ // Example:
+ // type T struct {}
+ // func (T) m() {}
+ // func (T) m(i int) int { return i }
+ DuplicateMethod
+
+ /* decls > special */
+
+ // InvalidBlank occurs when a blank identifier is used as a value or type.
+ //
+ // Per the spec:
+ // "The blank identifier may appear as an operand only on the left-hand side
+ // of an assignment."
+ //
+ // Example:
+ // var x = _
+ InvalidBlank
+
+ // InvalidIota occurs when the predeclared identifier iota is used outside
+ // of a constant declaration.
+ //
+ // Example:
+ // var x = iota
+ InvalidIota
+
+ // MissingInitBody occurs when an init function is missing its body.
+ //
+ // Example:
+ // func init()
+ MissingInitBody
+
+ // InvalidInitSig occurs when an init function declares parameters or
+ // results.
+ //
+ // Example:
+ // func init() int { return 1 }
+ InvalidInitSig
+
+ // InvalidInitDecl occurs when init is declared as anything other than a
+ // function.
+ //
+ // Example:
+ // var init = 1
+ InvalidInitDecl
+
+ // InvalidMainDecl occurs when main is declared as anything other than a
+ // function, in a main package.
+ InvalidMainDecl
+
+ /* exprs */
+
+ // TooManyValues occurs when a function returns too many values for the
+ // expression context in which it is used.
+ //
+ // Example:
+ // func ReturnTwo() (int, int) {
+ // return 1, 2
+ // }
+ //
+ // var x = ReturnTwo()
+ TooManyValues
+
+ // NotAnExpr occurs when a type expression is used where a value expression
+ // is expected.
+ //
+ // Example:
+ // type T struct {}
+ //
+ // func f() {
+ // T
+ // }
+ NotAnExpr
+
+ /* exprs > const */
+
+ // TruncatedFloat occurs when a float constant is truncated to an integer
+ // value.
+ //
+ // Example:
+ // var _ int = 98.6
+ TruncatedFloat
+
+ // NumericOverflow occurs when a numeric constant overflows its target type.
+ //
+ // Example:
+ // var x int8 = 1000
+ NumericOverflow
+
+ /* exprs > operation */
+
+ // UndefinedOp occurs when an operator is not defined for the type(s) used
+ // in an operation.
+ //
+ // Example:
+ // var c = "a" - "b"
+ UndefinedOp
+
+ // MismatchedTypes occurs when operand types are incompatible in a binary
+ // operation.
+ //
+ // Example:
+ // var a = "hello"
+ // var b = 1
+ // var c = a - b
+ MismatchedTypes
+
+ // DivByZero occurs when a division operation is provable at compile
+ // time to be a division by zero.
+ //
+ // Example:
+ // const divisor = 0
+ // var x int = 1/divisor
+ DivByZero
+
+ // NonNumericIncDec occurs when an increment or decrement operator is
+ // applied to a non-numeric value.
+ //
+ // Example:
+ // func f() {
+ // var c = "c"
+ // c++
+ // }
+ NonNumericIncDec
+
+ /* exprs > ptr */
+
+ // UnaddressableOperand occurs when the & operator is applied to an
+ // unaddressable expression.
+ //
+ // Example:
+ // var x = &1
+ UnaddressableOperand
+
+ // InvalidIndirection occurs when a non-pointer value is indirected via the
+ // '*' operator.
+ //
+ // Example:
+ // var x int
+ // var y = *x
+ InvalidIndirection
+
+ /* exprs > [] */
+
+ // NonIndexableOperand occurs when an index operation is applied to a value
+ // that cannot be indexed.
+ //
+ // Example:
+ // var x = 1
+ // var y = x[1]
+ NonIndexableOperand
+
+ // InvalidIndex occurs when an index argument is not of integer type,
+ // negative, or out-of-bounds.
+ //
+ // Example:
+ // var s = [...]int{1,2,3}
+ // var x = s[5]
+ //
+ // Example:
+ // var s = []int{1,2,3}
+ // var _ = s[-1]
+ //
+ // Example:
+ // var s = []int{1,2,3}
+ // var i string
+ // var _ = s[i]
+ InvalidIndex
+
+ // SwappedSliceIndices occurs when constant indices in a slice expression
+ // are decreasing in value.
+ //
+ // Example:
+ // var _ = []int{1,2,3}[2:1]
+ SwappedSliceIndices
+
+ /* operators > slice */
+
+ // NonSliceableOperand occurs when a slice operation is applied to a value
+ // whose type is not sliceable, or is unaddressable.
+ //
+ // Example:
+ // var x = [...]int{1, 2, 3}[:1]
+ //
+ // Example:
+ // var x = 1
+ // var y = 1[:1]
+ NonSliceableOperand
+
+ // InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is
+ // applied to a string.
+ //
+ // Example:
+ // var s = "hello"
+ // var x = s[1:2:3]
+ InvalidSliceExpr
+
+ /* exprs > shift */
+
+ // InvalidShiftCount occurs when the right-hand side of a shift operation is
+ // either non-integer, negative, or too large.
+ //
+ // Example:
+ // var (
+ // x string
+ // y int = 1 << x
+ // )
+ InvalidShiftCount
+
+ // InvalidShiftOperand occurs when the shifted operand is not an integer.
+ //
+ // Example:
+ // var s = "hello"
+ // var x = s << 2
+ InvalidShiftOperand
+
+ /* exprs > chan */
+
+ // InvalidReceive occurs when there is a channel receive from a value that
+ // is either not a channel, or is a send-only channel.
+ //
+ // Example:
+ // func f() {
+ // var x = 1
+ // <-x
+ // }
+ InvalidReceive
+
+ // InvalidSend occurs when there is a channel send to a value that is not a
+ // channel, or is a receive-only channel.
+ //
+ // Example:
+ // func f() {
+ // var x = 1
+ // x <- "hello!"
+ // }
+ InvalidSend
+
+ /* exprs > literal */
+
+ // DuplicateLitKey occurs when an index is duplicated in a slice, array, or
+ // map literal.
+ //
+ // Example:
+ // var _ = []int{0:1, 0:2}
+ //
+ // Example:
+ // var _ = map[string]int{"a": 1, "a": 2}
+ DuplicateLitKey
+
+ // MissingLitKey occurs when a map literal is missing a key expression.
+ //
+ // Example:
+ // var _ = map[string]int{1}
+ MissingLitKey
+
+ // InvalidLitIndex occurs when the key in a key-value element of a slice or
+ // array literal is not an integer constant.
+ //
+ // Example:
+ // var i = 0
+ // var x = []string{i: "world"}
+ InvalidLitIndex
+
+ // OversizeArrayLit occurs when an array literal exceeds its length.
+ //
+ // Example:
+ // var _ = [2]int{1,2,3}
+ OversizeArrayLit
+
+ // MixedStructLit occurs when a struct literal contains a mix of positional
+ // and named elements.
+ //
+ // Example:
+ // var _ = struct{i, j int}{i: 1, 2}
+ MixedStructLit
+
+ // InvalidStructLit occurs when a positional struct literal has an incorrect
+ // number of values.
+ //
+ // Example:
+ // var _ = struct{i, j int}{1,2,3}
+ InvalidStructLit
+
+ // MissingLitField occurs when a struct literal refers to a field that does
+ // not exist on the struct type.
+ //
+ // Example:
+ // var _ = struct{i int}{j: 2}
+ MissingLitField
+
+ // DuplicateLitField occurs when a struct literal contains duplicated
+ // fields.
+ //
+ // Example:
+ // var _ = struct{i int}{i: 1, i: 2}
+ DuplicateLitField
+
+ // UnexportedLitField occurs when a positional struct literal implicitly
+ // assigns an unexported field of an imported type.
+ UnexportedLitField
+
+ // InvalidLitField occurs when a field name is not a valid identifier.
+ //
+ // Example:
+ // var _ = struct{i int}{1: 1}
+ InvalidLitField
+
+ // UntypedLit occurs when a composite literal omits a required type
+ // identifier.
+ //
+ // Example:
+ // type outer struct{
+ // inner struct { i int }
+ // }
+ //
+ // var _ = outer{inner: {1}}
+ UntypedLit
+
+ // InvalidLit occurs when a composite literal expression does not match its
+ // type.
+ //
+ // Example:
+ // type P *struct{
+ // x int
+ // }
+ // var _ = P {}
+ InvalidLit
+
+ /* exprs > selector */
+
+ // AmbiguousSelector occurs when a selector is ambiguous.
+ //
+ // Example:
+ // type E1 struct { i int }
+ // type E2 struct { i int }
+ // type T struct { E1; E2 }
+ //
+ // var x T
+ // var _ = x.i
+ AmbiguousSelector
+
+ // UndeclaredImportedName occurs when a package-qualified identifier is
+ // undeclared by the imported package.
+ //
+ // Example:
+ // import "go/types"
+ //
+ // var _ = types.NotAnActualIdentifier
+ UndeclaredImportedName
+
+ // UnexportedName occurs when a selector refers to an unexported identifier
+ // of an imported package.
+ //
+ // Example:
+ // import "reflect"
+ //
+ // type _ reflect.flag
+ UnexportedName
+
+ // UndeclaredName occurs when an identifier is not declared in the current
+ // scope.
+ //
+ // Example:
+ // var x T
+ UndeclaredName
+
+ // MissingFieldOrMethod occurs when a selector references a field or method
+ // that does not exist.
+ //
+ // Example:
+ // type T struct {}
+ //
+ // var x = T{}.f
+ MissingFieldOrMethod
+
+ /* exprs > ... */
+
+ // BadDotDotDotSyntax occurs when a "..." occurs in a context where it is
+ // not valid.
+ //
+ // Example:
+ // var _ = map[int][...]int{0: {}}
+ BadDotDotDotSyntax
+
+ // NonVariadicDotDotDot occurs when a "..." is used on the final argument to
+ // a non-variadic function.
+ //
+ // Example:
+ // func printArgs(s []string) {
+ // for _, a := range s {
+ // println(a)
+ // }
+ // }
+ //
+ // func f() {
+ // s := []string{"a", "b", "c"}
+ // printArgs(s...)
+ // }
+ NonVariadicDotDotDot
+
+ // MisplacedDotDotDot occurs when a "..." is used somewhere other than the
+ // final argument to a function call.
+ //
+ // Example:
+ // func printArgs(args ...int) {
+ // for _, a := range args {
+ // println(a)
+ // }
+ // }
+ //
+ // func f() {
+ // a := []int{1,2,3}
+ // printArgs(0, a...)
+ // }
+ MisplacedDotDotDot
+
+ // InvalidDotDotDotOperand occurs when a "..." operator is applied to a
+ // single-valued operand.
+ //
+ // Example:
+ // func printArgs(args ...int) {
+ // for _, a := range args {
+ // println(a)
+ // }
+ // }
+ //
+ // func f() {
+ // a := 1
+ // printArgs(a...)
+ // }
+ //
+ // Example:
+ // func args() (int, int) {
+ // return 1, 2
+ // }
+ //
+ // func printArgs(args ...int) {
+ // for _, a := range args {
+ // println(a)
+ // }
+ // }
+ //
+ // func g() {
+ // printArgs(args()...)
+ // }
+ InvalidDotDotDotOperand
+
+ // InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in
+ // function.
+ //
+ // Example:
+ // var s = []int{1, 2, 3}
+ // var l = len(s...)
+ InvalidDotDotDot
+
+ /* exprs > built-in */
+
+ // UncalledBuiltin occurs when a built-in function is used as a
+ // function-valued expression, instead of being called.
+ //
+ // Per the spec:
+ // "The built-in functions do not have standard Go types, so they can only
+ // appear in call expressions; they cannot be used as function values."
+ //
+ // Example:
+ // var _ = copy
+ UncalledBuiltin
+
+ // InvalidAppend occurs when append is called with a first argument that is
+ // not a slice.
+ //
+ // Example:
+ // var _ = append(1, 2)
+ InvalidAppend
+
+ // InvalidCap occurs when an argument to the cap built-in function is not of
+ // supported type.
+ //
+ // See https://golang.org/ref/spec#Lengthand_capacity for information on
+ // which underlying types are supported as arguments to cap and len.
+ //
+ // Example:
+ // var s = 2
+ // var x = cap(s)
+ InvalidCap
+
+ // InvalidClose occurs when close(...) is called with an argument that is
+ // not of channel type, or that is a receive-only channel.
+ //
+ // Example:
+ // func f() {
+ // var x int
+ // close(x)
+ // }
+ InvalidClose
+
+ // InvalidCopy occurs when the arguments are not of slice type or do not
+ // have compatible type.
+ //
+ // See https://golang.org/ref/spec#Appendingand_copying_slices for more
+ // information on the type requirements for the copy built-in.
+ //
+ // Example:
+ // func f() {
+ // var x []int
+ // y := []int64{1,2,3}
+ // copy(x, y)
+ // }
+ InvalidCopy
+
+ // InvalidComplex occurs when the complex built-in function is called with
+ // arguments with incompatible types.
+ //
+ // Example:
+ // var _ = complex(float32(1), float64(2))
+ InvalidComplex
+
+ // InvalidDelete occurs when the delete built-in function is called with a
+ // first argument that is not a map.
+ //
+ // Example:
+ // func f() {
+ // m := "hello"
+ // delete(m, "e")
+ // }
+ InvalidDelete
+
+ // InvalidImag occurs when the imag built-in function is called with an
+ // argument that does not have complex type.
+ //
+ // Example:
+ // var _ = imag(int(1))
+ InvalidImag
+
+ // InvalidLen occurs when an argument to the len built-in function is not of
+ // supported type.
+ //
+ // See https://golang.org/ref/spec#Lengthand_capacity for information on
+ // which underlying types are supported as arguments to cap and len.
+ //
+ // Example:
+ // var s = 2
+ // var x = len(s)
+ InvalidLen
+
+ // SwappedMakeArgs occurs when make is called with three arguments, and its
+ // length argument is larger than its capacity argument.
+ //
+ // Example:
+ // var x = make([]int, 3, 2)
+ SwappedMakeArgs
+
+ // InvalidMake occurs when make is called with an unsupported type argument.
+ //
+ // See https://golang.org/ref/spec#Makingslices_maps_and_channels for
+ // information on the types that may be created using make.
+ //
+ // Example:
+ // var x = make(int)
+ InvalidMake
+
+ // InvalidReal occurs when the real built-in function is called with an
+ // argument that does not have complex type.
+ //
+ // Example:
+ // var _ = real(int(1))
+ InvalidReal
+
+ /* exprs > assertion */
+
+ // InvalidAssert occurs when a type assertion is applied to a
+ // value that is not of interface type.
+ //
+ // Example:
+ // var x = 1
+ // var _ = x.(float64)
+ InvalidAssert
+
+ // ImpossibleAssert occurs for a type assertion x.(T) when the value x of
+ // interface cannot have dynamic type T, due to a missing or mismatching
+ // method on T.
+ //
+ // Example:
+ // type T int
+ //
+ // func (t *T) m() int { return int(*t) }
+ //
+ // type I interface { m() int }
+ //
+ // var x I
+ // var _ = x.(T)
+ ImpossibleAssert
+
+ /* exprs > conversion */
+
+ // InvalidConversion occurs when the argument type cannot be converted to the
+ // target.
+ //
+ // See https://golang.org/ref/spec#Conversions for the rules of
+ // convertibility.
+ //
+ // Example:
+ // var x float64
+ // var _ = string(x)
+ InvalidConversion
+
+ // InvalidUntypedConversion occurs when an there is no valid implicit
+ // conversion from an untyped value satisfying the type constraints of the
+ // context in which it is used.
+ //
+ // Example:
+ // var _ = 1 + ""
+ InvalidUntypedConversion
+
+ /* offsetof */
+
+ // BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
+ // that is not a selector expression.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Offsetof(x)
+ BadOffsetofSyntax
+
+ // InvalidOffsetof occurs when unsafe.Offsetof is called with a method
+ // selector, rather than a field selector, or when the field is embedded via
+ // a pointer.
+ //
+ // Per the spec:
+ //
+ // "If f is an embedded field, it must be reachable without pointer
+ // indirections through fields of the struct. "
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // type T struct { f int }
+ // type S struct { *T }
+ // var s S
+ // var _ = unsafe.Offsetof(s.f)
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // type S struct{}
+ //
+ // func (S) m() {}
+ //
+ // var s S
+ // var _ = unsafe.Offsetof(s.m)
+ InvalidOffsetof
+
+ /* control flow > scope */
+
+ // UnusedExpr occurs when a side-effect free expression is used as a
+ // statement. Such a statement has no effect.
+ //
+ // Example:
+ // func f(i int) {
+ // i*i
+ // }
+ UnusedExpr
+
+ // UnusedVar occurs when a variable is declared but unused.
+ //
+ // Example:
+ // func f() {
+ // x := 1
+ // }
+ UnusedVar
+
+ // MissingReturn occurs when a function with results is missing a return
+ // statement.
+ //
+ // Example:
+ // func f() int {}
+ MissingReturn
+
+ // WrongResultCount occurs when a return statement returns an incorrect
+ // number of values.
+ //
+ // Example:
+ // func ReturnOne() int {
+ // return 1, 2
+ // }
+ WrongResultCount
+
+ // OutOfScopeResult occurs when the name of a value implicitly returned by
+ // an empty return statement is shadowed in a nested scope.
+ //
+ // Example:
+ // func factor(n int) (i int) {
+ // for i := 2; i < n; i++ {
+ // if n%i == 0 {
+ // return
+ // }
+ // }
+ // return 0
+ // }
+ OutOfScopeResult
+
+ /* control flow > if */
+
+ // InvalidCond occurs when an if condition is not a boolean expression.
+ //
+ // Example:
+ // func checkReturn(i int) {
+ // if i {
+ // panic("non-zero return")
+ // }
+ // }
+ InvalidCond
+
+ /* control flow > for */
+
+ // InvalidPostDecl occurs when there is a declaration in a for-loop post
+ // statement.
+ //
+ // Example:
+ // func f() {
+ // for i := 0; i < 10; j := 0 {}
+ // }
+ InvalidPostDecl
+
+ // InvalidChanRange occurs when a send-only channel used in a range
+ // expression.
+ //
+ // Example:
+ // func sum(c chan<- int) {
+ // s := 0
+ // for i := range c {
+ // s += i
+ // }
+ // }
+ InvalidChanRange
+
+ // InvalidIterVar occurs when two iteration variables are used while ranging
+ // over a channel.
+ //
+ // Example:
+ // func f(c chan int) {
+ // for k, v := range c {
+ // println(k, v)
+ // }
+ // }
+ InvalidIterVar
+
+ // InvalidRangeExpr occurs when the type of a range expression is not array,
+ // slice, string, map, or channel.
+ //
+ // Example:
+ // func f(i int) {
+ // for j := range i {
+ // println(j)
+ // }
+ // }
+ InvalidRangeExpr
+
+ /* control flow > switch */
+
+ // MisplacedBreak occurs when a break statement is not within a for, switch,
+ // or select statement of the innermost function definition.
+ //
+ // Example:
+ // func f() {
+ // break
+ // }
+ MisplacedBreak
+
+ // MisplacedContinue occurs when a continue statement is not within a for
+ // loop of the innermost function definition.
+ //
+ // Example:
+ // func sumeven(n int) int {
+ // proceed := func() {
+ // continue
+ // }
+ // sum := 0
+ // for i := 1; i <= n; i++ {
+ // if i % 2 != 0 {
+ // proceed()
+ // }
+ // sum += i
+ // }
+ // return sum
+ // }
+ MisplacedContinue
+
+ // MisplacedFallthrough occurs when a fallthrough statement is not within an
+ // expression switch.
+ //
+ // Example:
+ // func typename(i interface{}) string {
+ // switch i.(type) {
+ // case int64:
+ // fallthrough
+ // case int:
+ // return "int"
+ // }
+ // return "unsupported"
+ // }
+ MisplacedFallthrough
+
+ // DuplicateCase occurs when a type or expression switch has duplicate
+ // cases.
+ //
+ // Example:
+ // func printInt(i int) {
+ // switch i {
+ // case 1:
+ // println("one")
+ // case 1:
+ // println("One")
+ // }
+ // }
+ DuplicateCase
+
+ // DuplicateDefault occurs when a type or expression switch has multiple
+ // default clauses.
+ //
+ // Example:
+ // func printInt(i int) {
+ // switch i {
+ // case 1:
+ // println("one")
+ // default:
+ // println("One")
+ // default:
+ // println("1")
+ // }
+ // }
+ DuplicateDefault
+
+ // BadTypeKeyword occurs when a .(type) expression is used anywhere other
+ // than a type switch.
+ //
+ // Example:
+ // type I interface {
+ // m()
+ // }
+ // var t I
+ // var _ = t.(type)
+ BadTypeKeyword
+
+ // InvalidTypeSwitch occurs when .(type) is used on an expression that is
+ // not of interface type.
+ //
+ // Example:
+ // func f(i int) {
+ // switch x := i.(type) {}
+ // }
+ InvalidTypeSwitch
+
+ // InvalidExprSwitch occurs when a switch expression is not comparable.
+ //
+ // Example:
+ // func _() {
+ // var a struct{ _ func() }
+ // switch a /* ERROR cannot switch on a */ {
+ // }
+ // }
+ InvalidExprSwitch
+
+ /* control flow > select */
+
+ // InvalidSelectCase occurs when a select case is not a channel send or
+ // receive.
+ //
+ // Example:
+ // func checkChan(c <-chan int) bool {
+ // select {
+ // case c:
+ // return true
+ // default:
+ // return false
+ // }
+ // }
+ InvalidSelectCase
+
+ /* control flow > labels and jumps */
+
+ // UndeclaredLabel occurs when an undeclared label is jumped to.
+ //
+ // Example:
+ // func f() {
+ // goto L
+ // }
+ UndeclaredLabel
+
+ // DuplicateLabel occurs when a label is declared more than once.
+ //
+ // Example:
+ // func f() int {
+ // L:
+ // L:
+ // return 1
+ // }
+ DuplicateLabel
+
+ // MisplacedLabel occurs when a break or continue label is not on a for,
+ // switch, or select statement.
+ //
+ // Example:
+ // func f() {
+ // L:
+ // a := []int{1,2,3}
+ // for _, e := range a {
+ // if e > 10 {
+ // break L
+ // }
+ // println(a)
+ // }
+ // }
+ MisplacedLabel
+
+ // UnusedLabel occurs when a label is declared but not used.
+ //
+ // Example:
+ // func f() {
+ // L:
+ // }
+ UnusedLabel
+
+ // JumpOverDecl occurs when a label jumps over a variable declaration.
+ //
+ // Example:
+ // func f() int {
+ // goto L
+ // x := 2
+ // L:
+ // x++
+ // return x
+ // }
+ JumpOverDecl
+
+ // JumpIntoBlock occurs when a forward jump goes to a label inside a nested
+ // block.
+ //
+ // Example:
+ // func f(x int) {
+ // goto L
+ // if x > 0 {
+ // L:
+ // print("inside block")
+ // }
+ // }
+ JumpIntoBlock
+
+ /* control flow > calls */
+
+ // InvalidMethodExpr occurs when a pointer method is called but the argument
+ // is not addressable.
+ //
+ // Example:
+ // type T struct {}
+ //
+ // func (*T) m() int { return 1 }
+ //
+ // var _ = T.m(T{})
+ InvalidMethodExpr
+
+ // WrongArgCount occurs when too few or too many arguments are passed by a
+ // function call.
+ //
+ // Example:
+ // func f(i int) {}
+ // var x = f()
+ WrongArgCount
+
+ // InvalidCall occurs when an expression is called that is not of function
+ // type.
+ //
+ // Example:
+ // var x = "x"
+ // var y = x()
+ InvalidCall
+
+ /* control flow > suspended */
+
+ // UnusedResults occurs when a restricted expression-only built-in function
+ // is suspended via go or defer. Such a suspension discards the results of
+ // these side-effect free built-in functions, and therefore is ineffectual.
+ //
+ // Example:
+ // func f(a []int) int {
+ // defer len(a)
+ // return i
+ // }
+ UnusedResults
+
+ // InvalidDefer occurs when a deferred expression is not a function call,
+ // for example if the expression is a type conversion.
+ //
+ // Example:
+ // func f(i int) int {
+ // defer int32(i)
+ // return i
+ // }
+ InvalidDefer
+
+ // InvalidGo occurs when a go expression is not a function call, for example
+ // if the expression is a type conversion.
+ //
+ // Example:
+ // func f(i int) int {
+ // go int32(i)
+ // return i
+ // }
+ InvalidGo
+
+ // All codes below were added in Go 1.17.
+
+ /* decl */
+
+ // BadDecl occurs when a declaration has invalid syntax.
+ BadDecl
+
+ // RepeatedDecl occurs when an identifier occurs more than once on the left
+ // hand side of a short variable declaration.
+ //
+ // Example:
+ // func _() {
+ // x, y, y := 1, 2, 3
+ // }
+ RepeatedDecl
+
+ /* unsafe */
+
+ // InvalidUnsafeAdd occurs when unsafe.Add is called with a
+ // length argument that is not of integer type.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var p unsafe.Pointer
+ // var _ = unsafe.Add(p, float64(1))
+ InvalidUnsafeAdd
+
+ // InvalidUnsafeSlice occurs when unsafe.Slice is called with a
+ // pointer argument that is not of pointer type or a length argument
+ // that is not of integer type, negative, or out of bounds.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Slice(x, 1)
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Slice(&x, float64(1))
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Slice(&x, -1)
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Slice(&x, uint64(1) << 63)
+ InvalidUnsafeSlice
+
+ // All codes below were added in Go 1.18.
+
+ /* features */
+
+ // UnsupportedFeature occurs when a language feature is used that is not
+ // supported at this Go version.
+ UnsupportedFeature
+
+ /* type params */
+
+ // NotAGenericType occurs when a non-generic type is used where a generic
+ // type is expected: in type or function instantiation.
+ //
+ // Example:
+ // type T int
+ //
+ // var _ T[int]
+ NotAGenericType
+
+ // WrongTypeArgCount occurs when a type or function is instantiated with an
+ // incorrect number of type arguments, including when a generic type or
+ // function is used without instantiation.
+ //
+ // Errors involving failed type inference are assigned other error codes.
+ //
+ // Example:
+ // type T[p any] int
+ //
+ // var _ T[int, string]
+ //
+ // Example:
+ // func f[T any]() {}
+ //
+ // var x = f
+ WrongTypeArgCount
+
+ // CannotInferTypeArgs occurs when type or function type argument inference
+ // fails to infer all type arguments.
+ //
+ // Example:
+ // func f[T any]() {}
+ //
+ // func _() {
+ // f()
+ // }
+ //
+ // Example:
+ // type N[P, Q any] struct{}
+ //
+ // var _ N[int]
+ CannotInferTypeArgs
+
+ // InvalidTypeArg occurs when a type argument does not satisfy its
+ // corresponding type parameter constraints.
+ //
+ // Example:
+ // type T[P ~int] struct{}
+ //
+ // var _ T[string]
+ InvalidTypeArg // arguments? InferenceFailed
+
+ // InvalidInstanceCycle occurs when an invalid cycle is detected
+ // within the instantiation graph.
+ //
+ // Example:
+ // func f[T any]() { f[*T]() }
+ InvalidInstanceCycle
+
+ // InvalidUnion occurs when an embedded union or approximation element is
+ // not valid.
+ //
+ // Example:
+ // type _ interface {
+ // ~int | interface{ m() }
+ // }
+ InvalidUnion
+
+ // MisplacedConstraintIface occurs when a constraint-type interface is used
+ // outside of constraint position.
+ //
+ // Example:
+ // type I interface { ~int }
+ //
+ // var _ I
+ MisplacedConstraintIface
+
+ // InvalidMethodTypeParams occurs when methods have type parameters.
+ //
+ // It cannot be encountered with an AST parsed using go/parser.
+ InvalidMethodTypeParams
+
+ // MisplacedTypeParam occurs when a type parameter is used in a place where
+ // it is not permitted.
+ //
+ // Example:
+ // type T[P any] P
+ //
+ // Example:
+ // type T[P any] struct{ *P }
+ MisplacedTypeParam
+
+ // InvalidUnsafeSliceData occurs when unsafe.SliceData is called with
+ // an argument that is not of slice type. It also occurs if it is used
+ // in a package compiled for a language version before go1.20.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.SliceData(x)
+ InvalidUnsafeSliceData
+
+ // InvalidUnsafeString occurs when unsafe.String is called with
+ // a length argument that is not of integer type, negative, or
+ // out of bounds. It also occurs if it is used in a package
+ // compiled for a language version before go1.20.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var b [10]byte
+ // var _ = unsafe.String(&b[0], -1)
+ InvalidUnsafeString
+
+ // InvalidUnsafeStringData occurs if it is used in a package
+ // compiled for a language version before go1.20.
+ _ // not used anymore
+
+)
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go
new file mode 100644
index 00000000..15ecf7c5
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go
@@ -0,0 +1,179 @@
+// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT.
+
+package typesinternal
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[InvalidSyntaxTree - -1]
+ _ = x[Test-1]
+ _ = x[BlankPkgName-2]
+ _ = x[MismatchedPkgName-3]
+ _ = x[InvalidPkgUse-4]
+ _ = x[BadImportPath-5]
+ _ = x[BrokenImport-6]
+ _ = x[ImportCRenamed-7]
+ _ = x[UnusedImport-8]
+ _ = x[InvalidInitCycle-9]
+ _ = x[DuplicateDecl-10]
+ _ = x[InvalidDeclCycle-11]
+ _ = x[InvalidTypeCycle-12]
+ _ = x[InvalidConstInit-13]
+ _ = x[InvalidConstVal-14]
+ _ = x[InvalidConstType-15]
+ _ = x[UntypedNilUse-16]
+ _ = x[WrongAssignCount-17]
+ _ = x[UnassignableOperand-18]
+ _ = x[NoNewVar-19]
+ _ = x[MultiValAssignOp-20]
+ _ = x[InvalidIfaceAssign-21]
+ _ = x[InvalidChanAssign-22]
+ _ = x[IncompatibleAssign-23]
+ _ = x[UnaddressableFieldAssign-24]
+ _ = x[NotAType-25]
+ _ = x[InvalidArrayLen-26]
+ _ = x[BlankIfaceMethod-27]
+ _ = x[IncomparableMapKey-28]
+ _ = x[InvalidIfaceEmbed-29]
+ _ = x[InvalidPtrEmbed-30]
+ _ = x[BadRecv-31]
+ _ = x[InvalidRecv-32]
+ _ = x[DuplicateFieldAndMethod-33]
+ _ = x[DuplicateMethod-34]
+ _ = x[InvalidBlank-35]
+ _ = x[InvalidIota-36]
+ _ = x[MissingInitBody-37]
+ _ = x[InvalidInitSig-38]
+ _ = x[InvalidInitDecl-39]
+ _ = x[InvalidMainDecl-40]
+ _ = x[TooManyValues-41]
+ _ = x[NotAnExpr-42]
+ _ = x[TruncatedFloat-43]
+ _ = x[NumericOverflow-44]
+ _ = x[UndefinedOp-45]
+ _ = x[MismatchedTypes-46]
+ _ = x[DivByZero-47]
+ _ = x[NonNumericIncDec-48]
+ _ = x[UnaddressableOperand-49]
+ _ = x[InvalidIndirection-50]
+ _ = x[NonIndexableOperand-51]
+ _ = x[InvalidIndex-52]
+ _ = x[SwappedSliceIndices-53]
+ _ = x[NonSliceableOperand-54]
+ _ = x[InvalidSliceExpr-55]
+ _ = x[InvalidShiftCount-56]
+ _ = x[InvalidShiftOperand-57]
+ _ = x[InvalidReceive-58]
+ _ = x[InvalidSend-59]
+ _ = x[DuplicateLitKey-60]
+ _ = x[MissingLitKey-61]
+ _ = x[InvalidLitIndex-62]
+ _ = x[OversizeArrayLit-63]
+ _ = x[MixedStructLit-64]
+ _ = x[InvalidStructLit-65]
+ _ = x[MissingLitField-66]
+ _ = x[DuplicateLitField-67]
+ _ = x[UnexportedLitField-68]
+ _ = x[InvalidLitField-69]
+ _ = x[UntypedLit-70]
+ _ = x[InvalidLit-71]
+ _ = x[AmbiguousSelector-72]
+ _ = x[UndeclaredImportedName-73]
+ _ = x[UnexportedName-74]
+ _ = x[UndeclaredName-75]
+ _ = x[MissingFieldOrMethod-76]
+ _ = x[BadDotDotDotSyntax-77]
+ _ = x[NonVariadicDotDotDot-78]
+ _ = x[MisplacedDotDotDot-79]
+ _ = x[InvalidDotDotDotOperand-80]
+ _ = x[InvalidDotDotDot-81]
+ _ = x[UncalledBuiltin-82]
+ _ = x[InvalidAppend-83]
+ _ = x[InvalidCap-84]
+ _ = x[InvalidClose-85]
+ _ = x[InvalidCopy-86]
+ _ = x[InvalidComplex-87]
+ _ = x[InvalidDelete-88]
+ _ = x[InvalidImag-89]
+ _ = x[InvalidLen-90]
+ _ = x[SwappedMakeArgs-91]
+ _ = x[InvalidMake-92]
+ _ = x[InvalidReal-93]
+ _ = x[InvalidAssert-94]
+ _ = x[ImpossibleAssert-95]
+ _ = x[InvalidConversion-96]
+ _ = x[InvalidUntypedConversion-97]
+ _ = x[BadOffsetofSyntax-98]
+ _ = x[InvalidOffsetof-99]
+ _ = x[UnusedExpr-100]
+ _ = x[UnusedVar-101]
+ _ = x[MissingReturn-102]
+ _ = x[WrongResultCount-103]
+ _ = x[OutOfScopeResult-104]
+ _ = x[InvalidCond-105]
+ _ = x[InvalidPostDecl-106]
+ _ = x[InvalidChanRange-107]
+ _ = x[InvalidIterVar-108]
+ _ = x[InvalidRangeExpr-109]
+ _ = x[MisplacedBreak-110]
+ _ = x[MisplacedContinue-111]
+ _ = x[MisplacedFallthrough-112]
+ _ = x[DuplicateCase-113]
+ _ = x[DuplicateDefault-114]
+ _ = x[BadTypeKeyword-115]
+ _ = x[InvalidTypeSwitch-116]
+ _ = x[InvalidExprSwitch-117]
+ _ = x[InvalidSelectCase-118]
+ _ = x[UndeclaredLabel-119]
+ _ = x[DuplicateLabel-120]
+ _ = x[MisplacedLabel-121]
+ _ = x[UnusedLabel-122]
+ _ = x[JumpOverDecl-123]
+ _ = x[JumpIntoBlock-124]
+ _ = x[InvalidMethodExpr-125]
+ _ = x[WrongArgCount-126]
+ _ = x[InvalidCall-127]
+ _ = x[UnusedResults-128]
+ _ = x[InvalidDefer-129]
+ _ = x[InvalidGo-130]
+ _ = x[BadDecl-131]
+ _ = x[RepeatedDecl-132]
+ _ = x[InvalidUnsafeAdd-133]
+ _ = x[InvalidUnsafeSlice-134]
+ _ = x[UnsupportedFeature-135]
+ _ = x[NotAGenericType-136]
+ _ = x[WrongTypeArgCount-137]
+ _ = x[CannotInferTypeArgs-138]
+ _ = x[InvalidTypeArg-139]
+ _ = x[InvalidInstanceCycle-140]
+ _ = x[InvalidUnion-141]
+ _ = x[MisplacedConstraintIface-142]
+ _ = x[InvalidMethodTypeParams-143]
+ _ = x[MisplacedTypeParam-144]
+ _ = x[InvalidUnsafeSliceData-145]
+ _ = x[InvalidUnsafeString-146]
+}
+
+const (
+ _ErrorCode_name_0 = "InvalidSyntaxTree"
+ _ErrorCode_name_1 = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilUseWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString"
+)
+
+var (
+ _ErrorCode_index_1 = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 218, 234, 253, 261, 277, 295, 312, 330, 354, 362, 377, 393, 411, 428, 443, 450, 461, 484, 499, 511, 522, 537, 551, 566, 581, 594, 603, 617, 632, 643, 658, 667, 683, 703, 721, 740, 752, 771, 790, 806, 823, 842, 856, 867, 882, 895, 910, 926, 940, 956, 971, 988, 1006, 1021, 1031, 1041, 1058, 1080, 1094, 1108, 1128, 1146, 1166, 1184, 1207, 1223, 1238, 1251, 1261, 1273, 1284, 1298, 1311, 1322, 1332, 1347, 1358, 1369, 1382, 1398, 1415, 1439, 1456, 1471, 1481, 1490, 1503, 1519, 1535, 1546, 1561, 1577, 1591, 1607, 1621, 1638, 1658, 1671, 1687, 1701, 1718, 1735, 1752, 1767, 1781, 1795, 1806, 1818, 1831, 1848, 1861, 1872, 1885, 1897, 1906, 1913, 1925, 1941, 1959, 1977, 1992, 2009, 2028, 2042, 2062, 2074, 2098, 2121, 2139, 2161, 2180}
+)
+
+func (i ErrorCode) String() string {
+ switch {
+ case i == -1:
+ return _ErrorCode_name_0
+ case 1 <= i && i <= 146:
+ i -= 1
+ return _ErrorCode_name_1[_ErrorCode_index_1[i]:_ErrorCode_index_1[i+1]]
+ default:
+ return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/recv.go b/vendor/golang.org/x/tools/internal/typesinternal/recv.go
new file mode 100644
index 00000000..fea7c8b7
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/recv.go
@@ -0,0 +1,43 @@
+// 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 typesinternal
+
+import (
+ "go/types"
+
+ "golang.org/x/tools/internal/aliases"
+)
+
+// ReceiverNamed returns the named type (if any) associated with the
+// type of recv, which may be of the form N or *N, or aliases thereof.
+// It also reports whether a Pointer was present.
+func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) {
+ t := recv.Type()
+ if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok {
+ isPtr = true
+ t = ptr.Elem()
+ }
+ named, _ = aliases.Unalias(t).(*types.Named)
+ return
+}
+
+// Unpointer returns T given *T or an alias thereof.
+// For all other types it is the identity function.
+// It does not look at underlying types.
+// The result may be an alias.
+//
+// Use this function to strip off the optional pointer on a receiver
+// in a field or method selection, without losing the named type
+// (which is needed to compute the method set).
+//
+// See also [typeparams.MustDeref], which removes one level of
+// indirection from the type, regardless of named types (analogous to
+// a LOAD instruction).
+func Unpointer(t types.Type) types.Type {
+ if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok {
+ return ptr.Elem()
+ }
+ return t
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go
new file mode 100644
index 00000000..cc86487e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go
@@ -0,0 +1,89 @@
+// 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 typesinternal
+
+import (
+ "go/types"
+
+ "golang.org/x/tools/internal/stdlib"
+ "golang.org/x/tools/internal/versions"
+)
+
+// TooNewStdSymbols computes the set of package-level symbols
+// exported by pkg that are not available at the specified version.
+// The result maps each symbol to its minimum version.
+//
+// The pkg is allowed to contain type errors.
+func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]string {
+ disallowed := make(map[types.Object]string)
+
+ // Pass 1: package-level symbols.
+ symbols := stdlib.PackageSymbols[pkg.Path()]
+ for _, sym := range symbols {
+ symver := sym.Version.String()
+ if versions.Before(version, symver) {
+ switch sym.Kind {
+ case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type:
+ disallowed[pkg.Scope().Lookup(sym.Name)] = symver
+ }
+ }
+ }
+
+ // Pass 2: fields and methods.
+ //
+ // We allow fields and methods if their associated type is
+ // disallowed, as otherwise we would report false positives
+ // for compatibility shims. Consider:
+ //
+ // //go:build go1.22
+ // type T struct { F std.Real } // correct new API
+ //
+ // //go:build !go1.22
+ // type T struct { F fake } // shim
+ // type fake struct { ... }
+ // func (fake) M () {}
+ //
+ // These alternative declarations of T use either the std.Real
+ // type, introduced in go1.22, or a fake type, for the field
+ // F. (The fakery could be arbitrarily deep, involving more
+ // nested fields and methods than are shown here.) Clients
+ // that use the compatibility shim T will compile with any
+ // version of go, whether older or newer than go1.22, but only
+ // the newer version will use the std.Real implementation.
+ //
+ // Now consider a reference to method M in new(T).F.M() in a
+ // module that requires a minimum of go1.21. The analysis may
+ // occur using a version of Go higher than 1.21, selecting the
+ // first version of T, so the method M is Real.M. This would
+ // spuriously cause the analyzer to report a reference to a
+ // too-new symbol even though this expression compiles just
+ // fine (with the fake implementation) using go1.21.
+ for _, sym := range symbols {
+ symVersion := sym.Version.String()
+ if !versions.Before(version, symVersion) {
+ continue // allowed
+ }
+
+ var obj types.Object
+ switch sym.Kind {
+ case stdlib.Field:
+ typename, name := sym.SplitField()
+ if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == "" {
+ obj, _, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name)
+ }
+
+ case stdlib.Method:
+ ptr, recvname, name := sym.SplitMethod()
+ if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == "" {
+ obj, _, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name)
+ }
+ }
+ if obj != nil {
+ disallowed[obj] = symVersion
+ }
+ }
+
+ return disallowed
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go
new file mode 100644
index 00000000..83923286
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go
@@ -0,0 +1,65 @@
+// 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.
+
+// Package typesinternal provides access to internal go/types APIs that are not
+// yet exported.
+package typesinternal
+
+import (
+ "go/token"
+ "go/types"
+ "reflect"
+ "unsafe"
+)
+
+func SetUsesCgo(conf *types.Config) bool {
+ v := reflect.ValueOf(conf).Elem()
+
+ f := v.FieldByName("go115UsesCgo")
+ if !f.IsValid() {
+ f = v.FieldByName("UsesCgo")
+ if !f.IsValid() {
+ return false
+ }
+ }
+
+ addr := unsafe.Pointer(f.UnsafeAddr())
+ *(*bool)(addr) = true
+
+ return true
+}
+
+// ReadGo116ErrorData extracts additional information from types.Error values
+// generated by Go version 1.16 and later: the error code, start position, and
+// end position. If all positions are valid, start <= err.Pos <= end.
+//
+// If the data could not be read, the final result parameter will be false.
+func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) {
+ var data [3]int
+ // By coincidence all of these fields are ints, which simplifies things.
+ v := reflect.ValueOf(err)
+ for i, name := range []string{"go116code", "go116start", "go116end"} {
+ f := v.FieldByName(name)
+ if !f.IsValid() {
+ return 0, 0, 0, false
+ }
+ data[i] = int(f.Int())
+ }
+ return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true
+}
+
+// NameRelativeTo returns a types.Qualifier that qualifies members of
+// all packages other than pkg, using only the package name.
+// (By contrast, [types.RelativeTo] uses the complete package path,
+// which is often excessive.)
+//
+// If pkg is nil, it is equivalent to [*types.Package.Name].
+func NameRelativeTo(pkg *types.Package) types.Qualifier {
+ return func(other *types.Package) string {
+ if pkg != nil && pkg == other {
+ return "" // same package; unqualified
+ }
+ return other.Name()
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/features.go b/vendor/golang.org/x/tools/internal/versions/features.go
new file mode 100644
index 00000000..b53f1786
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/features.go
@@ -0,0 +1,43 @@
+// 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 versions
+
+// This file contains predicates for working with file versions to
+// decide when a tool should consider a language feature enabled.
+
+// GoVersions that features in x/tools can be gated to.
+const (
+ Go1_18 = "go1.18"
+ Go1_19 = "go1.19"
+ Go1_20 = "go1.20"
+ Go1_21 = "go1.21"
+ Go1_22 = "go1.22"
+)
+
+// Future is an invalid unknown Go version sometime in the future.
+// Do not use directly with Compare.
+const Future = ""
+
+// AtLeast reports whether the file version v comes after a Go release.
+//
+// Use this predicate to enable a behavior once a certain Go release
+// has happened (and stays enabled in the future).
+func AtLeast(v, release string) bool {
+ if v == Future {
+ return true // an unknown future version is always after y.
+ }
+ return Compare(Lang(v), Lang(release)) >= 0
+}
+
+// Before reports whether the file version v is strictly before a Go release.
+//
+// Use this predicate to disable a behavior once a certain Go release
+// has happened (and stays enabled in the future).
+func Before(v, release string) bool {
+ if v == Future {
+ return false // an unknown future version happens after y.
+ }
+ return Compare(Lang(v), Lang(release)) < 0
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/gover.go b/vendor/golang.org/x/tools/internal/versions/gover.go
new file mode 100644
index 00000000..bbabcd22
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/gover.go
@@ -0,0 +1,172 @@
+// 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.
+
+// This is a fork of internal/gover for use by x/tools until
+// go1.21 and earlier are no longer supported by x/tools.
+
+package versions
+
+import "strings"
+
+// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]]
+// The numbers are the original decimal strings to avoid integer overflows
+// and since there is very little actual math. (Probably overflow doesn't matter in practice,
+// but at the time this code was written, there was an existing test that used
+// go1.99999999999, which does not fit in an int on 32-bit platforms.
+// The "big decimal" representation avoids the problem entirely.)
+type gover struct {
+ major string // decimal
+ minor string // decimal or ""
+ patch string // decimal or ""
+ kind string // "", "alpha", "beta", "rc"
+ pre string // decimal or ""
+}
+
+// compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as toolchain versions.
+// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21".
+// Malformed versions compare less than well-formed versions and equal to each other.
+// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0".
+func compare(x, y string) int {
+ vx := parse(x)
+ vy := parse(y)
+
+ if c := cmpInt(vx.major, vy.major); c != 0 {
+ return c
+ }
+ if c := cmpInt(vx.minor, vy.minor); c != 0 {
+ return c
+ }
+ if c := cmpInt(vx.patch, vy.patch); c != 0 {
+ return c
+ }
+ if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc
+ return c
+ }
+ if c := cmpInt(vx.pre, vy.pre); c != 0 {
+ return c
+ }
+ return 0
+}
+
+// lang returns the Go language version. For example, lang("1.2.3") == "1.2".
+func lang(x string) string {
+ v := parse(x)
+ if v.minor == "" || v.major == "1" && v.minor == "0" {
+ return v.major
+ }
+ return v.major + "." + v.minor
+}
+
+// isValid reports whether the version x is valid.
+func isValid(x string) bool {
+ return parse(x) != gover{}
+}
+
+// parse parses the Go version string x into a version.
+// It returns the zero version if x is malformed.
+func parse(x string) gover {
+ var v gover
+
+ // Parse major version.
+ var ok bool
+ v.major, x, ok = cutInt(x)
+ if !ok {
+ return gover{}
+ }
+ if x == "" {
+ // Interpret "1" as "1.0.0".
+ v.minor = "0"
+ v.patch = "0"
+ return v
+ }
+
+ // Parse . before minor version.
+ if x[0] != '.' {
+ return gover{}
+ }
+
+ // Parse minor version.
+ v.minor, x, ok = cutInt(x[1:])
+ if !ok {
+ return gover{}
+ }
+ if x == "" {
+ // Patch missing is same as "0" for older versions.
+ // Starting in Go 1.21, patch missing is different from explicit .0.
+ if cmpInt(v.minor, "21") < 0 {
+ v.patch = "0"
+ }
+ return v
+ }
+
+ // Parse patch if present.
+ if x[0] == '.' {
+ v.patch, x, ok = cutInt(x[1:])
+ if !ok || x != "" {
+ // Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != "").
+ // Allowing them would be a bit confusing because we already have:
+ // 1.21 < 1.21rc1
+ // But a prerelease of a patch would have the opposite effect:
+ // 1.21.3rc1 < 1.21.3
+ // We've never needed them before, so let's not start now.
+ return gover{}
+ }
+ return v
+ }
+
+ // Parse prerelease.
+ i := 0
+ for i < len(x) && (x[i] < '0' || '9' < x[i]) {
+ if x[i] < 'a' || 'z' < x[i] {
+ return gover{}
+ }
+ i++
+ }
+ if i == 0 {
+ return gover{}
+ }
+ v.kind, x = x[:i], x[i:]
+ if x == "" {
+ return v
+ }
+ v.pre, x, ok = cutInt(x)
+ if !ok || x != "" {
+ return gover{}
+ }
+
+ return v
+}
+
+// cutInt scans the leading decimal number at the start of x to an integer
+// and returns that value and the rest of the string.
+func cutInt(x string) (n, rest string, ok bool) {
+ i := 0
+ for i < len(x) && '0' <= x[i] && x[i] <= '9' {
+ i++
+ }
+ if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero
+ return "", "", false
+ }
+ return x[:i], x[i:], true
+}
+
+// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers.
+// (Copied from golang.org/x/mod/semver's compareInt.)
+func cmpInt(x, y string) int {
+ if x == y {
+ return 0
+ }
+ if len(x) < len(y) {
+ return -1
+ }
+ if len(x) > len(y) {
+ return +1
+ }
+ if x < y {
+ return -1
+ } else {
+ return +1
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain.go b/vendor/golang.org/x/tools/internal/versions/toolchain.go
new file mode 100644
index 00000000..377bf7a5
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/toolchain.go
@@ -0,0 +1,14 @@
+// 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 versions
+
+// toolchain is maximum version (<1.22) that the go toolchain used
+// to build the current tool is known to support.
+//
+// When a tool is built with >=1.22, the value of toolchain is unused.
+//
+// x/tools does not support building with go <1.18. So we take this
+// as the minimum possible maximum.
+var toolchain string = Go1_18
diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go b/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go
new file mode 100644
index 00000000..f65beed9
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go
@@ -0,0 +1,14 @@
+// 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 go1.19
+// +build go1.19
+
+package versions
+
+func init() {
+ if Compare(toolchain, Go1_19) < 0 {
+ toolchain = Go1_19
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go b/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go
new file mode 100644
index 00000000..1a9efa12
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go
@@ -0,0 +1,14 @@
+// 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 go1.20
+// +build go1.20
+
+package versions
+
+func init() {
+ if Compare(toolchain, Go1_20) < 0 {
+ toolchain = Go1_20
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go b/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go
new file mode 100644
index 00000000..b7ef216d
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go
@@ -0,0 +1,14 @@
+// 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 go1.21
+// +build go1.21
+
+package versions
+
+func init() {
+ if Compare(toolchain, Go1_21) < 0 {
+ toolchain = Go1_21
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/types.go b/vendor/golang.org/x/tools/internal/versions/types.go
new file mode 100644
index 00000000..562eef21
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types.go
@@ -0,0 +1,19 @@
+// 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 versions
+
+import (
+ "go/types"
+)
+
+// GoVersion returns the Go version of the type package.
+// It returns zero if no version can be determined.
+func GoVersion(pkg *types.Package) string {
+ // TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25.
+ if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok {
+ return pkg.GoVersion()
+ }
+ return ""
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/types_go121.go b/vendor/golang.org/x/tools/internal/versions/types_go121.go
new file mode 100644
index 00000000..b4345d33
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types_go121.go
@@ -0,0 +1,30 @@
+// 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 !go1.22
+// +build !go1.22
+
+package versions
+
+import (
+ "go/ast"
+ "go/types"
+)
+
+// FileVersion returns a language version (<=1.21) derived from runtime.Version()
+// or an unknown future version.
+func FileVersion(info *types.Info, file *ast.File) string {
+ // In x/tools built with Go <= 1.21, we do not have Info.FileVersions
+ // available. We use a go version derived from the toolchain used to
+ // compile the tool by default.
+ // This will be <= go1.21. We take this as the maximum version that
+ // this tool can support.
+ //
+ // There are no features currently in x/tools that need to tell fine grained
+ // differences for versions <1.22.
+ return toolchain
+}
+
+// InitFileVersions is a noop when compiled with this Go version.
+func InitFileVersions(*types.Info) {}
diff --git a/vendor/golang.org/x/tools/internal/versions/types_go122.go b/vendor/golang.org/x/tools/internal/versions/types_go122.go
new file mode 100644
index 00000000..aac5db62
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types_go122.go
@@ -0,0 +1,41 @@
+// 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 go1.22
+// +build go1.22
+
+package versions
+
+import (
+ "go/ast"
+ "go/types"
+)
+
+// FileVersion returns a file's Go version.
+// The reported version is an unknown Future version if a
+// version cannot be determined.
+func FileVersion(info *types.Info, file *ast.File) string {
+ // In tools built with Go >= 1.22, the Go version of a file
+ // follow a cascades of sources:
+ // 1) types.Info.FileVersion, which follows the cascade:
+ // 1.a) file version (ast.File.GoVersion),
+ // 1.b) the package version (types.Config.GoVersion), or
+ // 2) is some unknown Future version.
+ //
+ // File versions require a valid package version to be provided to types
+ // in Config.GoVersion. Config.GoVersion is either from the package's module
+ // or the toolchain (go run). This value should be provided by go/packages
+ // or unitchecker.Config.GoVersion.
+ if v := info.FileVersions[file]; IsValid(v) {
+ return v
+ }
+ // Note: we could instead return runtime.Version() [if valid].
+ // This would act as a max version on what a tool can support.
+ return Future
+}
+
+// InitFileVersions initializes info to record Go versions for Go files.
+func InitFileVersions(info *types.Info) {
+ info.FileVersions = make(map[*ast.File]string)
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/versions.go b/vendor/golang.org/x/tools/internal/versions/versions.go
new file mode 100644
index 00000000..8d1f7453
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/versions.go
@@ -0,0 +1,57 @@
+// 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 versions
+
+import (
+ "strings"
+)
+
+// Note: If we use build tags to use go/versions when go >=1.22,
+// we run into go.dev/issue/53737. Under some operations users would see an
+// import of "go/versions" even if they would not compile the file.
+// For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include
+// For this reason, this library just a clone of go/versions for the moment.
+
+// Lang returns the Go language version for version x.
+// If x is not a valid version, Lang returns the empty string.
+// For example:
+//
+// Lang("go1.21rc2") = "go1.21"
+// Lang("go1.21.2") = "go1.21"
+// Lang("go1.21") = "go1.21"
+// Lang("go1") = "go1"
+// Lang("bad") = ""
+// Lang("1.21") = ""
+func Lang(x string) string {
+ v := lang(stripGo(x))
+ if v == "" {
+ return ""
+ }
+ return x[:2+len(v)] // "go"+v without allocation
+}
+
+// Compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as Go versions.
+// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
+// Invalid versions, including the empty string, compare less than
+// valid versions and equal to each other.
+// The language version "go1.21" compares less than the
+// release candidate and eventual releases "go1.21rc1" and "go1.21.0".
+// Custom toolchain suffixes are ignored during comparison:
+// "go1.21.0" and "go1.21.0-bigcorp" are equal.
+func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) }
+
+// IsValid reports whether the version x is valid.
+func IsValid(x string) bool { return isValid(stripGo(x)) }
+
+// stripGo converts from a "go1.21" version to a "1.21" version.
+// If v does not start with "go", stripGo returns the empty string (a known invalid version).
+func stripGo(v string) string {
+ v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix.
+ if len(v) < 2 || v[:2] != "go" {
+ return ""
+ }
+ return v[2:]
+}
diff --git a/vendor/gopkg.in/warnings.v0/LICENSE b/vendor/gopkg.in/warnings.v0/LICENSE
new file mode 100644
index 00000000..d65f7e9d
--- /dev/null
+++ b/vendor/gopkg.in/warnings.v0/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2016 Péter Surányi.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/gopkg.in/warnings.v0/README b/vendor/gopkg.in/warnings.v0/README
new file mode 100644
index 00000000..974212ba
--- /dev/null
+++ b/vendor/gopkg.in/warnings.v0/README
@@ -0,0 +1,77 @@
+Package warnings implements error handling with non-fatal errors (warnings).
+
+import path: "gopkg.in/warnings.v0"
+package docs: https://godoc.org/gopkg.in/warnings.v0
+issues: https://github.com/go-warnings/warnings/issues
+pull requests: https://github.com/go-warnings/warnings/pulls
+
+A recurring pattern in Go programming is the following:
+
+ func myfunc(params) error {
+ if err := doSomething(...); err != nil {
+ return err
+ }
+ if err := doSomethingElse(...); err != nil {
+ return err
+ }
+ if ok := doAnotherThing(...); !ok {
+ return errors.New("my error")
+ }
+ ...
+ return nil
+ }
+
+This pattern allows interrupting the flow on any received error. But what if
+there are errors that should be noted but still not fatal, for which the flow
+should not be interrupted? Implementing such logic at each if statement would
+make the code complex and the flow much harder to follow.
+
+Package warnings provides the Collector type and a clean and simple pattern
+for achieving such logic. The Collector takes care of deciding when to break
+the flow and when to continue, collecting any non-fatal errors (warnings)
+along the way. The only requirement is that fatal and non-fatal errors can be
+distinguished programmatically; that is a function such as
+
+ IsFatal(error) bool
+
+must be implemented. The following is an example of what the above snippet
+could look like using the warnings package:
+
+ import "gopkg.in/warnings.v0"
+
+ func isFatal(err error) bool {
+ _, ok := err.(WarningType)
+ return !ok
+ }
+
+ func myfunc(params) error {
+ c := warnings.NewCollector(isFatal)
+ c.FatalWithWarnings = true
+ if err := c.Collect(doSomething()); err != nil {
+ return err
+ }
+ if err := c.Collect(doSomethingElse(...)); err != nil {
+ return err
+ }
+ if ok := doAnotherThing(...); !ok {
+ if err := c.Collect(errors.New("my error")); err != nil {
+ return err
+ }
+ }
+ ...
+ return c.Done()
+ }
+
+For an example of a non-trivial code base using this library, see
+gopkg.in/gcfg.v1
+
+Rules for using warnings
+
+ - ensure that warnings are programmatically distinguishable from fatal
+ errors (i.e. implement an isFatal function and any necessary error types)
+ - ensure that there is a single Collector instance for a call of each
+ exported function
+ - ensure that all errors (fatal or warning) are fed through Collect
+ - ensure that every time an error is returned, it is one returned by a
+ Collector (from Collect or Done)
+ - ensure that Collect is never called after Done
diff --git a/vendor/gopkg.in/warnings.v0/warnings.go b/vendor/gopkg.in/warnings.v0/warnings.go
new file mode 100644
index 00000000..b849d1e3
--- /dev/null
+++ b/vendor/gopkg.in/warnings.v0/warnings.go
@@ -0,0 +1,194 @@
+// Package warnings implements error handling with non-fatal errors (warnings).
+//
+// A recurring pattern in Go programming is the following:
+//
+// func myfunc(params) error {
+// if err := doSomething(...); err != nil {
+// return err
+// }
+// if err := doSomethingElse(...); err != nil {
+// return err
+// }
+// if ok := doAnotherThing(...); !ok {
+// return errors.New("my error")
+// }
+// ...
+// return nil
+// }
+//
+// This pattern allows interrupting the flow on any received error. But what if
+// there are errors that should be noted but still not fatal, for which the flow
+// should not be interrupted? Implementing such logic at each if statement would
+// make the code complex and the flow much harder to follow.
+//
+// Package warnings provides the Collector type and a clean and simple pattern
+// for achieving such logic. The Collector takes care of deciding when to break
+// the flow and when to continue, collecting any non-fatal errors (warnings)
+// along the way. The only requirement is that fatal and non-fatal errors can be
+// distinguished programmatically; that is a function such as
+//
+// IsFatal(error) bool
+//
+// must be implemented. The following is an example of what the above snippet
+// could look like using the warnings package:
+//
+// import "gopkg.in/warnings.v0"
+//
+// func isFatal(err error) bool {
+// _, ok := err.(WarningType)
+// return !ok
+// }
+//
+// func myfunc(params) error {
+// c := warnings.NewCollector(isFatal)
+// c.FatalWithWarnings = true
+// if err := c.Collect(doSomething()); err != nil {
+// return err
+// }
+// if err := c.Collect(doSomethingElse(...)); err != nil {
+// return err
+// }
+// if ok := doAnotherThing(...); !ok {
+// if err := c.Collect(errors.New("my error")); err != nil {
+// return err
+// }
+// }
+// ...
+// return c.Done()
+// }
+//
+// For an example of a non-trivial code base using this library, see
+// gopkg.in/gcfg.v1
+//
+// Rules for using warnings
+//
+// - ensure that warnings are programmatically distinguishable from fatal
+// errors (i.e. implement an isFatal function and any necessary error types)
+// - ensure that there is a single Collector instance for a call of each
+// exported function
+// - ensure that all errors (fatal or warning) are fed through Collect
+// - ensure that every time an error is returned, it is one returned by a
+// Collector (from Collect or Done)
+// - ensure that Collect is never called after Done
+//
+// TODO
+//
+// - optionally limit the number of warnings (e.g. stop after 20 warnings) (?)
+// - consider interaction with contexts
+// - go vet-style invocations verifier
+// - semi-automatic code converter
+//
+package warnings // import "gopkg.in/warnings.v0"
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// List holds a collection of warnings and optionally one fatal error.
+type List struct {
+ Warnings []error
+ Fatal error
+}
+
+// Error implements the error interface.
+func (l List) Error() string {
+ b := bytes.NewBuffer(nil)
+ if l.Fatal != nil {
+ fmt.Fprintln(b, "fatal:")
+ fmt.Fprintln(b, l.Fatal)
+ }
+ switch len(l.Warnings) {
+ case 0:
+ // nop
+ case 1:
+ fmt.Fprintln(b, "warning:")
+ default:
+ fmt.Fprintln(b, "warnings:")
+ }
+ for _, err := range l.Warnings {
+ fmt.Fprintln(b, err)
+ }
+ return b.String()
+}
+
+// A Collector collects errors up to the first fatal error.
+type Collector struct {
+ // IsFatal distinguishes between warnings and fatal errors.
+ IsFatal func(error) bool
+ // FatalWithWarnings set to true means that a fatal error is returned as
+ // a List together with all warnings so far. The default behavior is to
+ // only return the fatal error and discard any warnings that have been
+ // collected.
+ FatalWithWarnings bool
+
+ l List
+ done bool
+}
+
+// NewCollector returns a new Collector; it uses isFatal to distinguish between
+// warnings and fatal errors.
+func NewCollector(isFatal func(error) bool) *Collector {
+ return &Collector{IsFatal: isFatal}
+}
+
+// Collect collects a single error (warning or fatal). It returns nil if
+// collection can continue (only warnings so far), or otherwise the errors
+// collected. Collect mustn't be called after the first fatal error or after
+// Done has been called.
+func (c *Collector) Collect(err error) error {
+ if c.done {
+ panic("warnings.Collector already done")
+ }
+ if err == nil {
+ return nil
+ }
+ if c.IsFatal(err) {
+ c.done = true
+ c.l.Fatal = err
+ } else {
+ c.l.Warnings = append(c.l.Warnings, err)
+ }
+ if c.l.Fatal != nil {
+ return c.erorr()
+ }
+ return nil
+}
+
+// Done ends collection and returns the collected error(s).
+func (c *Collector) Done() error {
+ c.done = true
+ return c.erorr()
+}
+
+func (c *Collector) erorr() error {
+ if !c.FatalWithWarnings && c.l.Fatal != nil {
+ return c.l.Fatal
+ }
+ if c.l.Fatal == nil && len(c.l.Warnings) == 0 {
+ return nil
+ }
+ // Note that a single warning is also returned as a List. This is to make it
+ // easier to determine fatal-ness of the returned error.
+ return c.l
+}
+
+// FatalOnly returns the fatal error, if any, **in an error returned by a
+// Collector**. It returns nil if and only if err is nil or err is a List
+// with err.Fatal == nil.
+func FatalOnly(err error) error {
+ l, ok := err.(List)
+ if !ok {
+ return err
+ }
+ return l.Fatal
+}
+
+// WarningsOnly returns the warnings **in an error returned by a Collector**.
+func WarningsOnly(err error) []error {
+ l, ok := err.(List)
+ if !ok {
+ return nil
+ }
+ return l.Warnings
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 327eccd2..fca40ffc 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,3 +1,6 @@
+# dario.cat/mergo v1.0.0
+## explicit; go 1.13
+dario.cat/mergo
# github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24
## explicit; go 1.20
github.com/AdaLogics/go-fuzz-headers
@@ -24,13 +27,39 @@ github.com/Masterminds/sprig/v3
# github.com/Masterminds/squirrel v1.5.4
## explicit; go 1.14
github.com/Masterminds/squirrel
+# github.com/Microsoft/go-winio v0.6.1
+## explicit; go 1.17
+github.com/Microsoft/go-winio
+github.com/Microsoft/go-winio/internal/fs
+github.com/Microsoft/go-winio/internal/socket
+github.com/Microsoft/go-winio/internal/stringbuffer
+github.com/Microsoft/go-winio/pkg/guid
# github.com/Microsoft/hcsshim v0.11.4
## explicit; go 1.18
github.com/Microsoft/hcsshim/osversion
# github.com/NVIDIA/k8s-test-infra v0.0.0-20240806103558-2d7411125519
## explicit; go 1.22.3
github.com/NVIDIA/k8s-test-infra/pkg/diagnostics
-github.com/NVIDIA/k8s-test-infra/pkg/framework
+# github.com/ProtonMail/go-crypto v1.0.0
+## explicit; go 1.13
+github.com/ProtonMail/go-crypto/bitcurves
+github.com/ProtonMail/go-crypto/brainpool
+github.com/ProtonMail/go-crypto/eax
+github.com/ProtonMail/go-crypto/internal/byteutil
+github.com/ProtonMail/go-crypto/ocb
+github.com/ProtonMail/go-crypto/openpgp
+github.com/ProtonMail/go-crypto/openpgp/aes/keywrap
+github.com/ProtonMail/go-crypto/openpgp/armor
+github.com/ProtonMail/go-crypto/openpgp/ecdh
+github.com/ProtonMail/go-crypto/openpgp/ecdsa
+github.com/ProtonMail/go-crypto/openpgp/eddsa
+github.com/ProtonMail/go-crypto/openpgp/elgamal
+github.com/ProtonMail/go-crypto/openpgp/errors
+github.com/ProtonMail/go-crypto/openpgp/internal/algorithm
+github.com/ProtonMail/go-crypto/openpgp/internal/ecc
+github.com/ProtonMail/go-crypto/openpgp/internal/encoding
+github.com/ProtonMail/go-crypto/openpgp/packet
+github.com/ProtonMail/go-crypto/openpgp/s2k
# github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
## explicit; go 1.13
github.com/asaskevich/govalidator
@@ -46,6 +75,20 @@ github.com/chai2010/gettext-go
github.com/chai2010/gettext-go/mo
github.com/chai2010/gettext-go/plural
github.com/chai2010/gettext-go/po
+# github.com/cloudflare/circl v1.3.7
+## explicit; go 1.19
+github.com/cloudflare/circl/dh/x25519
+github.com/cloudflare/circl/dh/x448
+github.com/cloudflare/circl/ecc/goldilocks
+github.com/cloudflare/circl/internal/conv
+github.com/cloudflare/circl/internal/sha3
+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/sign
+github.com/cloudflare/circl/sign/ed25519
+github.com/cloudflare/circl/sign/ed448
# github.com/containerd/containerd v1.7.12
## explicit; go 1.19
github.com/containerd/containerd/archive/compression
@@ -120,6 +163,14 @@ github.com/docker/go-metrics
## explicit; go 1.13
github.com/emicklei/go-restful/v3
github.com/emicklei/go-restful/v3/log
+# github.com/emirpasic/gods v1.18.1
+## explicit; go 1.2
+github.com/emirpasic/gods/containers
+github.com/emirpasic/gods/lists
+github.com/emirpasic/gods/lists/arraylist
+github.com/emirpasic/gods/trees
+github.com/emirpasic/gods/trees/binaryheap
+github.com/emirpasic/gods/utils
# github.com/evanphx/json-patch v5.7.0+incompatible
## explicit
github.com/evanphx/json-patch
@@ -142,6 +193,68 @@ github.com/fsnotify/fsnotify
# github.com/go-errors/errors v1.5.1
## explicit; go 1.14
github.com/go-errors/errors
+# github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376
+## explicit; go 1.13
+github.com/go-git/gcfg
+github.com/go-git/gcfg/scanner
+github.com/go-git/gcfg/token
+github.com/go-git/gcfg/types
+# github.com/go-git/go-billy/v5 v5.5.0
+## explicit; go 1.19
+github.com/go-git/go-billy/v5
+github.com/go-git/go-billy/v5/helper/chroot
+github.com/go-git/go-billy/v5/helper/polyfill
+github.com/go-git/go-billy/v5/memfs
+github.com/go-git/go-billy/v5/osfs
+github.com/go-git/go-billy/v5/util
+# github.com/go-git/go-git/v5 v5.12.0
+## explicit; go 1.19
+github.com/go-git/go-git/v5
+github.com/go-git/go-git/v5/config
+github.com/go-git/go-git/v5/internal/path_util
+github.com/go-git/go-git/v5/internal/revision
+github.com/go-git/go-git/v5/internal/url
+github.com/go-git/go-git/v5/plumbing
+github.com/go-git/go-git/v5/plumbing/cache
+github.com/go-git/go-git/v5/plumbing/color
+github.com/go-git/go-git/v5/plumbing/filemode
+github.com/go-git/go-git/v5/plumbing/format/config
+github.com/go-git/go-git/v5/plumbing/format/diff
+github.com/go-git/go-git/v5/plumbing/format/gitignore
+github.com/go-git/go-git/v5/plumbing/format/idxfile
+github.com/go-git/go-git/v5/plumbing/format/index
+github.com/go-git/go-git/v5/plumbing/format/objfile
+github.com/go-git/go-git/v5/plumbing/format/packfile
+github.com/go-git/go-git/v5/plumbing/format/pktline
+github.com/go-git/go-git/v5/plumbing/hash
+github.com/go-git/go-git/v5/plumbing/object
+github.com/go-git/go-git/v5/plumbing/protocol/packp
+github.com/go-git/go-git/v5/plumbing/protocol/packp/capability
+github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband
+github.com/go-git/go-git/v5/plumbing/revlist
+github.com/go-git/go-git/v5/plumbing/storer
+github.com/go-git/go-git/v5/plumbing/transport
+github.com/go-git/go-git/v5/plumbing/transport/client
+github.com/go-git/go-git/v5/plumbing/transport/file
+github.com/go-git/go-git/v5/plumbing/transport/git
+github.com/go-git/go-git/v5/plumbing/transport/http
+github.com/go-git/go-git/v5/plumbing/transport/internal/common
+github.com/go-git/go-git/v5/plumbing/transport/server
+github.com/go-git/go-git/v5/plumbing/transport/ssh
+github.com/go-git/go-git/v5/storage
+github.com/go-git/go-git/v5/storage/filesystem
+github.com/go-git/go-git/v5/storage/filesystem/dotgit
+github.com/go-git/go-git/v5/storage/memory
+github.com/go-git/go-git/v5/utils/binary
+github.com/go-git/go-git/v5/utils/diff
+github.com/go-git/go-git/v5/utils/ioutil
+github.com/go-git/go-git/v5/utils/merkletrie
+github.com/go-git/go-git/v5/utils/merkletrie/filesystem
+github.com/go-git/go-git/v5/utils/merkletrie/index
+github.com/go-git/go-git/v5/utils/merkletrie/internal/frame
+github.com/go-git/go-git/v5/utils/merkletrie/noder
+github.com/go-git/go-git/v5/utils/sync
+github.com/go-git/go-git/v5/utils/trace
# github.com/go-gorp/gorp/v3 v3.1.0
## explicit; go 1.18
github.com/go-gorp/gorp/v3
@@ -252,6 +365,9 @@ github.com/imdario/mergo
# github.com/inconshreveable/mousetrap v1.1.0
## explicit; go 1.18
github.com/inconshreveable/mousetrap
+# github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
+## explicit
+github.com/jbenet/go-context/io
# github.com/jmoiron/sqlx v1.3.5
## explicit; go 1.10
github.com/jmoiron/sqlx
@@ -262,6 +378,9 @@ github.com/josharian/intern
# github.com/json-iterator/go v1.1.12
## explicit; go 1.12
github.com/json-iterator/go
+# github.com/kevinburke/ssh_config v1.2.0
+## explicit
+github.com/kevinburke/ssh_config
# github.com/klauspost/compress v1.17.4
## explicit; go 1.19
github.com/klauspost/compress
@@ -388,6 +507,11 @@ github.com/openshift/api/security/v1
# github.com/peterbourgon/diskv v2.0.1+incompatible
## explicit
github.com/peterbourgon/diskv
+# github.com/pjbgf/sha1cd v0.3.0
+## explicit; go 1.19
+github.com/pjbgf/sha1cd
+github.com/pjbgf/sha1cd/internal
+github.com/pjbgf/sha1cd/ubc
# github.com/pkg/errors v0.9.1
## explicit
github.com/pkg/errors
@@ -427,12 +551,18 @@ github.com/rubenv/sql-migrate/sqlparse
# github.com/russross/blackfriday/v2 v2.1.0
## explicit
github.com/russross/blackfriday/v2
+# github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
+## explicit; go 1.13
+github.com/sergi/go-diff/diffmatchpatch
# github.com/shopspring/decimal v1.3.1
## explicit; go 1.13
github.com/shopspring/decimal
# github.com/sirupsen/logrus v1.9.3
## explicit; go 1.13
github.com/sirupsen/logrus
+# github.com/skeema/knownhosts v1.2.2
+## explicit; go 1.17
+github.com/skeema/knownhosts
# github.com/spf13/cast v1.6.0
## explicit; go 1.19
github.com/spf13/cast
@@ -445,6 +575,9 @@ github.com/spf13/pflag
# github.com/stretchr/testify v1.9.0
## explicit; go 1.17
github.com/stretchr/testify/assert
+# github.com/xanzy/ssh-agent v0.3.3
+## explicit; go 1.16
+github.com/xanzy/ssh-agent
# github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb
## explicit
github.com/xeipuuv/gojsonpointer
@@ -506,9 +639,16 @@ go.uber.org/zap/internal/stacktrace
go.uber.org/zap/zapcore
# golang.org/x/crypto v0.25.0
## explicit; go 1.20
+golang.org/x/crypto/argon2
golang.org/x/crypto/bcrypt
+golang.org/x/crypto/blake2b
golang.org/x/crypto/blowfish
golang.org/x/crypto/cast5
+golang.org/x/crypto/chacha20
+golang.org/x/crypto/curve25519
+golang.org/x/crypto/hkdf
+golang.org/x/crypto/internal/alias
+golang.org/x/crypto/internal/poly1305
golang.org/x/crypto/openpgp
golang.org/x/crypto/openpgp/armor
golang.org/x/crypto/openpgp/clearsign
@@ -518,11 +658,19 @@ golang.org/x/crypto/openpgp/packet
golang.org/x/crypto/openpgp/s2k
golang.org/x/crypto/pbkdf2
golang.org/x/crypto/scrypt
+golang.org/x/crypto/sha3
+golang.org/x/crypto/ssh
+golang.org/x/crypto/ssh/agent
+golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
+golang.org/x/crypto/ssh/knownhosts
# golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
## explicit; go 1.20
golang.org/x/exp/constraints
golang.org/x/exp/maps
golang.org/x/exp/slices
+# golang.org/x/mod v0.19.0
+## explicit; go 1.18
+golang.org/x/mod/semver
# golang.org/x/net v0.27.0
## explicit; go 1.18
golang.org/x/net/context
@@ -546,6 +694,8 @@ golang.org/x/sync/errgroup
golang.org/x/sync/semaphore
# golang.org/x/sys v0.22.0
## explicit; go 1.18
+golang.org/x/sys/cpu
+golang.org/x/sys/execabs
golang.org/x/sys/plan9
golang.org/x/sys/unix
golang.org/x/sys/windows
@@ -579,8 +729,25 @@ golang.org/x/text/unicode/norm
golang.org/x/time/rate
# golang.org/x/tools v0.23.0
## explicit; go 1.19
+golang.org/x/tools/cmd/stringer
golang.org/x/tools/cover
golang.org/x/tools/go/ast/inspector
+golang.org/x/tools/go/gcexportdata
+golang.org/x/tools/go/packages
+golang.org/x/tools/go/types/objectpath
+golang.org/x/tools/internal/aliases
+golang.org/x/tools/internal/event
+golang.org/x/tools/internal/event/core
+golang.org/x/tools/internal/event/keys
+golang.org/x/tools/internal/event/label
+golang.org/x/tools/internal/gcimporter
+golang.org/x/tools/internal/gocommand
+golang.org/x/tools/internal/packagesinternal
+golang.org/x/tools/internal/pkgbits
+golang.org/x/tools/internal/stdlib
+golang.org/x/tools/internal/tokeninternal
+golang.org/x/tools/internal/typesinternal
+golang.org/x/tools/internal/versions
# gomodules.xyz/jsonpatch/v2 v2.4.0
## explicit; go 1.20
gomodules.xyz/jsonpatch/v2
@@ -651,6 +818,9 @@ gopkg.in/evanphx/json-patch.v5
# gopkg.in/inf.v0 v0.9.1
## explicit
gopkg.in/inf.v0
+# gopkg.in/warnings.v0 v0.1.2
+## explicit
+gopkg.in/warnings.v0
# gopkg.in/yaml.v2 v2.4.0
## explicit; go 1.15
gopkg.in/yaml.v2