mirror of
https://github.com/vbatts/go-mtree.git
synced 2024-11-26 01:55:39 +00:00
Merge pull request #142 from tklauser/utimes-unix
Use UtimesNanoAt from golang.org/x/sys/unix
This commit is contained in:
commit
a30ab86d71
402 changed files with 23580 additions and 37736 deletions
11
glide.lock
generated
11
glide.lock
generated
|
@ -1,14 +1,15 @@
|
||||||
hash: c4cfd3ace8e3926093aacecfa0f22fbeb5b2a7cb53e0b12a48b5108f6c83d9b8
|
hash: 72477bc1ec8c50d432740cbf3940cae19387d596c02f1046c7e989458462e536
|
||||||
updated: 2017-06-24T14:24:17.116476656-04:00
|
updated: 2017-10-20T11:31:42.730083725+02:00
|
||||||
imports:
|
imports:
|
||||||
- name: github.com/Sirupsen/logrus
|
- name: github.com/Sirupsen/logrus
|
||||||
version: 202f25545ea4cf9b191ff7f846df5d87c9382c2b
|
version: f006c2ac4710855cf0f916dd6b77acf6b048dc6e
|
||||||
- name: golang.org/x/crypto
|
- name: golang.org/x/crypto
|
||||||
version: adbae1b6b6fb4b02448a0fc0dbbc9ba2b95b294d
|
version: 1351f936d976c60a0a48d728281922cf63eafb8d
|
||||||
subpackages:
|
subpackages:
|
||||||
- ripemd160
|
- ripemd160
|
||||||
|
- ssh/terminal
|
||||||
- name: golang.org/x/sys
|
- name: golang.org/x/sys
|
||||||
version: c23410a886927bab8ca5e80b08af6a56faeb330d
|
version: 8dbc5d05d6edcc104950cc299a1ce6641235bc86
|
||||||
subpackages:
|
subpackages:
|
||||||
- unix
|
- unix
|
||||||
testImports: []
|
testImports: []
|
||||||
|
|
|
@ -8,3 +8,7 @@ import:
|
||||||
- ripemd160
|
- ripemd160
|
||||||
- package: github.com/Sirupsen/logrus
|
- package: github.com/Sirupsen/logrus
|
||||||
version: ^1.0.0
|
version: ^1.0.0
|
||||||
|
- package: golang.org/x/sys
|
||||||
|
version: 8dbc5d05d6edcc104950cc299a1ce6641235bc86
|
||||||
|
subpackages:
|
||||||
|
- unix
|
||||||
|
|
22
lchtimes_unix.go
Normal file
22
lchtimes_unix.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// +build darwin dragonfly freebsd openbsd linux netbsd solaris
|
||||||
|
|
||||||
|
package mtree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func lchtimes(name string, atime time.Time, mtime time.Time) error {
|
||||||
|
utimes := []unix.Timespec{
|
||||||
|
unix.NsecToTimespec(atime.UnixNano()),
|
||||||
|
unix.NsecToTimespec(mtime.UnixNano()),
|
||||||
|
}
|
||||||
|
if e := unix.UtimesNanoAt(unix.AT_FDCWD, name, utimes, unix.AT_SYMLINK_NOFOLLOW); e != nil {
|
||||||
|
return &os.PathError{Op: "chtimes", Path: name, Err: e}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
11
lchtimes_unsupported.go
Normal file
11
lchtimes_unsupported.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package mtree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func lchtimes(name string, atime time.Time, mtime time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -5,9 +5,6 @@ package mtree
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/vbatts/go-mtree/xattr"
|
"github.com/vbatts/go-mtree/xattr"
|
||||||
)
|
)
|
||||||
|
@ -22,37 +19,3 @@ func xattrUpdateKeywordFunc(path string, kv KeyVal) (os.FileInfo, error) {
|
||||||
}
|
}
|
||||||
return os.Lstat(path)
|
return os.Lstat(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func lchtimes(name string, atime time.Time, mtime time.Time) error {
|
|
||||||
var utimes [2]syscall.Timespec
|
|
||||||
utimes[0] = syscall.NsecToTimespec(atime.UnixNano())
|
|
||||||
utimes[1] = syscall.NsecToTimespec(mtime.UnixNano())
|
|
||||||
if e := utimensat(atFdCwd, name, (*[2]syscall.Timespec)(unsafe.Pointer(&utimes[0])), atSymlinkNofollow); e != nil {
|
|
||||||
return &os.PathError{Op: "chtimes", Path: name, Err: e}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// from uapi/linux/fcntl.h
|
|
||||||
// don't follow symlinks
|
|
||||||
const atSymlinkNofollow = 0x100
|
|
||||||
|
|
||||||
// special value for utimes as the FD for the current working directory
|
|
||||||
const atFdCwd = -0x64
|
|
||||||
|
|
||||||
func utimensat(dirfd int, path string, times *[2]syscall.Timespec, flags int) (err error) {
|
|
||||||
if len(times) != 2 {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
var _p0 *byte
|
|
||||||
_p0, err = syscall.BytePtrFromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, _, e1 := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = syscall.Errno(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,13 +4,8 @@ package mtree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func xattrUpdateKeywordFunc(path string, kv KeyVal) (os.FileInfo, error) {
|
func xattrUpdateKeywordFunc(path string, kv KeyVal) (os.FileInfo, error) {
|
||||||
return os.Lstat(path)
|
return os.Lstat(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func lchtimes(name string, atime time.Time, mtime time.Time) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
6
vendor/github.com/Sirupsen/logrus/.travis.yml
generated
vendored
6
vendor/github.com/Sirupsen/logrus/.travis.yml
generated
vendored
|
@ -8,6 +8,8 @@ env:
|
||||||
- GOMAXPROCS=4 GORACE=halt_on_error=1
|
- GOMAXPROCS=4 GORACE=halt_on_error=1
|
||||||
install:
|
install:
|
||||||
- go get github.com/stretchr/testify/assert
|
- go get github.com/stretchr/testify/assert
|
||||||
|
- go get gopkg.in/gemnasium/logrus-airbrake-hook.v2
|
||||||
|
- go get golang.org/x/sys/unix
|
||||||
|
- go get golang.org/x/sys/windows
|
||||||
script:
|
script:
|
||||||
- go test -race -v .
|
- go test -race -v ./...
|
||||||
- cd hooks/null && go test -race -v .
|
|
||||||
|
|
13
vendor/github.com/Sirupsen/logrus/CHANGELOG.md
generated
vendored
13
vendor/github.com/Sirupsen/logrus/CHANGELOG.md
generated
vendored
|
@ -1,3 +1,16 @@
|
||||||
|
# 1.0.3
|
||||||
|
|
||||||
|
* Replace example files with testable examples
|
||||||
|
|
||||||
|
# 1.0.2
|
||||||
|
|
||||||
|
* bug: quote non-string values in text formatter (#583)
|
||||||
|
* Make (*Logger) SetLevel a public method
|
||||||
|
|
||||||
|
# 1.0.1
|
||||||
|
|
||||||
|
* bug: fix escaping in text formatter (#575)
|
||||||
|
|
||||||
# 1.0.0
|
# 1.0.0
|
||||||
|
|
||||||
* Officially changed name to lower-case
|
* Officially changed name to lower-case
|
||||||
|
|
32
vendor/github.com/Sirupsen/logrus/README.md
generated
vendored
32
vendor/github.com/Sirupsen/logrus/README.md
generated
vendored
|
@ -1,22 +1,24 @@
|
||||||
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus)
|
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus)
|
||||||
|
|
||||||
Logrus is a structured logger for Go (golang), completely API compatible with
|
Logrus is a structured logger for Go (golang), completely API compatible with
|
||||||
the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not
|
the standard library logger.
|
||||||
yet stable (pre 1.0). Logrus itself is completely stable and has been used in
|
|
||||||
many large deployments. The core API is unlikely to change much but please
|
|
||||||
version control your Logrus to make sure you aren't fetching latest `master` on
|
|
||||||
every build.**
|
|
||||||
|
|
||||||
**Seeing weird case-sensitive problems?** Unfortunately, the author failed to
|
**Seeing weird case-sensitive problems?** It's in the past been possible to
|
||||||
realize the consequences of renaming to lower-case. Due to the Go package
|
import Logrus as both upper- and lower-case. Due to the Go package environment,
|
||||||
environment, this caused issues. Regretfully, there's no turning back now.
|
this caused issues in the community and we needed a standard. Some environments
|
||||||
|
experienced problems with the upper-case variant, so the lower-case was decided.
|
||||||
Everything using `logrus` will need to use the lower-case:
|
Everything using `logrus` will need to use the lower-case:
|
||||||
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
||||||
|
|
||||||
I am terribly sorry for this inconvenience. Logrus strives hard for backwards
|
To fix Glide, see [these
|
||||||
compatibility, and the author failed to realize the cascading consequences of
|
|
||||||
such a name-change. To fix Glide, see [these
|
|
||||||
comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
|
comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
|
||||||
|
For an in-depth explanation of the casing issue, see [this
|
||||||
|
comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
|
||||||
|
|
||||||
|
**Are you interested in assisting in maintaining Logrus?** Currently I have a
|
||||||
|
lot of obligations, and I am unable to provide Logrus with the maintainership it
|
||||||
|
needs. If you'd like to help, please reach out to me at `simon at author's
|
||||||
|
username dot com`.
|
||||||
|
|
||||||
Nicely color-coded in development (when a TTY is attached, otherwise just
|
Nicely color-coded in development (when a TTY is attached, otherwise just
|
||||||
plain text):
|
plain text):
|
||||||
|
@ -266,6 +268,7 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
|
||||||
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
||||||
| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
|
| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
|
||||||
| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
|
| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
|
||||||
|
| [Mattermost](https://github.com/shuLhan/mattermost-integration/tree/master/hooks/logrus) | Hook for logging to [Mattermost](https://mattermost.com/) |
|
||||||
| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
|
| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
|
||||||
| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) |
|
| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) |
|
||||||
| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
|
| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
|
||||||
|
@ -280,7 +283,7 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
|
||||||
| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
|
| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
|
||||||
| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
|
| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
|
||||||
| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
|
| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
|
||||||
| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
| [Syslog](https://github.com/sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
||||||
| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. |
|
| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. |
|
||||||
| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
|
| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
|
||||||
| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
|
| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
|
||||||
|
@ -369,6 +372,7 @@ The built-in logging formatters are:
|
||||||
|
|
||||||
Third party logging formatters:
|
Third party logging formatters:
|
||||||
|
|
||||||
|
* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can by parsed by Kubernetes and Google Container Engine.
|
||||||
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
||||||
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
||||||
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
||||||
|
@ -449,13 +453,13 @@ Logrus has a built in facility for asserting the presence of log messages. This
|
||||||
```go
|
```go
|
||||||
import(
|
import(
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/sirupsen/logrus/hooks/null"
|
"github.com/sirupsen/logrus/hooks/test"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSomething(t*testing.T){
|
func TestSomething(t*testing.T){
|
||||||
logger, hook := null.NewNullLogger()
|
logger, hook := test.NewNullLogger()
|
||||||
logger.Error("Helloerror")
|
logger.Error("Helloerror")
|
||||||
|
|
||||||
assert.Equal(t, 1, len(hook.Entries))
|
assert.Equal(t, 1, len(hook.Entries))
|
||||||
|
|
23
vendor/github.com/Sirupsen/logrus/alt_exit_test.go
generated
vendored
23
vendor/github.com/Sirupsen/logrus/alt_exit_test.go
generated
vendored
|
@ -2,7 +2,10 @@ package logrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -11,30 +14,36 @@ func TestRegister(t *testing.T) {
|
||||||
current := len(handlers)
|
current := len(handlers)
|
||||||
RegisterExitHandler(func() {})
|
RegisterExitHandler(func() {})
|
||||||
if len(handlers) != current+1 {
|
if len(handlers) != current+1 {
|
||||||
t.Fatalf("can't add handler")
|
t.Fatalf("expected %d handlers, got %d", current+1, len(handlers))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandler(t *testing.T) {
|
func TestHandler(t *testing.T) {
|
||||||
gofile := "/tmp/testprog.go"
|
tempDir, err := ioutil.TempDir("", "test_handler")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("can't create temp dir. %q", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tempDir)
|
||||||
|
|
||||||
|
gofile := filepath.Join(tempDir, "gofile.go")
|
||||||
if err := ioutil.WriteFile(gofile, testprog, 0666); err != nil {
|
if err := ioutil.WriteFile(gofile, testprog, 0666); err != nil {
|
||||||
t.Fatalf("can't create go file")
|
t.Fatalf("can't create go file. %q", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
outfile := "/tmp/testprog.out"
|
outfile := filepath.Join(tempDir, "outfile.out")
|
||||||
arg := time.Now().UTC().String()
|
arg := time.Now().UTC().String()
|
||||||
err := exec.Command("go", "run", gofile, outfile, arg).Run()
|
err = exec.Command("go", "run", gofile, outfile, arg).Run()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("completed normally, should have failed")
|
t.Fatalf("completed normally, should have failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(outfile)
|
data, err := ioutil.ReadFile(outfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't read output file %s", outfile)
|
t.Fatalf("can't read output file %s. %q", outfile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(data) != arg {
|
if string(data) != arg {
|
||||||
t.Fatalf("bad data")
|
t.Fatalf("bad data. Expected %q, got %q", data, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
vendor/github.com/Sirupsen/logrus/appveyor.yml
generated
vendored
Normal file
14
vendor/github.com/Sirupsen/logrus/appveyor.yml
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
version: "{build}"
|
||||||
|
platform: x64
|
||||||
|
clone_folder: c:\gopath\src\github.com\sirupsen\logrus
|
||||||
|
environment:
|
||||||
|
GOPATH: c:\gopath
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
install:
|
||||||
|
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
|
||||||
|
- go version
|
||||||
|
build_script:
|
||||||
|
- go get -t
|
||||||
|
- go test
|
1
vendor/github.com/Sirupsen/logrus/entry.go
generated
vendored
1
vendor/github.com/Sirupsen/logrus/entry.go
generated
vendored
|
@ -35,6 +35,7 @@ type Entry struct {
|
||||||
Time time.Time
|
Time time.Time
|
||||||
|
|
||||||
// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
|
// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
|
||||||
|
// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
|
||||||
Level Level
|
Level Level
|
||||||
|
|
||||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||||
|
|
69
vendor/github.com/Sirupsen/logrus/example_basic_test.go
generated
vendored
Normal file
69
vendor/github.com/Sirupsen/logrus/example_basic_test.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package logrus_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_basic() {
|
||||||
|
var log = logrus.New()
|
||||||
|
log.Formatter = new(logrus.JSONFormatter)
|
||||||
|
log.Formatter = new(logrus.TextFormatter) //default
|
||||||
|
log.Formatter.(*logrus.TextFormatter).DisableTimestamp = true // remove timestamp from test output
|
||||||
|
log.Level = logrus.DebugLevel
|
||||||
|
log.Out = os.Stdout
|
||||||
|
|
||||||
|
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
|
||||||
|
// if err == nil {
|
||||||
|
// log.Out = file
|
||||||
|
// } else {
|
||||||
|
// log.Info("Failed to log to file, using default stderr")
|
||||||
|
// }
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err != nil {
|
||||||
|
entry := err.(*logrus.Entry)
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"omg": true,
|
||||||
|
"err_animal": entry.Data["animal"],
|
||||||
|
"err_size": entry.Data["size"],
|
||||||
|
"err_level": entry.Level,
|
||||||
|
"err_message": entry.Message,
|
||||||
|
"number": 100,
|
||||||
|
}).Error("The ice breaks!") // or use Fatal() to force the process to exit with a nonzero code
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"animal": "walrus",
|
||||||
|
"number": 8,
|
||||||
|
}).Debug("Started observing beach")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"animal": "walrus",
|
||||||
|
"size": 10,
|
||||||
|
}).Info("A group of walrus emerges from the ocean")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"omg": true,
|
||||||
|
"number": 122,
|
||||||
|
}).Warn("The group's number increased tremendously!")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"temperature": -4,
|
||||||
|
}).Debug("Temperature changes")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"animal": "orca",
|
||||||
|
"size": 9009,
|
||||||
|
}).Panic("It's over 9000!")
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// level=debug msg="Started observing beach" animal=walrus number=8
|
||||||
|
// level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
|
||||||
|
// level=warning msg="The group's number increased tremendously!" number=122 omg=true
|
||||||
|
// level=debug msg="Temperature changes" temperature=-4
|
||||||
|
// level=panic msg="It's over 9000!" animal=orca size=9009
|
||||||
|
// level=error msg="The ice breaks!" err_animal=orca err_level=panic err_message="It's over 9000!" err_size=9009 number=100 omg=true
|
||||||
|
}
|
35
vendor/github.com/Sirupsen/logrus/example_hook_test.go
generated
vendored
Normal file
35
vendor/github.com/Sirupsen/logrus/example_hook_test.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package logrus_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"gopkg.in/gemnasium/logrus-airbrake-hook.v2"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_hook() {
|
||||||
|
var log = logrus.New()
|
||||||
|
log.Formatter = new(logrus.TextFormatter) // default
|
||||||
|
log.Formatter.(*logrus.TextFormatter).DisableTimestamp = true // remove timestamp from test output
|
||||||
|
log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
|
||||||
|
log.Out = os.Stdout
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"animal": "walrus",
|
||||||
|
"size": 10,
|
||||||
|
}).Info("A group of walrus emerges from the ocean")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"omg": true,
|
||||||
|
"number": 122,
|
||||||
|
}).Warn("The group's number increased tremendously!")
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"omg": true,
|
||||||
|
"number": 100,
|
||||||
|
}).Error("The ice breaks!")
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
|
||||||
|
// level=warning msg="The group's number increased tremendously!" number=122 omg=true
|
||||||
|
// level=error msg="The ice breaks!" number=100 omg=true
|
||||||
|
}
|
59
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
59
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
|
@ -1,59 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
// "os"
|
|
||||||
)
|
|
||||||
|
|
||||||
var log = logrus.New()
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.Formatter = new(logrus.JSONFormatter)
|
|
||||||
log.Formatter = new(logrus.TextFormatter) // default
|
|
||||||
|
|
||||||
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
|
|
||||||
// if err == nil {
|
|
||||||
// log.Out = file
|
|
||||||
// } else {
|
|
||||||
// log.Info("Failed to log to file, using default stderr")
|
|
||||||
// }
|
|
||||||
|
|
||||||
log.Level = logrus.DebugLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
defer func() {
|
|
||||||
err := recover()
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"err": err,
|
|
||||||
"number": 100,
|
|
||||||
}).Fatal("The ice breaks!")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"number": 8,
|
|
||||||
}).Debug("Started observing beach")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"size": 10,
|
|
||||||
}).Info("A group of walrus emerges from the ocean")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"number": 122,
|
|
||||||
}).Warn("The group's number increased tremendously!")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"temperature": -4,
|
|
||||||
}).Debug("Temperature changes")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"animal": "orca",
|
|
||||||
"size": 9009,
|
|
||||||
}).Panic("It's over 9000!")
|
|
||||||
}
|
|
30
vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
30
vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
|
@ -1,30 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
var log = logrus.New()
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.Formatter = new(logrus.TextFormatter) // default
|
|
||||||
log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"size": 10,
|
|
||||||
}).Info("A group of walrus emerges from the ocean")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"number": 122,
|
|
||||||
}).Warn("The group's number increased tremendously!")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"number": 100,
|
|
||||||
}).Fatal("The ice breaks!")
|
|
||||||
}
|
|
2
vendor/github.com/Sirupsen/logrus/exported.go
generated
vendored
2
vendor/github.com/Sirupsen/logrus/exported.go
generated
vendored
|
@ -31,7 +31,7 @@ func SetFormatter(formatter Formatter) {
|
||||||
func SetLevel(level Level) {
|
func SetLevel(level Level) {
|
||||||
std.mu.Lock()
|
std.mu.Lock()
|
||||||
defer std.mu.Unlock()
|
defer std.mu.Unlock()
|
||||||
std.setLevel(level)
|
std.SetLevel(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLevel returns the standard logger level.
|
// GetLevel returns the standard logger level.
|
||||||
|
|
2
vendor/github.com/Sirupsen/logrus/formatter.go
generated
vendored
2
vendor/github.com/Sirupsen/logrus/formatter.go
generated
vendored
|
@ -2,7 +2,7 @@ package logrus
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
const DefaultTimestampFormat = time.RFC3339
|
const defaultTimestampFormat = time.RFC3339
|
||||||
|
|
||||||
// The Formatter interface is used to implement a custom Formatter. It takes an
|
// The Formatter interface is used to implement a custom Formatter. It takes an
|
||||||
// `Entry`. It exposes all the fields, including the default ones:
|
// `Entry`. It exposes all the fields, including the default ones:
|
||||||
|
|
8
vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
8
vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
|
@ -6,12 +6,12 @@
|
||||||
import (
|
import (
|
||||||
"log/syslog"
|
"log/syslog"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
lSyslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log := logrus.New()
|
log := logrus.New()
|
||||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
hook, err := lSyslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Hooks.Add(hook)
|
log.Hooks.Add(hook)
|
||||||
|
@ -25,12 +25,12 @@ If you want to connect to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "
|
||||||
import (
|
import (
|
||||||
"log/syslog"
|
"log/syslog"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
lSyslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log := logrus.New()
|
log := logrus.New()
|
||||||
hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
|
hook, err := lSyslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Hooks.Add(hook)
|
log.Hooks.Add(hook)
|
||||||
|
|
5
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
5
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
|
@ -1,12 +1,13 @@
|
||||||
// +build !windows,!nacl,!plan9
|
// +build !windows,!nacl,!plan9
|
||||||
|
|
||||||
package logrus_syslog
|
package syslog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"log/syslog"
|
"log/syslog"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SyslogHook to send logs via syslog.
|
// SyslogHook to send logs via syslog.
|
||||||
|
|
5
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
5
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
|
@ -1,9 +1,10 @@
|
||||||
package logrus_syslog
|
package syslog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"log/syslog"
|
"log/syslog"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLocalhostAddAndPrint(t *testing.T) {
|
func TestLocalhostAddAndPrint(t *testing.T) {
|
||||||
|
|
9
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
9
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
|
@ -6,8 +6,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type fieldKey string
|
type fieldKey string
|
||||||
|
|
||||||
|
// FieldMap allows customization of the key names for default fields.
|
||||||
type FieldMap map[fieldKey]string
|
type FieldMap map[fieldKey]string
|
||||||
|
|
||||||
|
// Default key names for the default fields
|
||||||
const (
|
const (
|
||||||
FieldKeyMsg = "msg"
|
FieldKeyMsg = "msg"
|
||||||
FieldKeyLevel = "level"
|
FieldKeyLevel = "level"
|
||||||
|
@ -22,6 +25,7 @@ func (f FieldMap) resolve(key fieldKey) string {
|
||||||
return string(key)
|
return string(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JSONFormatter formats logs into parsable json
|
||||||
type JSONFormatter struct {
|
type JSONFormatter struct {
|
||||||
// TimestampFormat sets the format used for marshaling timestamps.
|
// TimestampFormat sets the format used for marshaling timestamps.
|
||||||
TimestampFormat string
|
TimestampFormat string
|
||||||
|
@ -29,7 +33,7 @@ type JSONFormatter struct {
|
||||||
// DisableTimestamp allows disabling automatic timestamps in output
|
// DisableTimestamp allows disabling automatic timestamps in output
|
||||||
DisableTimestamp bool
|
DisableTimestamp bool
|
||||||
|
|
||||||
// FieldMap allows users to customize the names of keys for various fields.
|
// FieldMap allows users to customize the names of keys for default fields.
|
||||||
// As an example:
|
// As an example:
|
||||||
// formatter := &JSONFormatter{
|
// formatter := &JSONFormatter{
|
||||||
// FieldMap: FieldMap{
|
// FieldMap: FieldMap{
|
||||||
|
@ -41,6 +45,7 @@ type JSONFormatter struct {
|
||||||
FieldMap FieldMap
|
FieldMap FieldMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format renders a single log entry
|
||||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
data := make(Fields, len(entry.Data)+3)
|
data := make(Fields, len(entry.Data)+3)
|
||||||
for k, v := range entry.Data {
|
for k, v := range entry.Data {
|
||||||
|
@ -57,7 +62,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if timestampFormat == "" {
|
if timestampFormat == "" {
|
||||||
timestampFormat = DefaultTimestampFormat
|
timestampFormat = defaultTimestampFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
if !f.DisableTimestamp {
|
if !f.DisableTimestamp {
|
||||||
|
|
4
vendor/github.com/Sirupsen/logrus/logger.go
generated
vendored
4
vendor/github.com/Sirupsen/logrus/logger.go
generated
vendored
|
@ -25,7 +25,7 @@ type Logger struct {
|
||||||
Formatter Formatter
|
Formatter Formatter
|
||||||
// The logging level the logger should log at. This is typically (and defaults
|
// The logging level the logger should log at. This is typically (and defaults
|
||||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||||
// logged. `logrus.Debug` is useful in
|
// logged.
|
||||||
Level Level
|
Level Level
|
||||||
// Used to sync writing to the log. Locking is enabled by Default
|
// Used to sync writing to the log. Locking is enabled by Default
|
||||||
mu MutexWrap
|
mu MutexWrap
|
||||||
|
@ -312,6 +312,6 @@ func (logger *Logger) level() Level {
|
||||||
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) setLevel(level Level) {
|
func (logger *Logger) SetLevel(level Level) {
|
||||||
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
||||||
}
|
}
|
||||||
|
|
10
vendor/github.com/Sirupsen/logrus/terminal_appengine.go
generated
vendored
10
vendor/github.com/Sirupsen/logrus/terminal_appengine.go
generated
vendored
|
@ -1,10 +0,0 @@
|
||||||
// +build appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
6
vendor/github.com/Sirupsen/logrus/terminal_bsd.go
generated
vendored
6
vendor/github.com/Sirupsen/logrus/terminal_bsd.go
generated
vendored
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import "syscall"
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
const ioctlReadTermios = syscall.TIOCGETA
|
const ioctlReadTermios = unix.TIOCGETA
|
||||||
|
|
||||||
type Termios syscall.Termios
|
type Termios unix.Termios
|
||||||
|
|
6
vendor/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
6
vendor/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import "syscall"
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
const ioctlReadTermios = syscall.TCGETS
|
const ioctlReadTermios = unix.TCGETS
|
||||||
|
|
||||||
type Termios syscall.Termios
|
type Termios unix.Termios
|
||||||
|
|
28
vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
28
vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
|
@ -1,28 +0,0 @@
|
||||||
// Based on ssh/terminal:
|
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build linux darwin freebsd openbsd netbsd dragonfly
|
|
||||||
// +build !appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
var termios Termios
|
|
||||||
switch v := f.(type) {
|
|
||||||
case *os.File:
|
|
||||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
|
||||||
return err == 0
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
21
vendor/github.com/Sirupsen/logrus/terminal_solaris.go
generated
vendored
21
vendor/github.com/Sirupsen/logrus/terminal_solaris.go
generated
vendored
|
@ -1,21 +0,0 @@
|
||||||
// +build solaris,!appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
switch v := f.(type) {
|
|
||||||
case *os.File:
|
|
||||||
_, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA)
|
|
||||||
return err == nil
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
82
vendor/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
82
vendor/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
|
@ -1,82 +0,0 @@
|
||||||
// Based on ssh/terminal:
|
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build windows,!appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
|
|
||||||
var (
|
|
||||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
|
||||||
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
enableProcessedOutput = 0x0001
|
|
||||||
enableWrapAtEolOutput = 0x0002
|
|
||||||
enableVirtualTerminalProcessing = 0x0004
|
|
||||||
)
|
|
||||||
|
|
||||||
func getVersion() (float64, error) {
|
|
||||||
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
|
|
||||||
cmd := exec.Command("cmd", "ver")
|
|
||||||
cmd.Stdout = stdout
|
|
||||||
cmd.Stderr = stderr
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// The output should be like "Microsoft Windows [Version XX.X.XXXXXX]"
|
|
||||||
version := strings.Replace(stdout.String(), "\n", "", -1)
|
|
||||||
version = strings.Replace(version, "\r\n", "", -1)
|
|
||||||
|
|
||||||
x1 := strings.Index(version, "[Version")
|
|
||||||
|
|
||||||
if x1 == -1 || strings.Index(version, "]") == -1 {
|
|
||||||
return -1, errors.New("Can't determine Windows version")
|
|
||||||
}
|
|
||||||
|
|
||||||
return strconv.ParseFloat(version[x1+9:x1+13], 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
ver, err := getVersion()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activate Virtual Processing for Windows CMD
|
|
||||||
// Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
|
|
||||||
if ver >= 10 {
|
|
||||||
handle := syscall.Handle(os.Stderr.Fd())
|
|
||||||
procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
switch v := f.(type) {
|
|
||||||
case *os.File:
|
|
||||||
var st uint32
|
|
||||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
|
|
||||||
return r != 0 && e == 0
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
56
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
56
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
|
@ -3,10 +3,14 @@ package logrus
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -14,7 +18,7 @@ const (
|
||||||
red = 31
|
red = 31
|
||||||
green = 32
|
green = 32
|
||||||
yellow = 33
|
yellow = 33
|
||||||
blue = 34
|
blue = 36
|
||||||
gray = 37
|
gray = 37
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,6 +30,7 @@ func init() {
|
||||||
baseTimestamp = time.Now()
|
baseTimestamp = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TextFormatter formats logs into text
|
||||||
type TextFormatter struct {
|
type TextFormatter struct {
|
||||||
// Set to true to bypass checking for a TTY before outputting colors.
|
// Set to true to bypass checking for a TTY before outputting colors.
|
||||||
ForceColors bool
|
ForceColors bool
|
||||||
|
@ -52,10 +57,6 @@ type TextFormatter struct {
|
||||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||||
QuoteEmptyFields bool
|
QuoteEmptyFields bool
|
||||||
|
|
||||||
// QuoteCharacter can be set to the override the default quoting character "
|
|
||||||
// with something else. For example: ', or `.
|
|
||||||
QuoteCharacter string
|
|
||||||
|
|
||||||
// Whether the logger's out is to a terminal
|
// Whether the logger's out is to a terminal
|
||||||
isTerminal bool
|
isTerminal bool
|
||||||
|
|
||||||
|
@ -63,14 +64,21 @@ type TextFormatter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) init(entry *Entry) {
|
func (f *TextFormatter) init(entry *Entry) {
|
||||||
if len(f.QuoteCharacter) == 0 {
|
|
||||||
f.QuoteCharacter = "\""
|
|
||||||
}
|
|
||||||
if entry.Logger != nil {
|
if entry.Logger != nil {
|
||||||
f.isTerminal = IsTerminal(entry.Logger.Out)
|
f.isTerminal = f.checkIfTerminal(entry.Logger.Out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) checkIfTerminal(w io.Writer) bool {
|
||||||
|
switch v := w.(type) {
|
||||||
|
case *os.File:
|
||||||
|
return terminal.IsTerminal(int(v.Fd()))
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format renders a single log entry
|
||||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
var b *bytes.Buffer
|
var b *bytes.Buffer
|
||||||
keys := make([]string, 0, len(entry.Data))
|
keys := make([]string, 0, len(entry.Data))
|
||||||
|
@ -95,7 +103,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if timestampFormat == "" {
|
if timestampFormat == "" {
|
||||||
timestampFormat = DefaultTimestampFormat
|
timestampFormat = defaultTimestampFormat
|
||||||
}
|
}
|
||||||
if isColored {
|
if isColored {
|
||||||
f.printColored(b, entry, keys, timestampFormat)
|
f.printColored(b, entry, keys, timestampFormat)
|
||||||
|
@ -153,7 +161,7 @@ func (f *TextFormatter) needsQuoting(text string) bool {
|
||||||
if !((ch >= 'a' && ch <= 'z') ||
|
if !((ch >= 'a' && ch <= 'z') ||
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
(ch >= 'A' && ch <= 'Z') ||
|
||||||
(ch >= '0' && ch <= '9') ||
|
(ch >= '0' && ch <= '9') ||
|
||||||
ch == '-' || ch == '.') {
|
ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,29 +169,23 @@ func (f *TextFormatter) needsQuoting(text string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||||
|
if b.Len() > 0 {
|
||||||
|
b.WriteByte(' ')
|
||||||
|
}
|
||||||
b.WriteString(key)
|
b.WriteString(key)
|
||||||
b.WriteByte('=')
|
b.WriteByte('=')
|
||||||
f.appendValue(b, value)
|
f.appendValue(b, value)
|
||||||
b.WriteByte(' ')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||||
switch value := value.(type) {
|
stringVal, ok := value.(string)
|
||||||
case string:
|
if !ok {
|
||||||
if !f.needsQuoting(value) {
|
stringVal = fmt.Sprint(value)
|
||||||
b.WriteString(value)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter)
|
|
||||||
}
|
}
|
||||||
case error:
|
|
||||||
errmsg := value.Error()
|
if !f.needsQuoting(stringVal) {
|
||||||
if !f.needsQuoting(errmsg) {
|
b.WriteString(stringVal)
|
||||||
b.WriteString(errmsg)
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter)
|
b.WriteString(fmt.Sprintf("%q", stringVal))
|
||||||
}
|
|
||||||
default:
|
|
||||||
fmt.Fprint(b, value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
84
vendor/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
84
vendor/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
|
@ -3,18 +3,38 @@ package logrus
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestFormatting(t *testing.T) {
|
||||||
|
tf := &TextFormatter{DisableColors: true}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
value string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{`foo`, "time=\"0001-01-01T00:00:00Z\" level=panic test=foo\n"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
b, _ := tf.Format(WithField("test", tc.value))
|
||||||
|
|
||||||
|
if string(b) != tc.expected {
|
||||||
|
t.Errorf("formatting expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestQuoting(t *testing.T) {
|
func TestQuoting(t *testing.T) {
|
||||||
tf := &TextFormatter{DisableColors: true}
|
tf := &TextFormatter{DisableColors: true}
|
||||||
|
|
||||||
checkQuoting := func(q bool, value interface{}) {
|
checkQuoting := func(q bool, value interface{}) {
|
||||||
b, _ := tf.Format(WithField("test", value))
|
b, _ := tf.Format(WithField("test", value))
|
||||||
idx := bytes.Index(b, ([]byte)("test="))
|
idx := bytes.Index(b, ([]byte)("test="))
|
||||||
cont := bytes.Contains(b[idx+5:], []byte(tf.QuoteCharacter))
|
cont := bytes.Contains(b[idx+5:], []byte("\""))
|
||||||
if cont != q {
|
if cont != q {
|
||||||
if q {
|
if q {
|
||||||
t.Errorf("quoting expected for: %#v", value)
|
t.Errorf("quoting expected for: %#v", value)
|
||||||
|
@ -28,24 +48,18 @@ func TestQuoting(t *testing.T) {
|
||||||
checkQuoting(false, "abcd")
|
checkQuoting(false, "abcd")
|
||||||
checkQuoting(false, "v1.0")
|
checkQuoting(false, "v1.0")
|
||||||
checkQuoting(false, "1234567890")
|
checkQuoting(false, "1234567890")
|
||||||
checkQuoting(true, "/foobar")
|
checkQuoting(false, "/foobar")
|
||||||
|
checkQuoting(false, "foo_bar")
|
||||||
|
checkQuoting(false, "foo@bar")
|
||||||
|
checkQuoting(false, "foobar^")
|
||||||
|
checkQuoting(false, "+/-_^@f.oobar")
|
||||||
|
checkQuoting(true, "foobar$")
|
||||||
|
checkQuoting(true, "&foobar")
|
||||||
checkQuoting(true, "x y")
|
checkQuoting(true, "x y")
|
||||||
checkQuoting(true, "x,y")
|
checkQuoting(true, "x,y")
|
||||||
checkQuoting(false, errors.New("invalid"))
|
checkQuoting(false, errors.New("invalid"))
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
checkQuoting(true, errors.New("invalid argument"))
|
||||||
|
|
||||||
// Test for custom quote character.
|
|
||||||
tf.QuoteCharacter = "`"
|
|
||||||
checkQuoting(false, "")
|
|
||||||
checkQuoting(false, "abcd")
|
|
||||||
checkQuoting(true, "/foobar")
|
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
|
||||||
|
|
||||||
// Test for multi-character quotes.
|
|
||||||
tf.QuoteCharacter = "§~±"
|
|
||||||
checkQuoting(false, "abcd")
|
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
|
||||||
|
|
||||||
// Test for quoting empty fields.
|
// Test for quoting empty fields.
|
||||||
tf.QuoteEmptyFields = true
|
tf.QuoteEmptyFields = true
|
||||||
checkQuoting(true, "")
|
checkQuoting(true, "")
|
||||||
|
@ -53,13 +67,53 @@ func TestQuoting(t *testing.T) {
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
checkQuoting(true, errors.New("invalid argument"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEscaping(t *testing.T) {
|
||||||
|
tf := &TextFormatter{DisableColors: true}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
value string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{`ba"r`, `ba\"r`},
|
||||||
|
{`ba'r`, `ba'r`},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
b, _ := tf.Format(WithField("test", tc.value))
|
||||||
|
if !bytes.Contains(b, []byte(tc.expected)) {
|
||||||
|
t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEscaping_Interface(t *testing.T) {
|
||||||
|
tf := &TextFormatter{DisableColors: true}
|
||||||
|
|
||||||
|
ts := time.Now()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
value interface{}
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{ts, fmt.Sprintf("\"%s\"", ts.String())},
|
||||||
|
{errors.New("error: something went wrong"), "\"error: something went wrong\""},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
b, _ := tf.Format(WithField("test", tc.value))
|
||||||
|
if !bytes.Contains(b, []byte(tc.expected)) {
|
||||||
|
t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTimestampFormat(t *testing.T) {
|
func TestTimestampFormat(t *testing.T) {
|
||||||
checkTimeStr := func(format string) {
|
checkTimeStr := func(format string) {
|
||||||
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
|
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
|
||||||
customStr, _ := customFormatter.Format(WithField("test", "test"))
|
customStr, _ := customFormatter.Format(WithField("test", "test"))
|
||||||
timeStart := bytes.Index(customStr, ([]byte)("time="))
|
timeStart := bytes.Index(customStr, ([]byte)("time="))
|
||||||
timeEnd := bytes.Index(customStr, ([]byte)("level="))
|
timeEnd := bytes.Index(customStr, ([]byte)("level="))
|
||||||
timeStr := customStr[timeStart+5+len(customFormatter.QuoteCharacter) : timeEnd-1-len(customFormatter.QuoteCharacter)]
|
timeStr := customStr[timeStart+5+len("\"") : timeEnd-1-len("\"")]
|
||||||
if format == "" {
|
if format == "" {
|
||||||
format = time.RFC3339
|
format = time.RFC3339
|
||||||
}
|
}
|
||||||
|
|
1086
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
1086
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
File diff suppressed because it is too large
Load diff
1346
vendor/golang.org/x/crypto/acme/acme_test.go
generated
vendored
1346
vendor/golang.org/x/crypto/acme/acme_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
819
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
819
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
|
@ -1,819 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package autocert provides automatic access to certificates from Let's Encrypt
|
|
||||||
// and any other ACME-based CA.
|
|
||||||
//
|
|
||||||
// This package is a work in progress and makes no API stability promises.
|
|
||||||
package autocert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"crypto"
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/pem"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
mathrand "math/rand"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/acme"
|
|
||||||
)
|
|
||||||
|
|
||||||
// createCertRetryAfter is how much time to wait before removing a failed state
|
|
||||||
// entry due to an unsuccessful createCert call.
|
|
||||||
// This is a variable instead of a const for testing.
|
|
||||||
// TODO: Consider making it configurable or an exp backoff?
|
|
||||||
var createCertRetryAfter = time.Minute
|
|
||||||
|
|
||||||
// pseudoRand is safe for concurrent use.
|
|
||||||
var pseudoRand *lockedMathRand
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
src := mathrand.NewSource(timeNow().UnixNano())
|
|
||||||
pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcceptTOS is a Manager.Prompt function that always returns true to
|
|
||||||
// indicate acceptance of the CA's Terms of Service during account
|
|
||||||
// registration.
|
|
||||||
func AcceptTOS(tosURL string) bool { return true }
|
|
||||||
|
|
||||||
// HostPolicy specifies which host names the Manager is allowed to respond to.
|
|
||||||
// It returns a non-nil error if the host should be rejected.
|
|
||||||
// The returned error is accessible via tls.Conn.Handshake and its callers.
|
|
||||||
// See Manager's HostPolicy field and GetCertificate method docs for more details.
|
|
||||||
type HostPolicy func(ctx context.Context, host string) error
|
|
||||||
|
|
||||||
// HostWhitelist returns a policy where only the specified host names are allowed.
|
|
||||||
// Only exact matches are currently supported. Subdomains, regexp or wildcard
|
|
||||||
// will not match.
|
|
||||||
func HostWhitelist(hosts ...string) HostPolicy {
|
|
||||||
whitelist := make(map[string]bool, len(hosts))
|
|
||||||
for _, h := range hosts {
|
|
||||||
whitelist[h] = true
|
|
||||||
}
|
|
||||||
return func(_ context.Context, host string) error {
|
|
||||||
if !whitelist[host] {
|
|
||||||
return errors.New("acme/autocert: host not configured")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// defaultHostPolicy is used when Manager.HostPolicy is not set.
|
|
||||||
func defaultHostPolicy(context.Context, string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manager is a stateful certificate manager built on top of acme.Client.
|
|
||||||
// It obtains and refreshes certificates automatically,
|
|
||||||
// as well as providing them to a TLS server via tls.Config.
|
|
||||||
//
|
|
||||||
// To preserve issued certificates and improve overall performance,
|
|
||||||
// use a cache implementation of Cache. For instance, DirCache.
|
|
||||||
type Manager struct {
|
|
||||||
// Prompt specifies a callback function to conditionally accept a CA's Terms of Service (TOS).
|
|
||||||
// The registration may require the caller to agree to the CA's TOS.
|
|
||||||
// If so, Manager calls Prompt with a TOS URL provided by the CA. Prompt should report
|
|
||||||
// whether the caller agrees to the terms.
|
|
||||||
//
|
|
||||||
// To always accept the terms, the callers can use AcceptTOS.
|
|
||||||
Prompt func(tosURL string) bool
|
|
||||||
|
|
||||||
// Cache optionally stores and retrieves previously-obtained certificates.
|
|
||||||
// If nil, certs will only be cached for the lifetime of the Manager.
|
|
||||||
//
|
|
||||||
// Manager passes the Cache certificates data encoded in PEM, with private/public
|
|
||||||
// parts combined in a single Cache.Put call, private key first.
|
|
||||||
Cache Cache
|
|
||||||
|
|
||||||
// HostPolicy controls which domains the Manager will attempt
|
|
||||||
// to retrieve new certificates for. It does not affect cached certs.
|
|
||||||
//
|
|
||||||
// If non-nil, HostPolicy is called before requesting a new cert.
|
|
||||||
// If nil, all hosts are currently allowed. This is not recommended,
|
|
||||||
// as it opens a potential attack where clients connect to a server
|
|
||||||
// by IP address and pretend to be asking for an incorrect host name.
|
|
||||||
// Manager will attempt to obtain a certificate for that host, incorrectly,
|
|
||||||
// eventually reaching the CA's rate limit for certificate requests
|
|
||||||
// and making it impossible to obtain actual certificates.
|
|
||||||
//
|
|
||||||
// See GetCertificate for more details.
|
|
||||||
HostPolicy HostPolicy
|
|
||||||
|
|
||||||
// RenewBefore optionally specifies how early certificates should
|
|
||||||
// be renewed before they expire.
|
|
||||||
//
|
|
||||||
// If zero, they're renewed 30 days before expiration.
|
|
||||||
RenewBefore time.Duration
|
|
||||||
|
|
||||||
// Client is used to perform low-level operations, such as account registration
|
|
||||||
// and requesting new certificates.
|
|
||||||
// If Client is nil, a zero-value acme.Client is used with acme.LetsEncryptURL
|
|
||||||
// directory endpoint and a newly-generated ECDSA P-256 key.
|
|
||||||
//
|
|
||||||
// Mutating the field after the first call of GetCertificate method will have no effect.
|
|
||||||
Client *acme.Client
|
|
||||||
|
|
||||||
// Email optionally specifies a contact email address.
|
|
||||||
// This is used by CAs, such as Let's Encrypt, to notify about problems
|
|
||||||
// with issued certificates.
|
|
||||||
//
|
|
||||||
// If the Client's account key is already registered, Email is not used.
|
|
||||||
Email string
|
|
||||||
|
|
||||||
// ForceRSA makes the Manager generate certificates with 2048-bit RSA keys.
|
|
||||||
//
|
|
||||||
// If false, a default is used. Currently the default
|
|
||||||
// is EC-based keys using the P-256 curve.
|
|
||||||
ForceRSA bool
|
|
||||||
|
|
||||||
clientMu sync.Mutex
|
|
||||||
client *acme.Client // initialized by acmeClient method
|
|
||||||
|
|
||||||
stateMu sync.Mutex
|
|
||||||
state map[string]*certState // keyed by domain name
|
|
||||||
|
|
||||||
// tokenCert is keyed by token domain name, which matches server name
|
|
||||||
// of ClientHello. Keys always have ".acme.invalid" suffix.
|
|
||||||
tokenCertMu sync.RWMutex
|
|
||||||
tokenCert map[string]*tls.Certificate
|
|
||||||
|
|
||||||
// renewal tracks the set of domains currently running renewal timers.
|
|
||||||
// It is keyed by domain name.
|
|
||||||
renewalMu sync.Mutex
|
|
||||||
renewal map[string]*domainRenewal
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCertificate implements the tls.Config.GetCertificate hook.
|
|
||||||
// It provides a TLS certificate for hello.ServerName host, including answering
|
|
||||||
// *.acme.invalid (TLS-SNI) challenges. All other fields of hello are ignored.
|
|
||||||
//
|
|
||||||
// If m.HostPolicy is non-nil, GetCertificate calls the policy before requesting
|
|
||||||
// a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
|
|
||||||
// The error is propagated back to the caller of GetCertificate and is user-visible.
|
|
||||||
// This does not affect cached certs. See HostPolicy field description for more details.
|
|
||||||
func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
|
||||||
if m.Prompt == nil {
|
|
||||||
return nil, errors.New("acme/autocert: Manager.Prompt not set")
|
|
||||||
}
|
|
||||||
|
|
||||||
name := hello.ServerName
|
|
||||||
if name == "" {
|
|
||||||
return nil, errors.New("acme/autocert: missing server name")
|
|
||||||
}
|
|
||||||
if !strings.Contains(strings.Trim(name, "."), ".") {
|
|
||||||
return nil, errors.New("acme/autocert: server name component count invalid")
|
|
||||||
}
|
|
||||||
if strings.ContainsAny(name, `/\`) {
|
|
||||||
return nil, errors.New("acme/autocert: server name contains invalid character")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// check whether this is a token cert requested for TLS-SNI challenge
|
|
||||||
if strings.HasSuffix(name, ".acme.invalid") {
|
|
||||||
m.tokenCertMu.RLock()
|
|
||||||
defer m.tokenCertMu.RUnlock()
|
|
||||||
if cert := m.tokenCert[name]; cert != nil {
|
|
||||||
return cert, nil
|
|
||||||
}
|
|
||||||
if cert, err := m.cacheGet(ctx, name); err == nil {
|
|
||||||
return cert, nil
|
|
||||||
}
|
|
||||||
// TODO: cache error results?
|
|
||||||
return nil, fmt.Errorf("acme/autocert: no token cert for %q", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// regular domain
|
|
||||||
name = strings.TrimSuffix(name, ".") // golang.org/issue/18114
|
|
||||||
cert, err := m.cert(ctx, name)
|
|
||||||
if err == nil {
|
|
||||||
return cert, nil
|
|
||||||
}
|
|
||||||
if err != ErrCacheMiss {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// first-time
|
|
||||||
if err := m.hostPolicy()(ctx, name); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cert, err = m.createCert(ctx, name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
m.cachePut(ctx, name, cert)
|
|
||||||
return cert, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// cert returns an existing certificate either from m.state or cache.
|
|
||||||
// If a certificate is found in cache but not in m.state, the latter will be filled
|
|
||||||
// with the cached value.
|
|
||||||
func (m *Manager) cert(ctx context.Context, name string) (*tls.Certificate, error) {
|
|
||||||
m.stateMu.Lock()
|
|
||||||
if s, ok := m.state[name]; ok {
|
|
||||||
m.stateMu.Unlock()
|
|
||||||
s.RLock()
|
|
||||||
defer s.RUnlock()
|
|
||||||
return s.tlscert()
|
|
||||||
}
|
|
||||||
defer m.stateMu.Unlock()
|
|
||||||
cert, err := m.cacheGet(ctx, name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
signer, ok := cert.PrivateKey.(crypto.Signer)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("acme/autocert: private key cannot sign")
|
|
||||||
}
|
|
||||||
if m.state == nil {
|
|
||||||
m.state = make(map[string]*certState)
|
|
||||||
}
|
|
||||||
s := &certState{
|
|
||||||
key: signer,
|
|
||||||
cert: cert.Certificate,
|
|
||||||
leaf: cert.Leaf,
|
|
||||||
}
|
|
||||||
m.state[name] = s
|
|
||||||
go m.renew(name, s.key, s.leaf.NotAfter)
|
|
||||||
return cert, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// cacheGet always returns a valid certificate, or an error otherwise.
|
|
||||||
// If a cached certficate exists but is not valid, ErrCacheMiss is returned.
|
|
||||||
func (m *Manager) cacheGet(ctx context.Context, domain string) (*tls.Certificate, error) {
|
|
||||||
if m.Cache == nil {
|
|
||||||
return nil, ErrCacheMiss
|
|
||||||
}
|
|
||||||
data, err := m.Cache.Get(ctx, domain)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// private
|
|
||||||
priv, pub := pem.Decode(data)
|
|
||||||
if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
|
|
||||||
return nil, ErrCacheMiss
|
|
||||||
}
|
|
||||||
privKey, err := parsePrivateKey(priv.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// public
|
|
||||||
var pubDER [][]byte
|
|
||||||
for len(pub) > 0 {
|
|
||||||
var b *pem.Block
|
|
||||||
b, pub = pem.Decode(pub)
|
|
||||||
if b == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
pubDER = append(pubDER, b.Bytes)
|
|
||||||
}
|
|
||||||
if len(pub) > 0 {
|
|
||||||
// Leftover content not consumed by pem.Decode. Corrupt. Ignore.
|
|
||||||
return nil, ErrCacheMiss
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify and create TLS cert
|
|
||||||
leaf, err := validCert(domain, pubDER, privKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrCacheMiss
|
|
||||||
}
|
|
||||||
tlscert := &tls.Certificate{
|
|
||||||
Certificate: pubDER,
|
|
||||||
PrivateKey: privKey,
|
|
||||||
Leaf: leaf,
|
|
||||||
}
|
|
||||||
return tlscert, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Manager) cachePut(ctx context.Context, domain string, tlscert *tls.Certificate) error {
|
|
||||||
if m.Cache == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// contains PEM-encoded data
|
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
// private
|
|
||||||
switch key := tlscert.PrivateKey.(type) {
|
|
||||||
case *ecdsa.PrivateKey:
|
|
||||||
if err := encodeECDSAKey(&buf, key); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *rsa.PrivateKey:
|
|
||||||
b := x509.MarshalPKCS1PrivateKey(key)
|
|
||||||
pb := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: b}
|
|
||||||
if err := pem.Encode(&buf, pb); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return errors.New("acme/autocert: unknown private key type")
|
|
||||||
}
|
|
||||||
|
|
||||||
// public
|
|
||||||
for _, b := range tlscert.Certificate {
|
|
||||||
pb := &pem.Block{Type: "CERTIFICATE", Bytes: b}
|
|
||||||
if err := pem.Encode(&buf, pb); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.Cache.Put(ctx, domain, buf.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
|
|
||||||
b, err := x509.MarshalECPrivateKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pb := &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
|
|
||||||
return pem.Encode(w, pb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// createCert starts the domain ownership verification and returns a certificate
|
|
||||||
// for that domain upon success.
|
|
||||||
//
|
|
||||||
// If the domain is already being verified, it waits for the existing verification to complete.
|
|
||||||
// Either way, createCert blocks for the duration of the whole process.
|
|
||||||
func (m *Manager) createCert(ctx context.Context, domain string) (*tls.Certificate, error) {
|
|
||||||
// TODO: maybe rewrite this whole piece using sync.Once
|
|
||||||
state, err := m.certState(domain)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// state may exist if another goroutine is already working on it
|
|
||||||
// in which case just wait for it to finish
|
|
||||||
if !state.locked {
|
|
||||||
state.RLock()
|
|
||||||
defer state.RUnlock()
|
|
||||||
return state.tlscert()
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are the first; state is locked.
|
|
||||||
// Unblock the readers when domain ownership is verified
|
|
||||||
// and the we got the cert or the process failed.
|
|
||||||
defer state.Unlock()
|
|
||||||
state.locked = false
|
|
||||||
|
|
||||||
der, leaf, err := m.authorizedCert(ctx, state.key, domain)
|
|
||||||
if err != nil {
|
|
||||||
// Remove the failed state after some time,
|
|
||||||
// making the manager call createCert again on the following TLS hello.
|
|
||||||
time.AfterFunc(createCertRetryAfter, func() {
|
|
||||||
defer testDidRemoveState(domain)
|
|
||||||
m.stateMu.Lock()
|
|
||||||
defer m.stateMu.Unlock()
|
|
||||||
// Verify the state hasn't changed and it's still invalid
|
|
||||||
// before deleting.
|
|
||||||
s, ok := m.state[domain]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, err := validCert(domain, s.cert, s.key); err == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delete(m.state, domain)
|
|
||||||
})
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
state.cert = der
|
|
||||||
state.leaf = leaf
|
|
||||||
go m.renew(domain, state.key, state.leaf.NotAfter)
|
|
||||||
return state.tlscert()
|
|
||||||
}
|
|
||||||
|
|
||||||
// certState returns a new or existing certState.
|
|
||||||
// If a new certState is returned, state.exist is false and the state is locked.
|
|
||||||
// The returned error is non-nil only in the case where a new state could not be created.
|
|
||||||
func (m *Manager) certState(domain string) (*certState, error) {
|
|
||||||
m.stateMu.Lock()
|
|
||||||
defer m.stateMu.Unlock()
|
|
||||||
if m.state == nil {
|
|
||||||
m.state = make(map[string]*certState)
|
|
||||||
}
|
|
||||||
// existing state
|
|
||||||
if state, ok := m.state[domain]; ok {
|
|
||||||
return state, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// new locked state
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
key crypto.Signer
|
|
||||||
)
|
|
||||||
if m.ForceRSA {
|
|
||||||
key, err = rsa.GenerateKey(rand.Reader, 2048)
|
|
||||||
} else {
|
|
||||||
key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
state := &certState{
|
|
||||||
key: key,
|
|
||||||
locked: true,
|
|
||||||
}
|
|
||||||
state.Lock() // will be unlocked by m.certState caller
|
|
||||||
m.state[domain] = state
|
|
||||||
return state, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// authorizedCert starts domain ownership verification process and requests a new cert upon success.
|
|
||||||
// The key argument is the certificate private key.
|
|
||||||
func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain string) (der [][]byte, leaf *x509.Certificate, err error) {
|
|
||||||
if err := m.verify(ctx, domain); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
client, err := m.acmeClient(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
csr, err := certRequest(key, domain)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
der, _, err = client.CreateCert(ctx, csr, 0, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
leaf, err = validCert(domain, der, key)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return der, leaf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify starts a new identifier (domain) authorization flow.
|
|
||||||
// It prepares a challenge response and then blocks until the authorization
|
|
||||||
// is marked as "completed" by the CA (either succeeded or failed).
|
|
||||||
//
|
|
||||||
// verify returns nil iff the verification was successful.
|
|
||||||
func (m *Manager) verify(ctx context.Context, domain string) error {
|
|
||||||
client, err := m.acmeClient(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// start domain authorization and get the challenge
|
|
||||||
authz, err := client.Authorize(ctx, domain)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// maybe don't need to at all
|
|
||||||
if authz.Status == acme.StatusValid {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// pick a challenge: prefer tls-sni-02 over tls-sni-01
|
|
||||||
// TODO: consider authz.Combinations
|
|
||||||
var chal *acme.Challenge
|
|
||||||
for _, c := range authz.Challenges {
|
|
||||||
if c.Type == "tls-sni-02" {
|
|
||||||
chal = c
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if c.Type == "tls-sni-01" {
|
|
||||||
chal = c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if chal == nil {
|
|
||||||
return errors.New("acme/autocert: no supported challenge type found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a token cert for the challenge response
|
|
||||||
var (
|
|
||||||
cert tls.Certificate
|
|
||||||
name string
|
|
||||||
)
|
|
||||||
switch chal.Type {
|
|
||||||
case "tls-sni-01":
|
|
||||||
cert, name, err = client.TLSSNI01ChallengeCert(chal.Token)
|
|
||||||
case "tls-sni-02":
|
|
||||||
cert, name, err = client.TLSSNI02ChallengeCert(chal.Token)
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("acme/autocert: unknown challenge type %q", chal.Type)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.putTokenCert(ctx, name, &cert)
|
|
||||||
defer func() {
|
|
||||||
// verification has ended at this point
|
|
||||||
// don't need token cert anymore
|
|
||||||
go m.deleteTokenCert(name)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// ready to fulfill the challenge
|
|
||||||
if _, err := client.Accept(ctx, chal); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// wait for the CA to validate
|
|
||||||
_, err = client.WaitAuthorization(ctx, authz.URI)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// putTokenCert stores the cert under the named key in both m.tokenCert map
|
|
||||||
// and m.Cache.
|
|
||||||
func (m *Manager) putTokenCert(ctx context.Context, name string, cert *tls.Certificate) {
|
|
||||||
m.tokenCertMu.Lock()
|
|
||||||
defer m.tokenCertMu.Unlock()
|
|
||||||
if m.tokenCert == nil {
|
|
||||||
m.tokenCert = make(map[string]*tls.Certificate)
|
|
||||||
}
|
|
||||||
m.tokenCert[name] = cert
|
|
||||||
m.cachePut(ctx, name, cert)
|
|
||||||
}
|
|
||||||
|
|
||||||
// deleteTokenCert removes the token certificate for the specified domain name
|
|
||||||
// from both m.tokenCert map and m.Cache.
|
|
||||||
func (m *Manager) deleteTokenCert(name string) {
|
|
||||||
m.tokenCertMu.Lock()
|
|
||||||
defer m.tokenCertMu.Unlock()
|
|
||||||
delete(m.tokenCert, name)
|
|
||||||
if m.Cache != nil {
|
|
||||||
m.Cache.Delete(context.Background(), name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// renew starts a cert renewal timer loop, one per domain.
|
|
||||||
//
|
|
||||||
// The loop is scheduled in two cases:
|
|
||||||
// - a cert was fetched from cache for the first time (wasn't in m.state)
|
|
||||||
// - a new cert was created by m.createCert
|
|
||||||
//
|
|
||||||
// The key argument is a certificate private key.
|
|
||||||
// The exp argument is the cert expiration time (NotAfter).
|
|
||||||
func (m *Manager) renew(domain string, key crypto.Signer, exp time.Time) {
|
|
||||||
m.renewalMu.Lock()
|
|
||||||
defer m.renewalMu.Unlock()
|
|
||||||
if m.renewal[domain] != nil {
|
|
||||||
// another goroutine is already on it
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if m.renewal == nil {
|
|
||||||
m.renewal = make(map[string]*domainRenewal)
|
|
||||||
}
|
|
||||||
dr := &domainRenewal{m: m, domain: domain, key: key}
|
|
||||||
m.renewal[domain] = dr
|
|
||||||
dr.start(exp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// stopRenew stops all currently running cert renewal timers.
|
|
||||||
// The timers are not restarted during the lifetime of the Manager.
|
|
||||||
func (m *Manager) stopRenew() {
|
|
||||||
m.renewalMu.Lock()
|
|
||||||
defer m.renewalMu.Unlock()
|
|
||||||
for name, dr := range m.renewal {
|
|
||||||
delete(m.renewal, name)
|
|
||||||
dr.stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
|
|
||||||
const keyName = "acme_account.key"
|
|
||||||
|
|
||||||
genKey := func() (*ecdsa.PrivateKey, error) {
|
|
||||||
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.Cache == nil {
|
|
||||||
return genKey()
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := m.Cache.Get(ctx, keyName)
|
|
||||||
if err == ErrCacheMiss {
|
|
||||||
key, err := genKey()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var buf bytes.Buffer
|
|
||||||
if err := encodeECDSAKey(&buf, key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := m.Cache.Put(ctx, keyName, buf.Bytes()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return key, nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
priv, _ := pem.Decode(data)
|
|
||||||
if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
|
|
||||||
return nil, errors.New("acme/autocert: invalid account key found in cache")
|
|
||||||
}
|
|
||||||
return parsePrivateKey(priv.Bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Manager) acmeClient(ctx context.Context) (*acme.Client, error) {
|
|
||||||
m.clientMu.Lock()
|
|
||||||
defer m.clientMu.Unlock()
|
|
||||||
if m.client != nil {
|
|
||||||
return m.client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
client := m.Client
|
|
||||||
if client == nil {
|
|
||||||
client = &acme.Client{DirectoryURL: acme.LetsEncryptURL}
|
|
||||||
}
|
|
||||||
if client.Key == nil {
|
|
||||||
var err error
|
|
||||||
client.Key, err = m.accountKey(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var contact []string
|
|
||||||
if m.Email != "" {
|
|
||||||
contact = []string{"mailto:" + m.Email}
|
|
||||||
}
|
|
||||||
a := &acme.Account{Contact: contact}
|
|
||||||
_, err := client.Register(ctx, a, m.Prompt)
|
|
||||||
if ae, ok := err.(*acme.Error); err == nil || ok && ae.StatusCode == http.StatusConflict {
|
|
||||||
// conflict indicates the key is already registered
|
|
||||||
m.client = client
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
return m.client, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Manager) hostPolicy() HostPolicy {
|
|
||||||
if m.HostPolicy != nil {
|
|
||||||
return m.HostPolicy
|
|
||||||
}
|
|
||||||
return defaultHostPolicy
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Manager) renewBefore() time.Duration {
|
|
||||||
if m.RenewBefore > renewJitter {
|
|
||||||
return m.RenewBefore
|
|
||||||
}
|
|
||||||
return 720 * time.Hour // 30 days
|
|
||||||
}
|
|
||||||
|
|
||||||
// certState is ready when its mutex is unlocked for reading.
|
|
||||||
type certState struct {
|
|
||||||
sync.RWMutex
|
|
||||||
locked bool // locked for read/write
|
|
||||||
key crypto.Signer // private key for cert
|
|
||||||
cert [][]byte // DER encoding
|
|
||||||
leaf *x509.Certificate // parsed cert[0]; always non-nil if cert != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// tlscert creates a tls.Certificate from s.key and s.cert.
|
|
||||||
// Callers should wrap it in s.RLock() and s.RUnlock().
|
|
||||||
func (s *certState) tlscert() (*tls.Certificate, error) {
|
|
||||||
if s.key == nil {
|
|
||||||
return nil, errors.New("acme/autocert: missing signer")
|
|
||||||
}
|
|
||||||
if len(s.cert) == 0 {
|
|
||||||
return nil, errors.New("acme/autocert: missing certificate")
|
|
||||||
}
|
|
||||||
return &tls.Certificate{
|
|
||||||
PrivateKey: s.key,
|
|
||||||
Certificate: s.cert,
|
|
||||||
Leaf: s.leaf,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// certRequest creates a certificate request for the given common name cn
|
|
||||||
// and optional SANs.
|
|
||||||
func certRequest(key crypto.Signer, cn string, san ...string) ([]byte, error) {
|
|
||||||
req := &x509.CertificateRequest{
|
|
||||||
Subject: pkix.Name{CommonName: cn},
|
|
||||||
DNSNames: san,
|
|
||||||
}
|
|
||||||
return x509.CreateCertificateRequest(rand.Reader, req, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
|
|
||||||
// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
|
|
||||||
// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
|
|
||||||
//
|
|
||||||
// Inspired by parsePrivateKey in crypto/tls/tls.go.
|
|
||||||
func parsePrivateKey(der []byte) (crypto.Signer, error) {
|
|
||||||
if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
|
|
||||||
return key, nil
|
|
||||||
}
|
|
||||||
if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
|
|
||||||
switch key := key.(type) {
|
|
||||||
case *rsa.PrivateKey:
|
|
||||||
return key, nil
|
|
||||||
case *ecdsa.PrivateKey:
|
|
||||||
return key, nil
|
|
||||||
default:
|
|
||||||
return nil, errors.New("acme/autocert: unknown private key type in PKCS#8 wrapping")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if key, err := x509.ParseECPrivateKey(der); err == nil {
|
|
||||||
return key, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, errors.New("acme/autocert: failed to parse private key")
|
|
||||||
}
|
|
||||||
|
|
||||||
// validCert parses a cert chain provided as der argument and verifies the leaf, der[0],
|
|
||||||
// corresponds to the private key, as well as the domain match and expiration dates.
|
|
||||||
// It doesn't do any revocation checking.
|
|
||||||
//
|
|
||||||
// The returned value is the verified leaf cert.
|
|
||||||
func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) {
|
|
||||||
// parse public part(s)
|
|
||||||
var n int
|
|
||||||
for _, b := range der {
|
|
||||||
n += len(b)
|
|
||||||
}
|
|
||||||
pub := make([]byte, n)
|
|
||||||
n = 0
|
|
||||||
for _, b := range der {
|
|
||||||
n += copy(pub[n:], b)
|
|
||||||
}
|
|
||||||
x509Cert, err := x509.ParseCertificates(pub)
|
|
||||||
if len(x509Cert) == 0 {
|
|
||||||
return nil, errors.New("acme/autocert: no public key found")
|
|
||||||
}
|
|
||||||
// verify the leaf is not expired and matches the domain name
|
|
||||||
leaf = x509Cert[0]
|
|
||||||
now := timeNow()
|
|
||||||
if now.Before(leaf.NotBefore) {
|
|
||||||
return nil, errors.New("acme/autocert: certificate is not valid yet")
|
|
||||||
}
|
|
||||||
if now.After(leaf.NotAfter) {
|
|
||||||
return nil, errors.New("acme/autocert: expired certificate")
|
|
||||||
}
|
|
||||||
if err := leaf.VerifyHostname(domain); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// ensure the leaf corresponds to the private key
|
|
||||||
switch pub := leaf.PublicKey.(type) {
|
|
||||||
case *rsa.PublicKey:
|
|
||||||
prv, ok := key.(*rsa.PrivateKey)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("acme/autocert: private key type does not match public key type")
|
|
||||||
}
|
|
||||||
if pub.N.Cmp(prv.N) != 0 {
|
|
||||||
return nil, errors.New("acme/autocert: private key does not match public key")
|
|
||||||
}
|
|
||||||
case *ecdsa.PublicKey:
|
|
||||||
prv, ok := key.(*ecdsa.PrivateKey)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("acme/autocert: private key type does not match public key type")
|
|
||||||
}
|
|
||||||
if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {
|
|
||||||
return nil, errors.New("acme/autocert: private key does not match public key")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, errors.New("acme/autocert: unknown public key algorithm")
|
|
||||||
}
|
|
||||||
return leaf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func retryAfter(v string) time.Duration {
|
|
||||||
if i, err := strconv.Atoi(v); err == nil {
|
|
||||||
return time.Duration(i) * time.Second
|
|
||||||
}
|
|
||||||
if t, err := http.ParseTime(v); err == nil {
|
|
||||||
return t.Sub(timeNow())
|
|
||||||
}
|
|
||||||
return time.Second
|
|
||||||
}
|
|
||||||
|
|
||||||
type lockedMathRand struct {
|
|
||||||
sync.Mutex
|
|
||||||
rnd *mathrand.Rand
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *lockedMathRand) int63n(max int64) int64 {
|
|
||||||
r.Lock()
|
|
||||||
n := r.rnd.Int63n(max)
|
|
||||||
r.Unlock()
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// For easier testing.
|
|
||||||
var (
|
|
||||||
timeNow = time.Now
|
|
||||||
|
|
||||||
// Called when a state is removed.
|
|
||||||
testDidRemoveState = func(domain string) {}
|
|
||||||
)
|
|
606
vendor/golang.org/x/crypto/acme/autocert/autocert_test.go
generated
vendored
606
vendor/golang.org/x/crypto/acme/autocert/autocert_test.go
generated
vendored
|
@ -1,606 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package autocert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto"
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"html/template"
|
|
||||||
"io"
|
|
||||||
"math/big"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"reflect"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/acme"
|
|
||||||
)
|
|
||||||
|
|
||||||
var discoTmpl = template.Must(template.New("disco").Parse(`{
|
|
||||||
"new-reg": "{{.}}/new-reg",
|
|
||||||
"new-authz": "{{.}}/new-authz",
|
|
||||||
"new-cert": "{{.}}/new-cert"
|
|
||||||
}`))
|
|
||||||
|
|
||||||
var authzTmpl = template.Must(template.New("authz").Parse(`{
|
|
||||||
"status": "pending",
|
|
||||||
"challenges": [
|
|
||||||
{
|
|
||||||
"uri": "{{.}}/challenge/1",
|
|
||||||
"type": "tls-sni-01",
|
|
||||||
"token": "token-01"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"uri": "{{.}}/challenge/2",
|
|
||||||
"type": "tls-sni-02",
|
|
||||||
"token": "token-02"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}`))
|
|
||||||
|
|
||||||
type memCache struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
keyData map[string][]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *memCache) Get(ctx context.Context, key string) ([]byte, error) {
|
|
||||||
m.mu.Lock()
|
|
||||||
defer m.mu.Unlock()
|
|
||||||
|
|
||||||
v, ok := m.keyData[key]
|
|
||||||
if !ok {
|
|
||||||
return nil, ErrCacheMiss
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *memCache) Put(ctx context.Context, key string, data []byte) error {
|
|
||||||
m.mu.Lock()
|
|
||||||
defer m.mu.Unlock()
|
|
||||||
|
|
||||||
m.keyData[key] = data
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *memCache) Delete(ctx context.Context, key string) error {
|
|
||||||
m.mu.Lock()
|
|
||||||
defer m.mu.Unlock()
|
|
||||||
|
|
||||||
delete(m.keyData, key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMemCache() *memCache {
|
|
||||||
return &memCache{
|
|
||||||
keyData: make(map[string][]byte),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dummyCert(pub interface{}, san ...string) ([]byte, error) {
|
|
||||||
return dateDummyCert(pub, time.Now(), time.Now().Add(90*24*time.Hour), san...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dateDummyCert(pub interface{}, start, end time.Time, san ...string) ([]byte, error) {
|
|
||||||
// use EC key to run faster on 386
|
|
||||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
t := &x509.Certificate{
|
|
||||||
SerialNumber: big.NewInt(1),
|
|
||||||
NotBefore: start,
|
|
||||||
NotAfter: end,
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
KeyUsage: x509.KeyUsageKeyEncipherment,
|
|
||||||
DNSNames: san,
|
|
||||||
}
|
|
||||||
if pub == nil {
|
|
||||||
pub = &key.PublicKey
|
|
||||||
}
|
|
||||||
return x509.CreateCertificate(rand.Reader, t, t, pub, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodePayload(v interface{}, r io.Reader) error {
|
|
||||||
var req struct{ Payload string }
|
|
||||||
if err := json.NewDecoder(r).Decode(&req); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
payload, err := base64.RawURLEncoding.DecodeString(req.Payload)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return json.Unmarshal(payload, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCertificate(t *testing.T) {
|
|
||||||
man := &Manager{Prompt: AcceptTOS}
|
|
||||||
defer man.stopRenew()
|
|
||||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
|
||||||
testGetCertificate(t, man, "example.org", hello)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCertificate_trailingDot(t *testing.T) {
|
|
||||||
man := &Manager{Prompt: AcceptTOS}
|
|
||||||
defer man.stopRenew()
|
|
||||||
hello := &tls.ClientHelloInfo{ServerName: "example.org."}
|
|
||||||
testGetCertificate(t, man, "example.org", hello)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCertificate_ForceRSA(t *testing.T) {
|
|
||||||
man := &Manager{
|
|
||||||
Prompt: AcceptTOS,
|
|
||||||
Cache: newMemCache(),
|
|
||||||
ForceRSA: true,
|
|
||||||
}
|
|
||||||
defer man.stopRenew()
|
|
||||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
|
||||||
testGetCertificate(t, man, "example.org", hello)
|
|
||||||
|
|
||||||
cert, err := man.cacheGet(context.Background(), "example.org")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("man.cacheGet: %v", err)
|
|
||||||
}
|
|
||||||
if _, ok := cert.PrivateKey.(*rsa.PrivateKey); !ok {
|
|
||||||
t.Errorf("cert.PrivateKey is %T; want *rsa.PrivateKey", cert.PrivateKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCertificate_nilPrompt(t *testing.T) {
|
|
||||||
man := &Manager{}
|
|
||||||
defer man.stopRenew()
|
|
||||||
url, finish := startACMEServerStub(t, man, "example.org")
|
|
||||||
defer finish()
|
|
||||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
man.Client = &acme.Client{
|
|
||||||
Key: key,
|
|
||||||
DirectoryURL: url,
|
|
||||||
}
|
|
||||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
|
||||||
if _, err := man.GetCertificate(hello); err == nil {
|
|
||||||
t.Error("got certificate for example.org; wanted error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCertificate_expiredCache(t *testing.T) {
|
|
||||||
// Make an expired cert and cache it.
|
|
||||||
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
tmpl := &x509.Certificate{
|
|
||||||
SerialNumber: big.NewInt(1),
|
|
||||||
Subject: pkix.Name{CommonName: "example.org"},
|
|
||||||
NotAfter: time.Now(),
|
|
||||||
}
|
|
||||||
pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
tlscert := &tls.Certificate{
|
|
||||||
Certificate: [][]byte{pub},
|
|
||||||
PrivateKey: pk,
|
|
||||||
}
|
|
||||||
|
|
||||||
man := &Manager{Prompt: AcceptTOS, Cache: newMemCache()}
|
|
||||||
defer man.stopRenew()
|
|
||||||
if err := man.cachePut(context.Background(), "example.org", tlscert); err != nil {
|
|
||||||
t.Fatalf("man.cachePut: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The expired cached cert should trigger a new cert issuance
|
|
||||||
// and return without an error.
|
|
||||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
|
||||||
testGetCertificate(t, man, "example.org", hello)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCertificate_failedAttempt(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
}))
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
const example = "example.org"
|
|
||||||
d := createCertRetryAfter
|
|
||||||
f := testDidRemoveState
|
|
||||||
defer func() {
|
|
||||||
createCertRetryAfter = d
|
|
||||||
testDidRemoveState = f
|
|
||||||
}()
|
|
||||||
createCertRetryAfter = 0
|
|
||||||
done := make(chan struct{})
|
|
||||||
testDidRemoveState = func(domain string) {
|
|
||||||
if domain != example {
|
|
||||||
t.Errorf("testDidRemoveState: domain = %q; want %q", domain, example)
|
|
||||||
}
|
|
||||||
close(done)
|
|
||||||
}
|
|
||||||
|
|
||||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
man := &Manager{
|
|
||||||
Prompt: AcceptTOS,
|
|
||||||
Client: &acme.Client{
|
|
||||||
Key: key,
|
|
||||||
DirectoryURL: ts.URL,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
defer man.stopRenew()
|
|
||||||
hello := &tls.ClientHelloInfo{ServerName: example}
|
|
||||||
if _, err := man.GetCertificate(hello); err == nil {
|
|
||||||
t.Error("GetCertificate: err is nil")
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case <-time.After(5 * time.Second):
|
|
||||||
t.Errorf("took too long to remove the %q state", example)
|
|
||||||
case <-done:
|
|
||||||
man.stateMu.Lock()
|
|
||||||
defer man.stateMu.Unlock()
|
|
||||||
if v, exist := man.state[example]; exist {
|
|
||||||
t.Errorf("state exists for %q: %+v", example, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// startACMEServerStub runs an ACME server
|
|
||||||
// The domain argument is the expected domain name of a certificate request.
|
|
||||||
func startACMEServerStub(t *testing.T, man *Manager, domain string) (url string, finish func()) {
|
|
||||||
// echo token-02 | shasum -a 256
|
|
||||||
// then divide result in 2 parts separated by dot
|
|
||||||
tokenCertName := "4e8eb87631187e9ff2153b56b13a4dec.13a35d002e485d60ff37354b32f665d9.token.acme.invalid"
|
|
||||||
verifyTokenCert := func() {
|
|
||||||
hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
|
|
||||||
_, err := man.GetCertificate(hello)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("verifyTokenCert: GetCertificate(%q): %v", tokenCertName, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ACME CA server stub
|
|
||||||
var ca *httptest.Server
|
|
||||||
ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("replay-nonce", "nonce")
|
|
||||||
if r.Method == "HEAD" {
|
|
||||||
// a nonce request
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch r.URL.Path {
|
|
||||||
// discovery
|
|
||||||
case "/":
|
|
||||||
if err := discoTmpl.Execute(w, ca.URL); err != nil {
|
|
||||||
t.Errorf("discoTmpl: %v", err)
|
|
||||||
}
|
|
||||||
// client key registration
|
|
||||||
case "/new-reg":
|
|
||||||
w.Write([]byte("{}"))
|
|
||||||
// domain authorization
|
|
||||||
case "/new-authz":
|
|
||||||
w.Header().Set("location", ca.URL+"/authz/1")
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
if err := authzTmpl.Execute(w, ca.URL); err != nil {
|
|
||||||
t.Errorf("authzTmpl: %v", err)
|
|
||||||
}
|
|
||||||
// accept tls-sni-02 challenge
|
|
||||||
case "/challenge/2":
|
|
||||||
verifyTokenCert()
|
|
||||||
w.Write([]byte("{}"))
|
|
||||||
// authorization status
|
|
||||||
case "/authz/1":
|
|
||||||
w.Write([]byte(`{"status": "valid"}`))
|
|
||||||
// cert request
|
|
||||||
case "/new-cert":
|
|
||||||
var req struct {
|
|
||||||
CSR string `json:"csr"`
|
|
||||||
}
|
|
||||||
decodePayload(&req, r.Body)
|
|
||||||
b, _ := base64.RawURLEncoding.DecodeString(req.CSR)
|
|
||||||
csr, err := x509.ParseCertificateRequest(b)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("new-cert: CSR: %v", err)
|
|
||||||
}
|
|
||||||
if csr.Subject.CommonName != domain {
|
|
||||||
t.Errorf("CommonName in CSR = %q; want %q", csr.Subject.CommonName, domain)
|
|
||||||
}
|
|
||||||
der, err := dummyCert(csr.PublicKey, domain)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("new-cert: dummyCert: %v", err)
|
|
||||||
}
|
|
||||||
chainUp := fmt.Sprintf("<%s/ca-cert>; rel=up", ca.URL)
|
|
||||||
w.Header().Set("link", chainUp)
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
w.Write(der)
|
|
||||||
// CA chain cert
|
|
||||||
case "/ca-cert":
|
|
||||||
der, err := dummyCert(nil, "ca")
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("ca-cert: dummyCert: %v", err)
|
|
||||||
}
|
|
||||||
w.Write(der)
|
|
||||||
default:
|
|
||||||
t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
finish = func() {
|
|
||||||
ca.Close()
|
|
||||||
|
|
||||||
// make sure token cert was removed
|
|
||||||
cancel := make(chan struct{})
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
defer close(done)
|
|
||||||
tick := time.NewTicker(100 * time.Millisecond)
|
|
||||||
defer tick.Stop()
|
|
||||||
for {
|
|
||||||
hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
|
|
||||||
if _, err := man.GetCertificate(hello); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case <-tick.C:
|
|
||||||
case <-cancel:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
case <-time.After(5 * time.Second):
|
|
||||||
close(cancel)
|
|
||||||
t.Error("token cert was not removed")
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ca.URL, finish
|
|
||||||
}
|
|
||||||
|
|
||||||
// tests man.GetCertificate flow using the provided hello argument.
|
|
||||||
// The domain argument is the expected domain name of a certificate request.
|
|
||||||
func testGetCertificate(t *testing.T, man *Manager, domain string, hello *tls.ClientHelloInfo) {
|
|
||||||
url, finish := startACMEServerStub(t, man, domain)
|
|
||||||
defer finish()
|
|
||||||
|
|
||||||
// use EC key to run faster on 386
|
|
||||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
man.Client = &acme.Client{
|
|
||||||
Key: key,
|
|
||||||
DirectoryURL: url,
|
|
||||||
}
|
|
||||||
|
|
||||||
// simulate tls.Config.GetCertificate
|
|
||||||
var tlscert *tls.Certificate
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
tlscert, err = man.GetCertificate(hello)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case <-time.After(time.Minute):
|
|
||||||
t.Fatal("man.GetCertificate took too long to return")
|
|
||||||
case <-done:
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("man.GetCertificate: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify the tlscert is the same we responded with from the CA stub
|
|
||||||
if len(tlscert.Certificate) == 0 {
|
|
||||||
t.Fatal("len(tlscert.Certificate) is 0")
|
|
||||||
}
|
|
||||||
cert, err := x509.ParseCertificate(tlscert.Certificate[0])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("x509.ParseCertificate: %v", err)
|
|
||||||
}
|
|
||||||
if len(cert.DNSNames) == 0 || cert.DNSNames[0] != domain {
|
|
||||||
t.Errorf("cert.DNSNames = %v; want %q", cert.DNSNames, domain)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccountKeyCache(t *testing.T) {
|
|
||||||
m := Manager{Cache: newMemCache()}
|
|
||||||
ctx := context.Background()
|
|
||||||
k1, err := m.accountKey(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
k2, err := m.accountKey(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(k1, k2) {
|
|
||||||
t.Errorf("account keys don't match: k1 = %#v; k2 = %#v", k1, k2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCache(t *testing.T) {
|
|
||||||
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
tmpl := &x509.Certificate{
|
|
||||||
SerialNumber: big.NewInt(1),
|
|
||||||
Subject: pkix.Name{CommonName: "example.org"},
|
|
||||||
NotAfter: time.Now().Add(time.Hour),
|
|
||||||
}
|
|
||||||
pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &privKey.PublicKey, privKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
tlscert := &tls.Certificate{
|
|
||||||
Certificate: [][]byte{pub},
|
|
||||||
PrivateKey: privKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
man := &Manager{Cache: newMemCache()}
|
|
||||||
defer man.stopRenew()
|
|
||||||
ctx := context.Background()
|
|
||||||
if err := man.cachePut(ctx, "example.org", tlscert); err != nil {
|
|
||||||
t.Fatalf("man.cachePut: %v", err)
|
|
||||||
}
|
|
||||||
res, err := man.cacheGet(ctx, "example.org")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("man.cacheGet: %v", err)
|
|
||||||
}
|
|
||||||
if res == nil {
|
|
||||||
t.Fatal("res is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHostWhitelist(t *testing.T) {
|
|
||||||
policy := HostWhitelist("example.com", "example.org", "*.example.net")
|
|
||||||
tt := []struct {
|
|
||||||
host string
|
|
||||||
allow bool
|
|
||||||
}{
|
|
||||||
{"example.com", true},
|
|
||||||
{"example.org", true},
|
|
||||||
{"one.example.com", false},
|
|
||||||
{"two.example.org", false},
|
|
||||||
{"three.example.net", false},
|
|
||||||
{"dummy", false},
|
|
||||||
}
|
|
||||||
for i, test := range tt {
|
|
||||||
err := policy(nil, test.host)
|
|
||||||
if err != nil && test.allow {
|
|
||||||
t.Errorf("%d: policy(%q): %v; want nil", i, test.host, err)
|
|
||||||
}
|
|
||||||
if err == nil && !test.allow {
|
|
||||||
t.Errorf("%d: policy(%q): nil; want an error", i, test.host)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidCert(t *testing.T) {
|
|
||||||
key1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
key2, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
key3, err := rsa.GenerateKey(rand.Reader, 512)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
cert1, err := dummyCert(key1.Public(), "example.org")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
cert2, err := dummyCert(key2.Public(), "example.org")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
cert3, err := dummyCert(key3.Public(), "example.org")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
now := time.Now()
|
|
||||||
early, err := dateDummyCert(key1.Public(), now.Add(time.Hour), now.Add(2*time.Hour), "example.org")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
expired, err := dateDummyCert(key1.Public(), now.Add(-2*time.Hour), now.Add(-time.Hour), "example.org")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tt := []struct {
|
|
||||||
domain string
|
|
||||||
key crypto.Signer
|
|
||||||
cert [][]byte
|
|
||||||
ok bool
|
|
||||||
}{
|
|
||||||
{"example.org", key1, [][]byte{cert1}, true},
|
|
||||||
{"example.org", key3, [][]byte{cert3}, true},
|
|
||||||
{"example.org", key1, [][]byte{cert1, cert2, cert3}, true},
|
|
||||||
{"example.org", key1, [][]byte{cert1, {1}}, false},
|
|
||||||
{"example.org", key1, [][]byte{{1}}, false},
|
|
||||||
{"example.org", key1, [][]byte{cert2}, false},
|
|
||||||
{"example.org", key2, [][]byte{cert1}, false},
|
|
||||||
{"example.org", key1, [][]byte{cert3}, false},
|
|
||||||
{"example.org", key3, [][]byte{cert1}, false},
|
|
||||||
{"example.net", key1, [][]byte{cert1}, false},
|
|
||||||
{"example.org", key1, [][]byte{early}, false},
|
|
||||||
{"example.org", key1, [][]byte{expired}, false},
|
|
||||||
}
|
|
||||||
for i, test := range tt {
|
|
||||||
leaf, err := validCert(test.domain, test.cert, test.key)
|
|
||||||
if err != nil && test.ok {
|
|
||||||
t.Errorf("%d: err = %v", i, err)
|
|
||||||
}
|
|
||||||
if err == nil && !test.ok {
|
|
||||||
t.Errorf("%d: err is nil", i)
|
|
||||||
}
|
|
||||||
if err == nil && test.ok && leaf == nil {
|
|
||||||
t.Errorf("%d: leaf is nil", i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type cacheGetFunc func(ctx context.Context, key string) ([]byte, error)
|
|
||||||
|
|
||||||
func (f cacheGetFunc) Get(ctx context.Context, key string) ([]byte, error) {
|
|
||||||
return f(ctx, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f cacheGetFunc) Put(ctx context.Context, key string, data []byte) error {
|
|
||||||
return fmt.Errorf("unsupported Put of %q = %q", key, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f cacheGetFunc) Delete(ctx context.Context, key string) error {
|
|
||||||
return fmt.Errorf("unsupported Delete of %q", key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestManagerGetCertificateBogusSNI(t *testing.T) {
|
|
||||||
m := Manager{
|
|
||||||
Prompt: AcceptTOS,
|
|
||||||
Cache: cacheGetFunc(func(ctx context.Context, key string) ([]byte, error) {
|
|
||||||
return nil, fmt.Errorf("cache.Get of %s", key)
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
wantErr string
|
|
||||||
}{
|
|
||||||
{"foo.com", "cache.Get of foo.com"},
|
|
||||||
{"foo.com.", "cache.Get of foo.com"},
|
|
||||||
{`a\b.com`, "acme/autocert: server name contains invalid character"},
|
|
||||||
{`a/b.com`, "acme/autocert: server name contains invalid character"},
|
|
||||||
{"", "acme/autocert: missing server name"},
|
|
||||||
{"foo", "acme/autocert: server name component count invalid"},
|
|
||||||
{".foo", "acme/autocert: server name component count invalid"},
|
|
||||||
{"foo.", "acme/autocert: server name component count invalid"},
|
|
||||||
{"fo.o", "cache.Get of fo.o"},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
_, err := m.GetCertificate(&tls.ClientHelloInfo{ServerName: tt.name})
|
|
||||||
got := fmt.Sprint(err)
|
|
||||||
if got != tt.wantErr {
|
|
||||||
t.Errorf("GetCertificate(SNI = %q) = %q; want %q", tt.name, got, tt.wantErr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
130
vendor/golang.org/x/crypto/acme/autocert/cache.go
generated
vendored
130
vendor/golang.org/x/crypto/acme/autocert/cache.go
generated
vendored
|
@ -1,130 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package autocert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrCacheMiss is returned when a certificate is not found in cache.
|
|
||||||
var ErrCacheMiss = errors.New("acme/autocert: certificate cache miss")
|
|
||||||
|
|
||||||
// Cache is used by Manager to store and retrieve previously obtained certificates
|
|
||||||
// as opaque data.
|
|
||||||
//
|
|
||||||
// The key argument of the methods refers to a domain name but need not be an FQDN.
|
|
||||||
// Cache implementations should not rely on the key naming pattern.
|
|
||||||
type Cache interface {
|
|
||||||
// Get returns a certificate data for the specified key.
|
|
||||||
// If there's no such key, Get returns ErrCacheMiss.
|
|
||||||
Get(ctx context.Context, key string) ([]byte, error)
|
|
||||||
|
|
||||||
// Put stores the data in the cache under the specified key.
|
|
||||||
// Underlying implementations may use any data storage format,
|
|
||||||
// as long as the reverse operation, Get, results in the original data.
|
|
||||||
Put(ctx context.Context, key string, data []byte) error
|
|
||||||
|
|
||||||
// Delete removes a certificate data from the cache under the specified key.
|
|
||||||
// If there's no such key in the cache, Delete returns nil.
|
|
||||||
Delete(ctx context.Context, key string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// DirCache implements Cache using a directory on the local filesystem.
|
|
||||||
// If the directory does not exist, it will be created with 0700 permissions.
|
|
||||||
type DirCache string
|
|
||||||
|
|
||||||
// Get reads a certificate data from the specified file name.
|
|
||||||
func (d DirCache) Get(ctx context.Context, name string) ([]byte, error) {
|
|
||||||
name = filepath.Join(string(d), name)
|
|
||||||
var (
|
|
||||||
data []byte
|
|
||||||
err error
|
|
||||||
done = make(chan struct{})
|
|
||||||
)
|
|
||||||
go func() {
|
|
||||||
data, err = ioutil.ReadFile(name)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return nil, ctx.Err()
|
|
||||||
case <-done:
|
|
||||||
}
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return nil, ErrCacheMiss
|
|
||||||
}
|
|
||||||
return data, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put writes the certificate data to the specified file name.
|
|
||||||
// The file will be created with 0600 permissions.
|
|
||||||
func (d DirCache) Put(ctx context.Context, name string, data []byte) error {
|
|
||||||
if err := os.MkdirAll(string(d), 0700); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
var err error
|
|
||||||
go func() {
|
|
||||||
defer close(done)
|
|
||||||
var tmp string
|
|
||||||
if tmp, err = d.writeTempFile(name, data); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
// Don't overwrite the file if the context was canceled.
|
|
||||||
default:
|
|
||||||
newName := filepath.Join(string(d), name)
|
|
||||||
err = os.Rename(tmp, newName)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
case <-done:
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete removes the specified file name.
|
|
||||||
func (d DirCache) Delete(ctx context.Context, name string) error {
|
|
||||||
name = filepath.Join(string(d), name)
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
done = make(chan struct{})
|
|
||||||
)
|
|
||||||
go func() {
|
|
||||||
err = os.Remove(name)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
case <-done:
|
|
||||||
}
|
|
||||||
if err != nil && !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeTempFile writes b to a temporary file, closes the file and returns its path.
|
|
||||||
func (d DirCache) writeTempFile(prefix string, b []byte) (string, error) {
|
|
||||||
// TempFile uses 0600 permissions
|
|
||||||
f, err := ioutil.TempFile(string(d), prefix)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if _, err := f.Write(b); err != nil {
|
|
||||||
f.Close()
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return f.Name(), f.Close()
|
|
||||||
}
|
|
57
vendor/golang.org/x/crypto/acme/autocert/cache_test.go
generated
vendored
57
vendor/golang.org/x/crypto/acme/autocert/cache_test.go
generated
vendored
|
@ -1,57 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package autocert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// make sure DirCache satisfies Cache interface
|
|
||||||
var _ Cache = DirCache("/")
|
|
||||||
|
|
||||||
func TestDirCache(t *testing.T) {
|
|
||||||
dir, err := ioutil.TempDir("", "autocert")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
dir = filepath.Join(dir, "certs") // a nonexistent dir
|
|
||||||
cache := DirCache(dir)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
// test cache miss
|
|
||||||
if _, err := cache.Get(ctx, "nonexistent"); err != ErrCacheMiss {
|
|
||||||
t.Errorf("get: %v; want ErrCacheMiss", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// test put/get
|
|
||||||
b1 := []byte{1}
|
|
||||||
if err := cache.Put(ctx, "dummy", b1); err != nil {
|
|
||||||
t.Fatalf("put: %v", err)
|
|
||||||
}
|
|
||||||
b2, err := cache.Get(ctx, "dummy")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("get: %v", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(b1, b2) {
|
|
||||||
t.Errorf("b1 = %v; want %v", b1, b2)
|
|
||||||
}
|
|
||||||
name := filepath.Join(dir, "dummy")
|
|
||||||
if _, err := os.Stat(name); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// test delete
|
|
||||||
if err := cache.Delete(ctx, "dummy"); err != nil {
|
|
||||||
t.Fatalf("delete: %v", err)
|
|
||||||
}
|
|
||||||
if _, err := cache.Get(ctx, "dummy"); err != ErrCacheMiss {
|
|
||||||
t.Errorf("get: %v; want ErrCacheMiss", err)
|
|
||||||
}
|
|
||||||
}
|
|
34
vendor/golang.org/x/crypto/acme/autocert/example_test.go
generated
vendored
34
vendor/golang.org/x/crypto/acme/autocert/example_test.go
generated
vendored
|
@ -1,34 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package autocert_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/acme/autocert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleNewListener() {
|
|
||||||
mux := http.NewServeMux()
|
|
||||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fmt.Fprintf(w, "Hello, TLS user! Your config: %+v", r.TLS)
|
|
||||||
})
|
|
||||||
log.Fatal(http.Serve(autocert.NewListener("example.com"), mux))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleManager() {
|
|
||||||
m := autocert.Manager{
|
|
||||||
Prompt: autocert.AcceptTOS,
|
|
||||||
HostPolicy: autocert.HostWhitelist("example.org"),
|
|
||||||
}
|
|
||||||
s := &http.Server{
|
|
||||||
Addr: ":https",
|
|
||||||
TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
|
|
||||||
}
|
|
||||||
s.ListenAndServeTLS("", "")
|
|
||||||
}
|
|
160
vendor/golang.org/x/crypto/acme/autocert/listener.go
generated
vendored
160
vendor/golang.org/x/crypto/acme/autocert/listener.go
generated
vendored
|
@ -1,160 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package autocert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/tls"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewListener returns a net.Listener that listens on the standard TLS
|
|
||||||
// port (443) on all interfaces and returns *tls.Conn connections with
|
|
||||||
// LetsEncrypt certificates for the provided domain or domains.
|
|
||||||
//
|
|
||||||
// It enables one-line HTTPS servers:
|
|
||||||
//
|
|
||||||
// log.Fatal(http.Serve(autocert.NewListener("example.com"), handler))
|
|
||||||
//
|
|
||||||
// NewListener is a convenience function for a common configuration.
|
|
||||||
// More complex or custom configurations can use the autocert.Manager
|
|
||||||
// type instead.
|
|
||||||
//
|
|
||||||
// Use of this function implies acceptance of the LetsEncrypt Terms of
|
|
||||||
// Service. If domains is not empty, the provided domains are passed
|
|
||||||
// to HostWhitelist. If domains is empty, the listener will do
|
|
||||||
// LetsEncrypt challenges for any requested domain, which is not
|
|
||||||
// recommended.
|
|
||||||
//
|
|
||||||
// Certificates are cached in a "golang-autocert" directory under an
|
|
||||||
// operating system-specific cache or temp directory. This may not
|
|
||||||
// be suitable for servers spanning multiple machines.
|
|
||||||
//
|
|
||||||
// The returned listener uses a *tls.Config that enables HTTP/2, and
|
|
||||||
// should only be used with servers that support HTTP/2.
|
|
||||||
//
|
|
||||||
// The returned Listener also enables TCP keep-alives on the accepted
|
|
||||||
// connections. The returned *tls.Conn are returned before their TLS
|
|
||||||
// handshake has completed.
|
|
||||||
func NewListener(domains ...string) net.Listener {
|
|
||||||
m := &Manager{
|
|
||||||
Prompt: AcceptTOS,
|
|
||||||
}
|
|
||||||
if len(domains) > 0 {
|
|
||||||
m.HostPolicy = HostWhitelist(domains...)
|
|
||||||
}
|
|
||||||
dir := cacheDir()
|
|
||||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
|
||||||
log.Printf("warning: autocert.NewListener not using a cache: %v", err)
|
|
||||||
} else {
|
|
||||||
m.Cache = DirCache(dir)
|
|
||||||
}
|
|
||||||
return m.Listener()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listener listens on the standard TLS port (443) on all interfaces
|
|
||||||
// and returns a net.Listener returning *tls.Conn connections.
|
|
||||||
//
|
|
||||||
// The returned listener uses a *tls.Config that enables HTTP/2, and
|
|
||||||
// should only be used with servers that support HTTP/2.
|
|
||||||
//
|
|
||||||
// The returned Listener also enables TCP keep-alives on the accepted
|
|
||||||
// connections. The returned *tls.Conn are returned before their TLS
|
|
||||||
// handshake has completed.
|
|
||||||
//
|
|
||||||
// Unlike NewListener, it is the caller's responsibility to initialize
|
|
||||||
// the Manager m's Prompt, Cache, HostPolicy, and other desired options.
|
|
||||||
func (m *Manager) Listener() net.Listener {
|
|
||||||
ln := &listener{
|
|
||||||
m: m,
|
|
||||||
conf: &tls.Config{
|
|
||||||
GetCertificate: m.GetCertificate, // bonus: panic on nil m
|
|
||||||
NextProtos: []string{"h2", "http/1.1"}, // Enable HTTP/2
|
|
||||||
},
|
|
||||||
}
|
|
||||||
ln.tcpListener, ln.tcpListenErr = net.Listen("tcp", ":443")
|
|
||||||
return ln
|
|
||||||
}
|
|
||||||
|
|
||||||
type listener struct {
|
|
||||||
m *Manager
|
|
||||||
conf *tls.Config
|
|
||||||
|
|
||||||
tcpListener net.Listener
|
|
||||||
tcpListenErr error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ln *listener) Accept() (net.Conn, error) {
|
|
||||||
if ln.tcpListenErr != nil {
|
|
||||||
return nil, ln.tcpListenErr
|
|
||||||
}
|
|
||||||
conn, err := ln.tcpListener.Accept()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
tcpConn := conn.(*net.TCPConn)
|
|
||||||
|
|
||||||
// Because Listener is a convenience function, help out with
|
|
||||||
// this too. This is not possible for the caller to set once
|
|
||||||
// we return a *tcp.Conn wrapping an inaccessible net.Conn.
|
|
||||||
// If callers don't want this, they can do things the manual
|
|
||||||
// way and tweak as needed. But this is what net/http does
|
|
||||||
// itself, so copy that. If net/http changes, we can change
|
|
||||||
// here too.
|
|
||||||
tcpConn.SetKeepAlive(true)
|
|
||||||
tcpConn.SetKeepAlivePeriod(3 * time.Minute)
|
|
||||||
|
|
||||||
return tls.Server(tcpConn, ln.conf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ln *listener) Addr() net.Addr {
|
|
||||||
if ln.tcpListener != nil {
|
|
||||||
return ln.tcpListener.Addr()
|
|
||||||
}
|
|
||||||
// net.Listen failed. Return something non-nil in case callers
|
|
||||||
// call Addr before Accept:
|
|
||||||
return &net.TCPAddr{IP: net.IP{0, 0, 0, 0}, Port: 443}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ln *listener) Close() error {
|
|
||||||
if ln.tcpListenErr != nil {
|
|
||||||
return ln.tcpListenErr
|
|
||||||
}
|
|
||||||
return ln.tcpListener.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func homeDir() string {
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
return os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
|
|
||||||
}
|
|
||||||
if h := os.Getenv("HOME"); h != "" {
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
return "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
func cacheDir() string {
|
|
||||||
const base = "golang-autocert"
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
return filepath.Join(homeDir(), "Library", "Caches", base)
|
|
||||||
case "windows":
|
|
||||||
for _, ev := range []string{"APPDATA", "CSIDL_APPDATA", "TEMP", "TMP"} {
|
|
||||||
if v := os.Getenv(ev); v != "" {
|
|
||||||
return filepath.Join(v, base)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Worst case:
|
|
||||||
return filepath.Join(homeDir(), base)
|
|
||||||
}
|
|
||||||
if xdg := os.Getenv("XDG_CACHE_HOME"); xdg != "" {
|
|
||||||
return filepath.Join(xdg, base)
|
|
||||||
}
|
|
||||||
return filepath.Join(homeDir(), ".cache", base)
|
|
||||||
}
|
|
124
vendor/golang.org/x/crypto/acme/autocert/renewal.go
generated
vendored
124
vendor/golang.org/x/crypto/acme/autocert/renewal.go
generated
vendored
|
@ -1,124 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package autocert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// renewJitter is the maximum deviation from Manager.RenewBefore.
|
|
||||||
const renewJitter = time.Hour
|
|
||||||
|
|
||||||
// domainRenewal tracks the state used by the periodic timers
|
|
||||||
// renewing a single domain's cert.
|
|
||||||
type domainRenewal struct {
|
|
||||||
m *Manager
|
|
||||||
domain string
|
|
||||||
key crypto.Signer
|
|
||||||
|
|
||||||
timerMu sync.Mutex
|
|
||||||
timer *time.Timer
|
|
||||||
}
|
|
||||||
|
|
||||||
// start starts a cert renewal timer at the time
|
|
||||||
// defined by the certificate expiration time exp.
|
|
||||||
//
|
|
||||||
// If the timer is already started, calling start is a noop.
|
|
||||||
func (dr *domainRenewal) start(exp time.Time) {
|
|
||||||
dr.timerMu.Lock()
|
|
||||||
defer dr.timerMu.Unlock()
|
|
||||||
if dr.timer != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dr.timer = time.AfterFunc(dr.next(exp), dr.renew)
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop stops the cert renewal timer.
|
|
||||||
// If the timer is already stopped, calling stop is a noop.
|
|
||||||
func (dr *domainRenewal) stop() {
|
|
||||||
dr.timerMu.Lock()
|
|
||||||
defer dr.timerMu.Unlock()
|
|
||||||
if dr.timer == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dr.timer.Stop()
|
|
||||||
dr.timer = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// renew is called periodically by a timer.
|
|
||||||
// The first renew call is kicked off by dr.start.
|
|
||||||
func (dr *domainRenewal) renew() {
|
|
||||||
dr.timerMu.Lock()
|
|
||||||
defer dr.timerMu.Unlock()
|
|
||||||
if dr.timer == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
|
||||||
defer cancel()
|
|
||||||
// TODO: rotate dr.key at some point?
|
|
||||||
next, err := dr.do(ctx)
|
|
||||||
if err != nil {
|
|
||||||
next = renewJitter / 2
|
|
||||||
next += time.Duration(pseudoRand.int63n(int64(next)))
|
|
||||||
}
|
|
||||||
dr.timer = time.AfterFunc(next, dr.renew)
|
|
||||||
testDidRenewLoop(next, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// do is similar to Manager.createCert but it doesn't lock a Manager.state item.
|
|
||||||
// Instead, it requests a new certificate independently and, upon success,
|
|
||||||
// replaces dr.m.state item with a new one and updates cache for the given domain.
|
|
||||||
//
|
|
||||||
// It may return immediately if the expiration date of the currently cached cert
|
|
||||||
// is far enough in the future.
|
|
||||||
//
|
|
||||||
// The returned value is a time interval after which the renewal should occur again.
|
|
||||||
func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
|
|
||||||
// a race is likely unavoidable in a distributed environment
|
|
||||||
// but we try nonetheless
|
|
||||||
if tlscert, err := dr.m.cacheGet(ctx, dr.domain); err == nil {
|
|
||||||
next := dr.next(tlscert.Leaf.NotAfter)
|
|
||||||
if next > dr.m.renewBefore()+renewJitter {
|
|
||||||
return next, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
der, leaf, err := dr.m.authorizedCert(ctx, dr.key, dr.domain)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
state := &certState{
|
|
||||||
key: dr.key,
|
|
||||||
cert: der,
|
|
||||||
leaf: leaf,
|
|
||||||
}
|
|
||||||
tlscert, err := state.tlscert()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
dr.m.cachePut(ctx, dr.domain, tlscert)
|
|
||||||
dr.m.stateMu.Lock()
|
|
||||||
defer dr.m.stateMu.Unlock()
|
|
||||||
// m.state is guaranteed to be non-nil at this point
|
|
||||||
dr.m.state[dr.domain] = state
|
|
||||||
return dr.next(leaf.NotAfter), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dr *domainRenewal) next(expiry time.Time) time.Duration {
|
|
||||||
d := expiry.Sub(timeNow()) - dr.m.renewBefore()
|
|
||||||
// add a bit of randomness to renew deadline
|
|
||||||
n := pseudoRand.int63n(int64(renewJitter))
|
|
||||||
d -= time.Duration(n)
|
|
||||||
if d < 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
var testDidRenewLoop = func(next time.Duration, err error) {}
|
|
191
vendor/golang.org/x/crypto/acme/autocert/renewal_test.go
generated
vendored
191
vendor/golang.org/x/crypto/acme/autocert/renewal_test.go
generated
vendored
|
@ -1,191 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package autocert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/acme"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestRenewalNext(t *testing.T) {
|
|
||||||
now := time.Now()
|
|
||||||
timeNow = func() time.Time { return now }
|
|
||||||
defer func() { timeNow = time.Now }()
|
|
||||||
|
|
||||||
man := &Manager{RenewBefore: 7 * 24 * time.Hour}
|
|
||||||
defer man.stopRenew()
|
|
||||||
tt := []struct {
|
|
||||||
expiry time.Time
|
|
||||||
min, max time.Duration
|
|
||||||
}{
|
|
||||||
{now.Add(90 * 24 * time.Hour), 83*24*time.Hour - renewJitter, 83 * 24 * time.Hour},
|
|
||||||
{now.Add(time.Hour), 0, 1},
|
|
||||||
{now, 0, 1},
|
|
||||||
{now.Add(-time.Hour), 0, 1},
|
|
||||||
}
|
|
||||||
|
|
||||||
dr := &domainRenewal{m: man}
|
|
||||||
for i, test := range tt {
|
|
||||||
next := dr.next(test.expiry)
|
|
||||||
if next < test.min || test.max < next {
|
|
||||||
t.Errorf("%d: next = %v; want between %v and %v", i, next, test.min, test.max)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRenewFromCache(t *testing.T) {
|
|
||||||
const domain = "example.org"
|
|
||||||
|
|
||||||
// ACME CA server stub
|
|
||||||
var ca *httptest.Server
|
|
||||||
ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("replay-nonce", "nonce")
|
|
||||||
if r.Method == "HEAD" {
|
|
||||||
// a nonce request
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch r.URL.Path {
|
|
||||||
// discovery
|
|
||||||
case "/":
|
|
||||||
if err := discoTmpl.Execute(w, ca.URL); err != nil {
|
|
||||||
t.Fatalf("discoTmpl: %v", err)
|
|
||||||
}
|
|
||||||
// client key registration
|
|
||||||
case "/new-reg":
|
|
||||||
w.Write([]byte("{}"))
|
|
||||||
// domain authorization
|
|
||||||
case "/new-authz":
|
|
||||||
w.Header().Set("location", ca.URL+"/authz/1")
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
w.Write([]byte(`{"status": "valid"}`))
|
|
||||||
// cert request
|
|
||||||
case "/new-cert":
|
|
||||||
var req struct {
|
|
||||||
CSR string `json:"csr"`
|
|
||||||
}
|
|
||||||
decodePayload(&req, r.Body)
|
|
||||||
b, _ := base64.RawURLEncoding.DecodeString(req.CSR)
|
|
||||||
csr, err := x509.ParseCertificateRequest(b)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("new-cert: CSR: %v", err)
|
|
||||||
}
|
|
||||||
der, err := dummyCert(csr.PublicKey, domain)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("new-cert: dummyCert: %v", err)
|
|
||||||
}
|
|
||||||
chainUp := fmt.Sprintf("<%s/ca-cert>; rel=up", ca.URL)
|
|
||||||
w.Header().Set("link", chainUp)
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
w.Write(der)
|
|
||||||
// CA chain cert
|
|
||||||
case "/ca-cert":
|
|
||||||
der, err := dummyCert(nil, "ca")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ca-cert: dummyCert: %v", err)
|
|
||||||
}
|
|
||||||
w.Write(der)
|
|
||||||
default:
|
|
||||||
t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
defer ca.Close()
|
|
||||||
|
|
||||||
// use EC key to run faster on 386
|
|
||||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
man := &Manager{
|
|
||||||
Prompt: AcceptTOS,
|
|
||||||
Cache: newMemCache(),
|
|
||||||
RenewBefore: 24 * time.Hour,
|
|
||||||
Client: &acme.Client{
|
|
||||||
Key: key,
|
|
||||||
DirectoryURL: ca.URL,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
defer man.stopRenew()
|
|
||||||
|
|
||||||
// cache an almost expired cert
|
|
||||||
now := time.Now()
|
|
||||||
cert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), domain)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
tlscert := &tls.Certificate{PrivateKey: key, Certificate: [][]byte{cert}}
|
|
||||||
if err := man.cachePut(context.Background(), domain, tlscert); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// veriy the renewal happened
|
|
||||||
defer func() {
|
|
||||||
testDidRenewLoop = func(next time.Duration, err error) {}
|
|
||||||
}()
|
|
||||||
done := make(chan struct{})
|
|
||||||
testDidRenewLoop = func(next time.Duration, err error) {
|
|
||||||
defer close(done)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("testDidRenewLoop: %v", err)
|
|
||||||
}
|
|
||||||
// Next should be about 90 days:
|
|
||||||
// dummyCert creates 90days expiry + account for man.RenewBefore.
|
|
||||||
// Previous expiration was within 1 min.
|
|
||||||
future := 88 * 24 * time.Hour
|
|
||||||
if next < future {
|
|
||||||
t.Errorf("testDidRenewLoop: next = %v; want >= %v", next, future)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the new cert is cached
|
|
||||||
after := time.Now().Add(future)
|
|
||||||
tlscert, err := man.cacheGet(context.Background(), domain)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("man.cacheGet: %v", err)
|
|
||||||
}
|
|
||||||
if !tlscert.Leaf.NotAfter.After(after) {
|
|
||||||
t.Errorf("cache leaf.NotAfter = %v; want > %v", tlscert.Leaf.NotAfter, after)
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify the old cert is also replaced in memory
|
|
||||||
man.stateMu.Lock()
|
|
||||||
defer man.stateMu.Unlock()
|
|
||||||
s := man.state[domain]
|
|
||||||
if s == nil {
|
|
||||||
t.Fatalf("m.state[%q] is nil", domain)
|
|
||||||
}
|
|
||||||
tlscert, err = s.tlscert()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("s.tlscert: %v", err)
|
|
||||||
}
|
|
||||||
if !tlscert.Leaf.NotAfter.After(after) {
|
|
||||||
t.Errorf("state leaf.NotAfter = %v; want > %v", tlscert.Leaf.NotAfter, after)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigger renew
|
|
||||||
hello := &tls.ClientHelloInfo{ServerName: domain}
|
|
||||||
if _, err := man.GetCertificate(hello); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for renew loop
|
|
||||||
select {
|
|
||||||
case <-time.After(10 * time.Second):
|
|
||||||
t.Fatal("renew took too long to occur")
|
|
||||||
case <-done:
|
|
||||||
}
|
|
||||||
}
|
|
153
vendor/golang.org/x/crypto/acme/jws.go
generated
vendored
153
vendor/golang.org/x/crypto/acme/jws.go
generated
vendored
|
@ -1,153 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package acme
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto"
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/sha256"
|
|
||||||
_ "crypto/sha512" // need for EC keys
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
)
|
|
||||||
|
|
||||||
// jwsEncodeJSON signs claimset using provided key and a nonce.
|
|
||||||
// The result is serialized in JSON format.
|
|
||||||
// See https://tools.ietf.org/html/rfc7515#section-7.
|
|
||||||
func jwsEncodeJSON(claimset interface{}, key crypto.Signer, nonce string) ([]byte, error) {
|
|
||||||
jwk, err := jwkEncode(key.Public())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
alg, sha := jwsHasher(key)
|
|
||||||
if alg == "" || !sha.Available() {
|
|
||||||
return nil, ErrUnsupportedKey
|
|
||||||
}
|
|
||||||
phead := fmt.Sprintf(`{"alg":%q,"jwk":%s,"nonce":%q}`, alg, jwk, nonce)
|
|
||||||
phead = base64.RawURLEncoding.EncodeToString([]byte(phead))
|
|
||||||
cs, err := json.Marshal(claimset)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
payload := base64.RawURLEncoding.EncodeToString(cs)
|
|
||||||
hash := sha.New()
|
|
||||||
hash.Write([]byte(phead + "." + payload))
|
|
||||||
sig, err := jwsSign(key, sha, hash.Sum(nil))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
enc := struct {
|
|
||||||
Protected string `json:"protected"`
|
|
||||||
Payload string `json:"payload"`
|
|
||||||
Sig string `json:"signature"`
|
|
||||||
}{
|
|
||||||
Protected: phead,
|
|
||||||
Payload: payload,
|
|
||||||
Sig: base64.RawURLEncoding.EncodeToString(sig),
|
|
||||||
}
|
|
||||||
return json.Marshal(&enc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// jwkEncode encodes public part of an RSA or ECDSA key into a JWK.
|
|
||||||
// The result is also suitable for creating a JWK thumbprint.
|
|
||||||
// https://tools.ietf.org/html/rfc7517
|
|
||||||
func jwkEncode(pub crypto.PublicKey) (string, error) {
|
|
||||||
switch pub := pub.(type) {
|
|
||||||
case *rsa.PublicKey:
|
|
||||||
// https://tools.ietf.org/html/rfc7518#section-6.3.1
|
|
||||||
n := pub.N
|
|
||||||
e := big.NewInt(int64(pub.E))
|
|
||||||
// Field order is important.
|
|
||||||
// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.
|
|
||||||
return fmt.Sprintf(`{"e":"%s","kty":"RSA","n":"%s"}`,
|
|
||||||
base64.RawURLEncoding.EncodeToString(e.Bytes()),
|
|
||||||
base64.RawURLEncoding.EncodeToString(n.Bytes()),
|
|
||||||
), nil
|
|
||||||
case *ecdsa.PublicKey:
|
|
||||||
// https://tools.ietf.org/html/rfc7518#section-6.2.1
|
|
||||||
p := pub.Curve.Params()
|
|
||||||
n := p.BitSize / 8
|
|
||||||
if p.BitSize%8 != 0 {
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
x := pub.X.Bytes()
|
|
||||||
if n > len(x) {
|
|
||||||
x = append(make([]byte, n-len(x)), x...)
|
|
||||||
}
|
|
||||||
y := pub.Y.Bytes()
|
|
||||||
if n > len(y) {
|
|
||||||
y = append(make([]byte, n-len(y)), y...)
|
|
||||||
}
|
|
||||||
// Field order is important.
|
|
||||||
// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.
|
|
||||||
return fmt.Sprintf(`{"crv":"%s","kty":"EC","x":"%s","y":"%s"}`,
|
|
||||||
p.Name,
|
|
||||||
base64.RawURLEncoding.EncodeToString(x),
|
|
||||||
base64.RawURLEncoding.EncodeToString(y),
|
|
||||||
), nil
|
|
||||||
}
|
|
||||||
return "", ErrUnsupportedKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// jwsSign signs the digest using the given key.
|
|
||||||
// It returns ErrUnsupportedKey if the key type is unknown.
|
|
||||||
// The hash is used only for RSA keys.
|
|
||||||
func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
|
|
||||||
switch key := key.(type) {
|
|
||||||
case *rsa.PrivateKey:
|
|
||||||
return key.Sign(rand.Reader, digest, hash)
|
|
||||||
case *ecdsa.PrivateKey:
|
|
||||||
r, s, err := ecdsa.Sign(rand.Reader, key, digest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
rb, sb := r.Bytes(), s.Bytes()
|
|
||||||
size := key.Params().BitSize / 8
|
|
||||||
if size%8 > 0 {
|
|
||||||
size++
|
|
||||||
}
|
|
||||||
sig := make([]byte, size*2)
|
|
||||||
copy(sig[size-len(rb):], rb)
|
|
||||||
copy(sig[size*2-len(sb):], sb)
|
|
||||||
return sig, nil
|
|
||||||
}
|
|
||||||
return nil, ErrUnsupportedKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// jwsHasher indicates suitable JWS algorithm name and a hash function
|
|
||||||
// to use for signing a digest with the provided key.
|
|
||||||
// It returns ("", 0) if the key is not supported.
|
|
||||||
func jwsHasher(key crypto.Signer) (string, crypto.Hash) {
|
|
||||||
switch key := key.(type) {
|
|
||||||
case *rsa.PrivateKey:
|
|
||||||
return "RS256", crypto.SHA256
|
|
||||||
case *ecdsa.PrivateKey:
|
|
||||||
switch key.Params().Name {
|
|
||||||
case "P-256":
|
|
||||||
return "ES256", crypto.SHA256
|
|
||||||
case "P-384":
|
|
||||||
return "ES384", crypto.SHA384
|
|
||||||
case "P-521":
|
|
||||||
return "ES512", crypto.SHA512
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// JWKThumbprint creates a JWK thumbprint out of pub
|
|
||||||
// as specified in https://tools.ietf.org/html/rfc7638.
|
|
||||||
func JWKThumbprint(pub crypto.PublicKey) (string, error) {
|
|
||||||
jwk, err := jwkEncode(pub)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
b := sha256.Sum256([]byte(jwk))
|
|
||||||
return base64.RawURLEncoding.EncodeToString(b[:]), nil
|
|
||||||
}
|
|
319
vendor/golang.org/x/crypto/acme/jws_test.go
generated
vendored
319
vendor/golang.org/x/crypto/acme/jws_test.go
generated
vendored
|
@ -1,319 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package acme
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"encoding/pem"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
testKeyPEM = `
|
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIEowIBAAKCAQEA4xgZ3eRPkwoRvy7qeRUbmMDe0V+xH9eWLdu0iheeLlrmD2mq
|
|
||||||
WXfP9IeSKApbn34g8TuAS9g5zhq8ELQ3kmjr+KV86GAMgI6VAcGlq3QrzpTCf/30
|
|
||||||
Ab7+zawrfRaFONa1HwEzPY1KHnGVkxJc85gNkwYI9SY2RHXtvln3zs5wITNrdosq
|
|
||||||
EXeaIkVYBEhbhNu54pp3kxo6TuWLi9e6pXeWetEwmlBwtWZlPoib2j3TxLBksKZf
|
|
||||||
oyFyek380mHgJAumQ/I2fjj98/97mk3ihOY4AgVdCDj1z/GCoZkG5Rq7nbCGyosy
|
|
||||||
KWyDX00Zs+nNqVhoLeIvXC4nnWdJMZ6rogxyQQIDAQABAoIBACIEZTOI1Kao9nmV
|
|
||||||
9IeIsuaR1Y61b9neOF/MLmIVIZu+AAJFCMB4Iw11FV6sFodwpEyeZhx2WkpWVN+H
|
|
||||||
r19eGiLX3zsL0DOdqBJoSIHDWCCMxgnYJ6nvS0nRxX3qVrBp8R2g12Ub+gNPbmFm
|
|
||||||
ecf/eeERIVxfifd9VsyRu34eDEvcmKFuLYbElFcPh62xE3x12UZvV/sN7gXbawpP
|
|
||||||
G+w255vbE5MoaKdnnO83cTFlcHvhn24M/78qP7Te5OAeelr1R89kYxQLpuGe4fbS
|
|
||||||
zc6E3ym5Td6urDetGGrSY1Eu10/8sMusX+KNWkm+RsBRbkyKq72ks/qKpOxOa+c6
|
|
||||||
9gm+Y8ECgYEA/iNUyg1ubRdH11p82l8KHtFC1DPE0V1gSZsX29TpM5jS4qv46K+s
|
|
||||||
8Ym1zmrORM8x+cynfPx1VQZQ34EYeCMIX212ryJ+zDATl4NE0I4muMvSiH9vx6Xc
|
|
||||||
7FmhNnaYzPsBL5Tm9nmtQuP09YEn8poiOJFiDs/4olnD5ogA5O4THGkCgYEA5MIL
|
|
||||||
qWYBUuqbEWLRtMruUtpASclrBqNNsJEsMGbeqBJmoMxdHeSZckbLOrqm7GlMyNRJ
|
|
||||||
Ne/5uWRGSzaMYuGmwsPpERzqEvYFnSrpjW5YtXZ+JtxFXNVfm9Z1gLLgvGpOUCIU
|
|
||||||
RbpoDckDe1vgUuk3y5+DjZihs+rqIJ45XzXTzBkCgYBWuf3segruJZy5rEKhTv+o
|
|
||||||
JqeUvRn0jNYYKFpLBeyTVBrbie6GkbUGNIWbrK05pC+c3K9nosvzuRUOQQL1tJbd
|
|
||||||
4gA3oiD9U4bMFNr+BRTHyZ7OQBcIXdz3t1qhuHVKtnngIAN1p25uPlbRFUNpshnt
|
|
||||||
jgeVoHlsBhApcs5DUc+pyQKBgDzeHPg/+g4z+nrPznjKnktRY1W+0El93kgi+J0Q
|
|
||||||
YiJacxBKEGTJ1MKBb8X6sDurcRDm22wMpGfd9I5Cv2v4GsUsF7HD/cx5xdih+G73
|
|
||||||
c4clNj/k0Ff5Nm1izPUno4C+0IOl7br39IPmfpSuR6wH/h6iHQDqIeybjxyKvT1G
|
|
||||||
N0rRAoGBAKGD+4ZI/E1MoJ5CXB8cDDMHagbE3cq/DtmYzE2v1DFpQYu5I4PCm5c7
|
|
||||||
EQeIP6dZtv8IMgtGIb91QX9pXvP0aznzQKwYIA8nZgoENCPfiMTPiEDT9e/0lObO
|
|
||||||
9XWsXpbSTsRPj0sv1rB+UzBJ0PgjK4q2zOF0sNo7b1+6nlM3BWPx
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
`
|
|
||||||
|
|
||||||
// This thumbprint is for the testKey defined above.
|
|
||||||
testKeyThumbprint = "6nicxzh6WETQlrvdchkz-U3e3DOQZ4heJKU63rfqMqQ"
|
|
||||||
|
|
||||||
// openssl ecparam -name secp256k1 -genkey -noout
|
|
||||||
testKeyECPEM = `
|
|
||||||
-----BEGIN EC PRIVATE KEY-----
|
|
||||||
MHcCAQEEIK07hGLr0RwyUdYJ8wbIiBS55CjnkMD23DWr+ccnypWLoAoGCCqGSM49
|
|
||||||
AwEHoUQDQgAE5lhEug5xK4xBDZ2nAbaxLtaLiv85bxJ7ePd1dkO23HThqIrvawF5
|
|
||||||
QAaS/RNouybCiRhRjI3EaxLkQwgrCw0gqQ==
|
|
||||||
-----END EC PRIVATE KEY-----
|
|
||||||
`
|
|
||||||
// openssl ecparam -name secp384r1 -genkey -noout
|
|
||||||
testKeyEC384PEM = `
|
|
||||||
-----BEGIN EC PRIVATE KEY-----
|
|
||||||
MIGkAgEBBDAQ4lNtXRORWr1bgKR1CGysr9AJ9SyEk4jiVnlUWWUChmSNL+i9SLSD
|
|
||||||
Oe/naPqXJ6CgBwYFK4EEACKhZANiAAQzKtj+Ms0vHoTX5dzv3/L5YMXOWuI5UKRj
|
|
||||||
JigpahYCqXD2BA1j0E/2xt5vlPf+gm0PL+UHSQsCokGnIGuaHCsJAp3ry0gHQEke
|
|
||||||
WYXapUUFdvaK1R2/2hn5O+eiQM8YzCg=
|
|
||||||
-----END EC PRIVATE KEY-----
|
|
||||||
`
|
|
||||||
// openssl ecparam -name secp521r1 -genkey -noout
|
|
||||||
testKeyEC512PEM = `
|
|
||||||
-----BEGIN EC PRIVATE KEY-----
|
|
||||||
MIHcAgEBBEIBSNZKFcWzXzB/aJClAb305ibalKgtDA7+70eEkdPt28/3LZMM935Z
|
|
||||||
KqYHh/COcxuu3Kt8azRAUz3gyr4zZKhlKUSgBwYFK4EEACOhgYkDgYYABAHUNKbx
|
|
||||||
7JwC7H6pa2sV0tERWhHhB3JmW+OP6SUgMWryvIKajlx73eS24dy4QPGrWO9/ABsD
|
|
||||||
FqcRSkNVTXnIv6+0mAF25knqIBIg5Q8M9BnOu9GGAchcwt3O7RDHmqewnJJDrbjd
|
|
||||||
GGnm6rb+NnWR9DIopM0nKNkToWoF/hzopxu4Ae/GsQ==
|
|
||||||
-----END EC PRIVATE KEY-----
|
|
||||||
`
|
|
||||||
// 1. openssl ec -in key.pem -noout -text
|
|
||||||
// 2. remove first byte, 04 (the header); the rest is X and Y
|
|
||||||
// 3. convert each with: echo <val> | xxd -r -p | base64 -w 100 | tr -d '=' | tr '/+' '_-'
|
|
||||||
testKeyECPubX = "5lhEug5xK4xBDZ2nAbaxLtaLiv85bxJ7ePd1dkO23HQ"
|
|
||||||
testKeyECPubY = "4aiK72sBeUAGkv0TaLsmwokYUYyNxGsS5EMIKwsNIKk"
|
|
||||||
testKeyEC384PubX = "MyrY_jLNLx6E1-Xc79_y-WDFzlriOVCkYyYoKWoWAqlw9gQNY9BP9sbeb5T3_oJt"
|
|
||||||
testKeyEC384PubY = "Dy_lB0kLAqJBpyBrmhwrCQKd68tIB0BJHlmF2qVFBXb2itUdv9oZ-TvnokDPGMwo"
|
|
||||||
testKeyEC512PubX = "AdQ0pvHsnALsfqlraxXS0RFaEeEHcmZb44_pJSAxavK8gpqOXHvd5Lbh3LhA8atY738AGwMWpxFKQ1VNeci_r7SY"
|
|
||||||
testKeyEC512PubY = "AXbmSeogEiDlDwz0Gc670YYByFzC3c7tEMeap7CckkOtuN0Yaebqtv42dZH0MiikzSco2ROhagX-HOinG7gB78ax"
|
|
||||||
|
|
||||||
// echo -n '{"crv":"P-256","kty":"EC","x":"<testKeyECPubX>","y":"<testKeyECPubY>"}' | \
|
|
||||||
// openssl dgst -binary -sha256 | base64 | tr -d '=' | tr '/+' '_-'
|
|
||||||
testKeyECThumbprint = "zedj-Bd1Zshp8KLePv2MB-lJ_Hagp7wAwdkA0NUTniU"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
testKey *rsa.PrivateKey
|
|
||||||
testKeyEC *ecdsa.PrivateKey
|
|
||||||
testKeyEC384 *ecdsa.PrivateKey
|
|
||||||
testKeyEC512 *ecdsa.PrivateKey
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testKey = parseRSA(testKeyPEM, "testKeyPEM")
|
|
||||||
testKeyEC = parseEC(testKeyECPEM, "testKeyECPEM")
|
|
||||||
testKeyEC384 = parseEC(testKeyEC384PEM, "testKeyEC384PEM")
|
|
||||||
testKeyEC512 = parseEC(testKeyEC512PEM, "testKeyEC512PEM")
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodePEM(s, name string) []byte {
|
|
||||||
d, _ := pem.Decode([]byte(s))
|
|
||||||
if d == nil {
|
|
||||||
panic("no block found in " + name)
|
|
||||||
}
|
|
||||||
return d.Bytes
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseRSA(s, name string) *rsa.PrivateKey {
|
|
||||||
b := decodePEM(s, name)
|
|
||||||
k, err := x509.ParsePKCS1PrivateKey(b)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("%s: %v", name, err))
|
|
||||||
}
|
|
||||||
return k
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseEC(s, name string) *ecdsa.PrivateKey {
|
|
||||||
b := decodePEM(s, name)
|
|
||||||
k, err := x509.ParseECPrivateKey(b)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("%s: %v", name, err))
|
|
||||||
}
|
|
||||||
return k
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJWSEncodeJSON(t *testing.T) {
|
|
||||||
claims := struct{ Msg string }{"Hello JWS"}
|
|
||||||
// JWS signed with testKey and "nonce" as the nonce value
|
|
||||||
// JSON-serialized JWS fields are split for easier testing
|
|
||||||
const (
|
|
||||||
// {"alg":"RS256","jwk":{"e":"AQAB","kty":"RSA","n":"..."},"nonce":"nonce"}
|
|
||||||
protected = "eyJhbGciOiJSUzI1NiIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6" +
|
|
||||||
"IlJTQSIsIm4iOiI0eGdaM2VSUGt3b1J2eTdxZVJVYm1NRGUwVi14" +
|
|
||||||
"SDllV0xkdTBpaGVlTGxybUQybXFXWGZQOUllU0tBcGJuMzRnOFR1" +
|
|
||||||
"QVM5ZzV6aHE4RUxRM2ttanItS1Y4NkdBTWdJNlZBY0dscTNRcnpw" +
|
|
||||||
"VENmXzMwQWI3LXphd3JmUmFGT05hMUh3RXpQWTFLSG5HVmt4SmM4" +
|
|
||||||
"NWdOa3dZSTlTWTJSSFh0dmxuM3pzNXdJVE5yZG9zcUVYZWFJa1ZZ" +
|
|
||||||
"QkVoYmhOdTU0cHAza3hvNlR1V0xpOWU2cFhlV2V0RXdtbEJ3dFda" +
|
|
||||||
"bFBvaWIyajNUeExCa3NLWmZveUZ5ZWszODBtSGdKQXVtUV9JMmZq" +
|
|
||||||
"ajk4Xzk3bWszaWhPWTRBZ1ZkQ0RqMXpfR0NvWmtHNVJxN25iQ0d5" +
|
|
||||||
"b3N5S1d5RFgwMFpzLW5OcVZob0xlSXZYQzRubldkSk1aNnJvZ3h5" +
|
|
||||||
"UVEifSwibm9uY2UiOiJub25jZSJ9"
|
|
||||||
// {"Msg":"Hello JWS"}
|
|
||||||
payload = "eyJNc2ciOiJIZWxsbyBKV1MifQ"
|
|
||||||
signature = "eAGUikStX_UxyiFhxSLMyuyBcIB80GeBkFROCpap2sW3EmkU_ggF" +
|
|
||||||
"knaQzxrTfItICSAXsCLIquZ5BbrSWA_4vdEYrwWtdUj7NqFKjHRa" +
|
|
||||||
"zpLHcoR7r1rEHvkoP1xj49lS5fc3Wjjq8JUhffkhGbWZ8ZVkgPdC" +
|
|
||||||
"4tMBWiQDoth-x8jELP_3LYOB_ScUXi2mETBawLgOT2K8rA0Vbbmx" +
|
|
||||||
"hWNlOWuUf-8hL5YX4IOEwsS8JK_TrTq5Zc9My0zHJmaieqDV0UlP" +
|
|
||||||
"k0onFjPFkGm7MrPSgd0MqRG-4vSAg2O4hDo7rKv4n8POjjXlNQvM" +
|
|
||||||
"9IPLr8qZ7usYBKhEGwX3yq_eicAwBw"
|
|
||||||
)
|
|
||||||
|
|
||||||
b, err := jwsEncodeJSON(claims, testKey, "nonce")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
var jws struct{ Protected, Payload, Signature string }
|
|
||||||
if err := json.Unmarshal(b, &jws); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if jws.Protected != protected {
|
|
||||||
t.Errorf("protected:\n%s\nwant:\n%s", jws.Protected, protected)
|
|
||||||
}
|
|
||||||
if jws.Payload != payload {
|
|
||||||
t.Errorf("payload:\n%s\nwant:\n%s", jws.Payload, payload)
|
|
||||||
}
|
|
||||||
if jws.Signature != signature {
|
|
||||||
t.Errorf("signature:\n%s\nwant:\n%s", jws.Signature, signature)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJWSEncodeJSONEC(t *testing.T) {
|
|
||||||
tt := []struct {
|
|
||||||
key *ecdsa.PrivateKey
|
|
||||||
x, y string
|
|
||||||
alg, crv string
|
|
||||||
}{
|
|
||||||
{testKeyEC, testKeyECPubX, testKeyECPubY, "ES256", "P-256"},
|
|
||||||
{testKeyEC384, testKeyEC384PubX, testKeyEC384PubY, "ES384", "P-384"},
|
|
||||||
{testKeyEC512, testKeyEC512PubX, testKeyEC512PubY, "ES512", "P-521"},
|
|
||||||
}
|
|
||||||
for i, test := range tt {
|
|
||||||
claims := struct{ Msg string }{"Hello JWS"}
|
|
||||||
b, err := jwsEncodeJSON(claims, test.key, "nonce")
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%d: %v", i, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var jws struct{ Protected, Payload, Signature string }
|
|
||||||
if err := json.Unmarshal(b, &jws); err != nil {
|
|
||||||
t.Errorf("%d: %v", i, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err = base64.RawURLEncoding.DecodeString(jws.Protected)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%d: jws.Protected: %v", i, err)
|
|
||||||
}
|
|
||||||
var head struct {
|
|
||||||
Alg string
|
|
||||||
Nonce string
|
|
||||||
JWK struct {
|
|
||||||
Crv string
|
|
||||||
Kty string
|
|
||||||
X string
|
|
||||||
Y string
|
|
||||||
} `json:"jwk"`
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(b, &head); err != nil {
|
|
||||||
t.Errorf("%d: jws.Protected: %v", i, err)
|
|
||||||
}
|
|
||||||
if head.Alg != test.alg {
|
|
||||||
t.Errorf("%d: head.Alg = %q; want %q", i, head.Alg, test.alg)
|
|
||||||
}
|
|
||||||
if head.Nonce != "nonce" {
|
|
||||||
t.Errorf("%d: head.Nonce = %q; want nonce", i, head.Nonce)
|
|
||||||
}
|
|
||||||
if head.JWK.Crv != test.crv {
|
|
||||||
t.Errorf("%d: head.JWK.Crv = %q; want %q", i, head.JWK.Crv, test.crv)
|
|
||||||
}
|
|
||||||
if head.JWK.Kty != "EC" {
|
|
||||||
t.Errorf("%d: head.JWK.Kty = %q; want EC", i, head.JWK.Kty)
|
|
||||||
}
|
|
||||||
if head.JWK.X != test.x {
|
|
||||||
t.Errorf("%d: head.JWK.X = %q; want %q", i, head.JWK.X, test.x)
|
|
||||||
}
|
|
||||||
if head.JWK.Y != test.y {
|
|
||||||
t.Errorf("%d: head.JWK.Y = %q; want %q", i, head.JWK.Y, test.y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJWKThumbprintRSA(t *testing.T) {
|
|
||||||
// Key example from RFC 7638
|
|
||||||
const base64N = "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAt" +
|
|
||||||
"VT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn6" +
|
|
||||||
"4tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FD" +
|
|
||||||
"W2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n9" +
|
|
||||||
"1CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINH" +
|
|
||||||
"aQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"
|
|
||||||
const base64E = "AQAB"
|
|
||||||
const expected = "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs"
|
|
||||||
|
|
||||||
b, err := base64.RawURLEncoding.DecodeString(base64N)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error parsing example key N: %v", err)
|
|
||||||
}
|
|
||||||
n := new(big.Int).SetBytes(b)
|
|
||||||
|
|
||||||
b, err = base64.RawURLEncoding.DecodeString(base64E)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error parsing example key E: %v", err)
|
|
||||||
}
|
|
||||||
e := new(big.Int).SetBytes(b)
|
|
||||||
|
|
||||||
pub := &rsa.PublicKey{N: n, E: int(e.Uint64())}
|
|
||||||
th, err := JWKThumbprint(pub)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if th != expected {
|
|
||||||
t.Errorf("thumbprint = %q; want %q", th, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJWKThumbprintEC(t *testing.T) {
|
|
||||||
// Key example from RFC 7520
|
|
||||||
// expected was computed with
|
|
||||||
// echo -n '{"crv":"P-521","kty":"EC","x":"<base64X>","y":"<base64Y>"}' | \
|
|
||||||
// openssl dgst -binary -sha256 | \
|
|
||||||
// base64 | \
|
|
||||||
// tr -d '=' | tr '/+' '_-'
|
|
||||||
const (
|
|
||||||
base64X = "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkT" +
|
|
||||||
"KqjqvjyekWF-7ytDyRXYgCF5cj0Kt"
|
|
||||||
base64Y = "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUda" +
|
|
||||||
"QkAgDPrwQrJmbnX9cwlGfP-HqHZR1"
|
|
||||||
expected = "dHri3SADZkrush5HU_50AoRhcKFryN-PI6jPBtPL55M"
|
|
||||||
)
|
|
||||||
|
|
||||||
b, err := base64.RawURLEncoding.DecodeString(base64X)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error parsing example key X: %v", err)
|
|
||||||
}
|
|
||||||
x := new(big.Int).SetBytes(b)
|
|
||||||
|
|
||||||
b, err = base64.RawURLEncoding.DecodeString(base64Y)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error parsing example key Y: %v", err)
|
|
||||||
}
|
|
||||||
y := new(big.Int).SetBytes(b)
|
|
||||||
|
|
||||||
pub := &ecdsa.PublicKey{Curve: elliptic.P521(), X: x, Y: y}
|
|
||||||
th, err := JWKThumbprint(pub)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if th != expected {
|
|
||||||
t.Errorf("thumbprint = %q; want %q", th, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJWKThumbprintErrUnsupportedKey(t *testing.T) {
|
|
||||||
_, err := JWKThumbprint(struct{}{})
|
|
||||||
if err != ErrUnsupportedKey {
|
|
||||||
t.Errorf("err = %q; want %q", err, ErrUnsupportedKey)
|
|
||||||
}
|
|
||||||
}
|
|
295
vendor/golang.org/x/crypto/acme/types.go
generated
vendored
295
vendor/golang.org/x/crypto/acme/types.go
generated
vendored
|
@ -1,295 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package acme
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ACME server response statuses used to describe Authorization and Challenge states.
|
|
||||||
const (
|
|
||||||
StatusUnknown = "unknown"
|
|
||||||
StatusPending = "pending"
|
|
||||||
StatusProcessing = "processing"
|
|
||||||
StatusValid = "valid"
|
|
||||||
StatusInvalid = "invalid"
|
|
||||||
StatusRevoked = "revoked"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CRLReasonCode identifies the reason for a certificate revocation.
|
|
||||||
type CRLReasonCode int
|
|
||||||
|
|
||||||
// CRL reason codes as defined in RFC 5280.
|
|
||||||
const (
|
|
||||||
CRLReasonUnspecified CRLReasonCode = 0
|
|
||||||
CRLReasonKeyCompromise CRLReasonCode = 1
|
|
||||||
CRLReasonCACompromise CRLReasonCode = 2
|
|
||||||
CRLReasonAffiliationChanged CRLReasonCode = 3
|
|
||||||
CRLReasonSuperseded CRLReasonCode = 4
|
|
||||||
CRLReasonCessationOfOperation CRLReasonCode = 5
|
|
||||||
CRLReasonCertificateHold CRLReasonCode = 6
|
|
||||||
CRLReasonRemoveFromCRL CRLReasonCode = 8
|
|
||||||
CRLReasonPrivilegeWithdrawn CRLReasonCode = 9
|
|
||||||
CRLReasonAACompromise CRLReasonCode = 10
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrUnsupportedKey is returned when an unsupported key type is encountered.
|
|
||||||
var ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
|
|
||||||
|
|
||||||
// Error is an ACME error, defined in Problem Details for HTTP APIs doc
|
|
||||||
// http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
|
|
||||||
type Error struct {
|
|
||||||
// StatusCode is The HTTP status code generated by the origin server.
|
|
||||||
StatusCode int
|
|
||||||
// ProblemType is a URI reference that identifies the problem type,
|
|
||||||
// typically in a "urn:acme:error:xxx" form.
|
|
||||||
ProblemType string
|
|
||||||
// Detail is a human-readable explanation specific to this occurrence of the problem.
|
|
||||||
Detail string
|
|
||||||
// Header is the original server error response headers.
|
|
||||||
// It may be nil.
|
|
||||||
Header http.Header
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthorizationError indicates that an authorization for an identifier
|
|
||||||
// did not succeed.
|
|
||||||
// It contains all errors from Challenge items of the failed Authorization.
|
|
||||||
type AuthorizationError struct {
|
|
||||||
// URI uniquely identifies the failed Authorization.
|
|
||||||
URI string
|
|
||||||
|
|
||||||
// Identifier is an AuthzID.Value of the failed Authorization.
|
|
||||||
Identifier string
|
|
||||||
|
|
||||||
// Errors is a collection of non-nil error values of Challenge items
|
|
||||||
// of the failed Authorization.
|
|
||||||
Errors []error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AuthorizationError) Error() string {
|
|
||||||
e := make([]string, len(a.Errors))
|
|
||||||
for i, err := range a.Errors {
|
|
||||||
e[i] = err.Error()
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
|
|
||||||
}
|
|
||||||
|
|
||||||
// RateLimit reports whether err represents a rate limit error and
|
|
||||||
// any Retry-After duration returned by the server.
|
|
||||||
//
|
|
||||||
// See the following for more details on rate limiting:
|
|
||||||
// https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-5.6
|
|
||||||
func RateLimit(err error) (time.Duration, bool) {
|
|
||||||
e, ok := err.(*Error)
|
|
||||||
if !ok {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
// Some CA implementations may return incorrect values.
|
|
||||||
// Use case-insensitive comparison.
|
|
||||||
if !strings.HasSuffix(strings.ToLower(e.ProblemType), ":ratelimited") {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
if e.Header == nil {
|
|
||||||
return 0, true
|
|
||||||
}
|
|
||||||
return retryAfter(e.Header.Get("Retry-After"), 0), true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Account is a user account. It is associated with a private key.
|
|
||||||
type Account struct {
|
|
||||||
// URI is the account unique ID, which is also a URL used to retrieve
|
|
||||||
// account data from the CA.
|
|
||||||
URI string
|
|
||||||
|
|
||||||
// Contact is a slice of contact info used during registration.
|
|
||||||
Contact []string
|
|
||||||
|
|
||||||
// The terms user has agreed to.
|
|
||||||
// A value not matching CurrentTerms indicates that the user hasn't agreed
|
|
||||||
// to the actual Terms of Service of the CA.
|
|
||||||
AgreedTerms string
|
|
||||||
|
|
||||||
// Actual terms of a CA.
|
|
||||||
CurrentTerms string
|
|
||||||
|
|
||||||
// Authz is the authorization URL used to initiate a new authz flow.
|
|
||||||
Authz string
|
|
||||||
|
|
||||||
// Authorizations is a URI from which a list of authorizations
|
|
||||||
// granted to this account can be fetched via a GET request.
|
|
||||||
Authorizations string
|
|
||||||
|
|
||||||
// Certificates is a URI from which a list of certificates
|
|
||||||
// issued for this account can be fetched via a GET request.
|
|
||||||
Certificates string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Directory is ACME server discovery data.
|
|
||||||
type Directory struct {
|
|
||||||
// RegURL is an account endpoint URL, allowing for creating new
|
|
||||||
// and modifying existing accounts.
|
|
||||||
RegURL string
|
|
||||||
|
|
||||||
// AuthzURL is used to initiate Identifier Authorization flow.
|
|
||||||
AuthzURL string
|
|
||||||
|
|
||||||
// CertURL is a new certificate issuance endpoint URL.
|
|
||||||
CertURL string
|
|
||||||
|
|
||||||
// RevokeURL is used to initiate a certificate revocation flow.
|
|
||||||
RevokeURL string
|
|
||||||
|
|
||||||
// Term is a URI identifying the current terms of service.
|
|
||||||
Terms string
|
|
||||||
|
|
||||||
// Website is an HTTP or HTTPS URL locating a website
|
|
||||||
// providing more information about the ACME server.
|
|
||||||
Website string
|
|
||||||
|
|
||||||
// CAA consists of lowercase hostname elements, which the ACME server
|
|
||||||
// recognises as referring to itself for the purposes of CAA record validation
|
|
||||||
// as defined in RFC6844.
|
|
||||||
CAA []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Challenge encodes a returned CA challenge.
|
|
||||||
// Its Error field may be non-nil if the challenge is part of an Authorization
|
|
||||||
// with StatusInvalid.
|
|
||||||
type Challenge struct {
|
|
||||||
// Type is the challenge type, e.g. "http-01", "tls-sni-02", "dns-01".
|
|
||||||
Type string
|
|
||||||
|
|
||||||
// URI is where a challenge response can be posted to.
|
|
||||||
URI string
|
|
||||||
|
|
||||||
// Token is a random value that uniquely identifies the challenge.
|
|
||||||
Token string
|
|
||||||
|
|
||||||
// Status identifies the status of this challenge.
|
|
||||||
Status string
|
|
||||||
|
|
||||||
// Error indicates the reason for an authorization failure
|
|
||||||
// when this challenge was used.
|
|
||||||
// The type of a non-nil value is *Error.
|
|
||||||
Error error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authorization encodes an authorization response.
|
|
||||||
type Authorization struct {
|
|
||||||
// URI uniquely identifies a authorization.
|
|
||||||
URI string
|
|
||||||
|
|
||||||
// Status identifies the status of an authorization.
|
|
||||||
Status string
|
|
||||||
|
|
||||||
// Identifier is what the account is authorized to represent.
|
|
||||||
Identifier AuthzID
|
|
||||||
|
|
||||||
// Challenges that the client needs to fulfill in order to prove possession
|
|
||||||
// of the identifier (for pending authorizations).
|
|
||||||
// For final authorizations, the challenges that were used.
|
|
||||||
Challenges []*Challenge
|
|
||||||
|
|
||||||
// A collection of sets of challenges, each of which would be sufficient
|
|
||||||
// to prove possession of the identifier.
|
|
||||||
// Clients must complete a set of challenges that covers at least one set.
|
|
||||||
// Challenges are identified by their indices in the challenges array.
|
|
||||||
// If this field is empty, the client needs to complete all challenges.
|
|
||||||
Combinations [][]int
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthzID is an identifier that an account is authorized to represent.
|
|
||||||
type AuthzID struct {
|
|
||||||
Type string // The type of identifier, e.g. "dns".
|
|
||||||
Value string // The identifier itself, e.g. "example.org".
|
|
||||||
}
|
|
||||||
|
|
||||||
// wireAuthz is ACME JSON representation of Authorization objects.
|
|
||||||
type wireAuthz struct {
|
|
||||||
Status string
|
|
||||||
Challenges []wireChallenge
|
|
||||||
Combinations [][]int
|
|
||||||
Identifier struct {
|
|
||||||
Type string
|
|
||||||
Value string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (z *wireAuthz) authorization(uri string) *Authorization {
|
|
||||||
a := &Authorization{
|
|
||||||
URI: uri,
|
|
||||||
Status: z.Status,
|
|
||||||
Identifier: AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
|
|
||||||
Combinations: z.Combinations, // shallow copy
|
|
||||||
Challenges: make([]*Challenge, len(z.Challenges)),
|
|
||||||
}
|
|
||||||
for i, v := range z.Challenges {
|
|
||||||
a.Challenges[i] = v.challenge()
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
func (z *wireAuthz) error(uri string) *AuthorizationError {
|
|
||||||
err := &AuthorizationError{
|
|
||||||
URI: uri,
|
|
||||||
Identifier: z.Identifier.Value,
|
|
||||||
}
|
|
||||||
for _, raw := range z.Challenges {
|
|
||||||
if raw.Error != nil {
|
|
||||||
err.Errors = append(err.Errors, raw.Error.error(nil))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// wireChallenge is ACME JSON challenge representation.
|
|
||||||
type wireChallenge struct {
|
|
||||||
URI string `json:"uri"`
|
|
||||||
Type string
|
|
||||||
Token string
|
|
||||||
Status string
|
|
||||||
Error *wireError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *wireChallenge) challenge() *Challenge {
|
|
||||||
v := &Challenge{
|
|
||||||
URI: c.URI,
|
|
||||||
Type: c.Type,
|
|
||||||
Token: c.Token,
|
|
||||||
Status: c.Status,
|
|
||||||
}
|
|
||||||
if v.Status == "" {
|
|
||||||
v.Status = StatusPending
|
|
||||||
}
|
|
||||||
if c.Error != nil {
|
|
||||||
v.Error = c.Error.error(nil)
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// wireError is a subset of fields of the Problem Details object
|
|
||||||
// as described in https://tools.ietf.org/html/rfc7807#section-3.1.
|
|
||||||
type wireError struct {
|
|
||||||
Status int
|
|
||||||
Type string
|
|
||||||
Detail string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *wireError) error(h http.Header) *Error {
|
|
||||||
return &Error{
|
|
||||||
StatusCode: e.Status,
|
|
||||||
ProblemType: e.Type,
|
|
||||||
Detail: e.Detail,
|
|
||||||
Header: h,
|
|
||||||
}
|
|
||||||
}
|
|
63
vendor/golang.org/x/crypto/acme/types_test.go
generated
vendored
63
vendor/golang.org/x/crypto/acme/types_test.go
generated
vendored
|
@ -1,63 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package acme
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestRateLimit(t *testing.T) {
|
|
||||||
now := time.Date(2017, 04, 27, 10, 0, 0, 0, time.UTC)
|
|
||||||
f := timeNow
|
|
||||||
defer func() { timeNow = f }()
|
|
||||||
timeNow = func() time.Time { return now }
|
|
||||||
|
|
||||||
h120, hTime := http.Header{}, http.Header{}
|
|
||||||
h120.Set("Retry-After", "120")
|
|
||||||
hTime.Set("Retry-After", "Tue Apr 27 11:00:00 2017")
|
|
||||||
|
|
||||||
err1 := &Error{
|
|
||||||
ProblemType: "urn:ietf:params:acme:error:nolimit",
|
|
||||||
Header: h120,
|
|
||||||
}
|
|
||||||
err2 := &Error{
|
|
||||||
ProblemType: "urn:ietf:params:acme:error:rateLimited",
|
|
||||||
Header: h120,
|
|
||||||
}
|
|
||||||
err3 := &Error{
|
|
||||||
ProblemType: "urn:ietf:params:acme:error:rateLimited",
|
|
||||||
Header: nil,
|
|
||||||
}
|
|
||||||
err4 := &Error{
|
|
||||||
ProblemType: "urn:ietf:params:acme:error:rateLimited",
|
|
||||||
Header: hTime,
|
|
||||||
}
|
|
||||||
|
|
||||||
tt := []struct {
|
|
||||||
err error
|
|
||||||
res time.Duration
|
|
||||||
ok bool
|
|
||||||
}{
|
|
||||||
{nil, 0, false},
|
|
||||||
{errors.New("dummy"), 0, false},
|
|
||||||
{err1, 0, false},
|
|
||||||
{err2, 2 * time.Minute, true},
|
|
||||||
{err3, 0, true},
|
|
||||||
{err4, time.Hour, true},
|
|
||||||
}
|
|
||||||
for i, test := range tt {
|
|
||||||
res, ok := RateLimit(test.err)
|
|
||||||
if ok != test.ok {
|
|
||||||
t.Errorf("%d: RateLimit(%+v): ok = %v; want %v", i, test.err, ok, test.ok)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if res != test.res {
|
|
||||||
t.Errorf("%d: RateLimit(%+v) = %v; want %v", i, test.err, res, test.res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
7
vendor/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
7
vendor/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
|
@ -12,10 +12,9 @@ import (
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/crypto/blowfish"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"golang.org/x/crypto/blowfish"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -206,6 +205,7 @@ func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
|
func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
|
||||||
|
|
||||||
csalt, err := base64Decode(salt)
|
csalt, err := base64Decode(salt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -213,8 +213,7 @@ func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cip
|
||||||
|
|
||||||
// Bug compatibility with C bcrypt implementations. They use the trailing
|
// Bug compatibility with C bcrypt implementations. They use the trailing
|
||||||
// NULL in the key string during expansion.
|
// NULL in the key string during expansion.
|
||||||
// We copy the key to prevent changing the underlying array.
|
ckey := append(key, 0)
|
||||||
ckey := append(key[:len(key):len(key)], 0)
|
|
||||||
|
|
||||||
c, err := blowfish.NewSaltedCipher(ckey, csalt)
|
c, err := blowfish.NewSaltedCipher(ckey, csalt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
17
vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go
generated
vendored
17
vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go
generated
vendored
|
@ -224,20 +224,3 @@ func BenchmarkGeneration(b *testing.B) {
|
||||||
GenerateFromPassword(passwd, 10)
|
GenerateFromPassword(passwd, 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// See Issue https://github.com/golang/go/issues/20425.
|
|
||||||
func TestNoSideEffectsFromCompare(t *testing.T) {
|
|
||||||
source := []byte("passw0rd123456")
|
|
||||||
password := source[:len(source)-6]
|
|
||||||
token := source[len(source)-6:]
|
|
||||||
want := make([]byte, len(source))
|
|
||||||
copy(want, source)
|
|
||||||
|
|
||||||
wantHash := []byte("$2a$10$LK9XRuhNxHHCvjX3tdkRKei1QiCDUKrJRhZv7WWZPuQGRUM92rOUa")
|
|
||||||
_ = CompareHashAndPassword(wantHash, password)
|
|
||||||
|
|
||||||
got := bytes.Join([][]byte{password, token}, []byte(""))
|
|
||||||
if !bytes.Equal(got, want) {
|
|
||||||
t.Errorf("got=%q want=%q", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
194
vendor/golang.org/x/crypto/blake2b/blake2b.go
generated
vendored
194
vendor/golang.org/x/crypto/blake2b/blake2b.go
generated
vendored
|
@ -1,194 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package blake2b implements the BLAKE2b hash algorithm as
|
|
||||||
// defined in RFC 7693.
|
|
||||||
package blake2b // import "golang.org/x/crypto/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")
|
|
||||||
|
|
||||||
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 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 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 between zero and 64 bytes long.
|
|
||||||
func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) }
|
|
||||||
|
|
||||||
func newDigest(hashSize int, key []byte) (*digest, error) {
|
|
||||||
if len(key) > Size {
|
|
||||||
return nil, errKeySize
|
|
||||||
}
|
|
||||||
d := &digest{
|
|
||||||
size: hashSize,
|
|
||||||
keyLen: len(key),
|
|
||||||
}
|
|
||||||
copy(d.key[:], key)
|
|
||||||
d.Reset()
|
|
||||||
return d, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkSum(sum *[Size]byte, hashSize int, data []byte) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
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(b []byte) []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[:])
|
|
||||||
|
|
||||||
var sum [Size]byte
|
|
||||||
for i, v := range h[:(d.size+7)/8] {
|
|
||||||
binary.LittleEndian.PutUint64(sum[8*i:], v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return append(b, sum[:d.size]...)
|
|
||||||
}
|
|
43
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
generated
vendored
43
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
generated
vendored
|
@ -1,43 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.7,amd64,!gccgo,!appengine
|
|
||||||
|
|
||||||
package blake2b
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
useAVX2 = supportsAVX2()
|
|
||||||
useAVX = supportsAVX()
|
|
||||||
useSSE4 = supportsSSE4()
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func supportsSSE4() bool
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func supportsAVX() bool
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func supportsAVX2() bool
|
|
||||||
|
|
||||||
//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) {
|
|
||||||
if useAVX2 {
|
|
||||||
hashBlocksAVX2(h, c, flag, blocks)
|
|
||||||
} else if useAVX {
|
|
||||||
hashBlocksAVX(h, c, flag, blocks)
|
|
||||||
} else if useSSE4 {
|
|
||||||
hashBlocksSSE4(h, c, flag, blocks)
|
|
||||||
} else {
|
|
||||||
hashBlocksGeneric(h, c, flag, blocks)
|
|
||||||
}
|
|
||||||
}
|
|
762
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
generated
vendored
762
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
generated
vendored
|
@ -1,762 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.7,amd64,!gccgo,!appengine
|
|
||||||
|
|
||||||
#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
|
|
||||||
MOVQ SP, R9
|
|
||||||
ADDQ $31, R9
|
|
||||||
ANDQ $~31, R9
|
|
||||||
MOVQ R9, SP
|
|
||||||
|
|
||||||
MOVQ CX, 16(SP)
|
|
||||||
XORQ CX, CX
|
|
||||||
MOVQ CX, 24(SP)
|
|
||||||
|
|
||||||
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(SP)
|
|
||||||
|
|
||||||
loop:
|
|
||||||
ADDQ $128, R8
|
|
||||||
MOVQ R8, 0(SP)
|
|
||||||
CMPQ R8, $128
|
|
||||||
JGE noinc
|
|
||||||
INCQ R9
|
|
||||||
MOVQ R9, 8(SP)
|
|
||||||
|
|
||||||
noinc:
|
|
||||||
VMOVDQA Y8, Y0
|
|
||||||
VMOVDQA Y9, Y1
|
|
||||||
VMOVDQA Y6, Y2
|
|
||||||
VPXOR 0(SP), Y7, Y3
|
|
||||||
|
|
||||||
LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15()
|
|
||||||
VMOVDQA Y12, 32(SP)
|
|
||||||
VMOVDQA Y13, 64(SP)
|
|
||||||
VMOVDQA Y14, 96(SP)
|
|
||||||
VMOVDQA Y15, 128(SP)
|
|
||||||
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(SP)
|
|
||||||
VMOVDQA Y13, 192(SP)
|
|
||||||
VMOVDQA Y14, 224(SP)
|
|
||||||
VMOVDQA Y15, 256(SP)
|
|
||||||
|
|
||||||
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(SP), 64(SP), 96(SP), 128(SP), Y10, Y4, Y5)
|
|
||||||
ROUND_AVX2(160(SP), 192(SP), 224(SP), 256(SP), 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
|
|
||||||
|
|
||||||
MOVQ DX, SP
|
|
||||||
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, BP
|
|
||||||
MOVQ SP, R9
|
|
||||||
ADDQ $15, R9
|
|
||||||
ANDQ $~15, R9
|
|
||||||
MOVQ R9, SP
|
|
||||||
|
|
||||||
VMOVDQU ·AVX_c40<>(SB), X0
|
|
||||||
VMOVDQU ·AVX_c48<>(SB), X1
|
|
||||||
VMOVDQA X0, X8
|
|
||||||
VMOVDQA X1, X9
|
|
||||||
|
|
||||||
VMOVDQU ·AVX_iv3<>(SB), X0
|
|
||||||
VMOVDQA X0, 0(SP)
|
|
||||||
XORQ CX, 0(SP) // 0(SP) = ·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(SP), X7
|
|
||||||
|
|
||||||
LOAD_MSG_AVX_0_2_4_6_1_3_5_7()
|
|
||||||
VMOVDQA X12, 16(SP)
|
|
||||||
VMOVDQA X13, 32(SP)
|
|
||||||
VMOVDQA X14, 48(SP)
|
|
||||||
VMOVDQA X15, 64(SP)
|
|
||||||
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(SP)
|
|
||||||
VMOVDQA X13, 96(SP)
|
|
||||||
VMOVDQA X14, 112(SP)
|
|
||||||
VMOVDQA X15, 128(SP)
|
|
||||||
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(SP)
|
|
||||||
VMOVDQA X13, 160(SP)
|
|
||||||
VMOVDQA X14, 176(SP)
|
|
||||||
VMOVDQA X15, 192(SP)
|
|
||||||
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(SP)
|
|
||||||
VMOVDQA X13, 224(SP)
|
|
||||||
VMOVDQA X14, 240(SP)
|
|
||||||
VMOVDQA X15, 256(SP)
|
|
||||||
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(SP), 32(SP), 48(SP), 64(SP), X15, X8, X9)
|
|
||||||
SHUFFLE_AVX()
|
|
||||||
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 80(SP), 96(SP), 112(SP), 128(SP), X15, X8, X9)
|
|
||||||
SHUFFLE_AVX_INV()
|
|
||||||
|
|
||||||
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 144(SP), 160(SP), 176(SP), 192(SP), X15, X8, X9)
|
|
||||||
SHUFFLE_AVX()
|
|
||||||
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 208(SP), 224(SP), 240(SP), 256(SP), 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
|
|
||||||
|
|
||||||
MOVQ BP, SP
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func supportsAVX2() bool
|
|
||||||
TEXT ·supportsAVX2(SB), 4, $0-1
|
|
||||||
MOVQ runtime·support_avx2(SB), AX
|
|
||||||
MOVB AX, ret+0(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func supportsAVX() bool
|
|
||||||
TEXT ·supportsAVX(SB), 4, $0-1
|
|
||||||
MOVQ runtime·support_avx(SB), AX
|
|
||||||
MOVB AX, ret+0(FP)
|
|
||||||
RET
|
|
25
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go
generated
vendored
25
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go
generated
vendored
|
@ -1,25 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !go1.7,amd64,!gccgo,!appengine
|
|
||||||
|
|
||||||
package blake2b
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
useSSE4 = supportsSSE4()
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func supportsSSE4() bool
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
|
||||||
|
|
||||||
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
|
|
||||||
if useSSE4 {
|
|
||||||
hashBlocksSSE4(h, c, flag, blocks)
|
|
||||||
} else {
|
|
||||||
hashBlocksGeneric(h, c, flag, blocks)
|
|
||||||
}
|
|
||||||
}
|
|
290
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
generated
vendored
290
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
generated
vendored
|
@ -1,290 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
|
||||||
|
|
||||||
#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, BP
|
|
||||||
MOVQ SP, R9
|
|
||||||
ADDQ $15, R9
|
|
||||||
ANDQ $~15, R9
|
|
||||||
MOVQ R9, SP
|
|
||||||
|
|
||||||
MOVOU ·iv3<>(SB), X0
|
|
||||||
MOVO X0, 0(SP)
|
|
||||||
XORQ CX, 0(SP) // 0(SP) = ·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(SP), X7
|
|
||||||
|
|
||||||
LOAD_MSG(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7)
|
|
||||||
MOVO X8, 16(SP)
|
|
||||||
MOVO X9, 32(SP)
|
|
||||||
MOVO X10, 48(SP)
|
|
||||||
MOVO X11, 64(SP)
|
|
||||||
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(SP)
|
|
||||||
MOVO X9, 96(SP)
|
|
||||||
MOVO X10, 112(SP)
|
|
||||||
MOVO X11, 128(SP)
|
|
||||||
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(SP)
|
|
||||||
MOVO X9, 160(SP)
|
|
||||||
MOVO X10, 176(SP)
|
|
||||||
MOVO X11, 192(SP)
|
|
||||||
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(SP)
|
|
||||||
MOVO X9, 224(SP)
|
|
||||||
MOVO X10, 240(SP)
|
|
||||||
MOVO X11, 256(SP)
|
|
||||||
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(SP), 32(SP), 48(SP), 64(SP), X11, X13, X14)
|
|
||||||
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
|
||||||
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 80(SP), 96(SP), 112(SP), 128(SP), X11, X13, X14)
|
|
||||||
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
|
||||||
|
|
||||||
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 144(SP), 160(SP), 176(SP), 192(SP), X11, X13, X14)
|
|
||||||
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
|
||||||
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 208(SP), 224(SP), 240(SP), 256(SP), 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)
|
|
||||||
|
|
||||||
MOVQ BP, SP
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func supportsSSE4() bool
|
|
||||||
TEXT ·supportsSSE4(SB), 4, $0-1
|
|
||||||
MOVL $1, AX
|
|
||||||
CPUID
|
|
||||||
SHRL $19, CX // Bit 19 indicates SSE4 support
|
|
||||||
ANDL $1, CX // CX != 0 if support SSE4
|
|
||||||
MOVB CX, ret+0(FP)
|
|
||||||
RET
|
|
179
vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
generated
vendored
179
vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
generated
vendored
|
@ -1,179 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package blake2b
|
|
||||||
|
|
||||||
import "encoding/binary"
|
|
||||||
|
|
||||||
// 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 = v12<<(64-32) | v12>>32
|
|
||||||
v8 += v12
|
|
||||||
v4 ^= v8
|
|
||||||
v4 = v4<<(64-24) | v4>>24
|
|
||||||
v1 += m[s[1]]
|
|
||||||
v1 += v5
|
|
||||||
v13 ^= v1
|
|
||||||
v13 = v13<<(64-32) | v13>>32
|
|
||||||
v9 += v13
|
|
||||||
v5 ^= v9
|
|
||||||
v5 = v5<<(64-24) | v5>>24
|
|
||||||
v2 += m[s[2]]
|
|
||||||
v2 += v6
|
|
||||||
v14 ^= v2
|
|
||||||
v14 = v14<<(64-32) | v14>>32
|
|
||||||
v10 += v14
|
|
||||||
v6 ^= v10
|
|
||||||
v6 = v6<<(64-24) | v6>>24
|
|
||||||
v3 += m[s[3]]
|
|
||||||
v3 += v7
|
|
||||||
v15 ^= v3
|
|
||||||
v15 = v15<<(64-32) | v15>>32
|
|
||||||
v11 += v15
|
|
||||||
v7 ^= v11
|
|
||||||
v7 = v7<<(64-24) | v7>>24
|
|
||||||
|
|
||||||
v0 += m[s[4]]
|
|
||||||
v0 += v4
|
|
||||||
v12 ^= v0
|
|
||||||
v12 = v12<<(64-16) | v12>>16
|
|
||||||
v8 += v12
|
|
||||||
v4 ^= v8
|
|
||||||
v4 = v4<<(64-63) | v4>>63
|
|
||||||
v1 += m[s[5]]
|
|
||||||
v1 += v5
|
|
||||||
v13 ^= v1
|
|
||||||
v13 = v13<<(64-16) | v13>>16
|
|
||||||
v9 += v13
|
|
||||||
v5 ^= v9
|
|
||||||
v5 = v5<<(64-63) | v5>>63
|
|
||||||
v2 += m[s[6]]
|
|
||||||
v2 += v6
|
|
||||||
v14 ^= v2
|
|
||||||
v14 = v14<<(64-16) | v14>>16
|
|
||||||
v10 += v14
|
|
||||||
v6 ^= v10
|
|
||||||
v6 = v6<<(64-63) | v6>>63
|
|
||||||
v3 += m[s[7]]
|
|
||||||
v3 += v7
|
|
||||||
v15 ^= v3
|
|
||||||
v15 = v15<<(64-16) | v15>>16
|
|
||||||
v11 += v15
|
|
||||||
v7 ^= v11
|
|
||||||
v7 = v7<<(64-63) | v7>>63
|
|
||||||
|
|
||||||
v0 += m[s[8]]
|
|
||||||
v0 += v5
|
|
||||||
v15 ^= v0
|
|
||||||
v15 = v15<<(64-32) | v15>>32
|
|
||||||
v10 += v15
|
|
||||||
v5 ^= v10
|
|
||||||
v5 = v5<<(64-24) | v5>>24
|
|
||||||
v1 += m[s[9]]
|
|
||||||
v1 += v6
|
|
||||||
v12 ^= v1
|
|
||||||
v12 = v12<<(64-32) | v12>>32
|
|
||||||
v11 += v12
|
|
||||||
v6 ^= v11
|
|
||||||
v6 = v6<<(64-24) | v6>>24
|
|
||||||
v2 += m[s[10]]
|
|
||||||
v2 += v7
|
|
||||||
v13 ^= v2
|
|
||||||
v13 = v13<<(64-32) | v13>>32
|
|
||||||
v8 += v13
|
|
||||||
v7 ^= v8
|
|
||||||
v7 = v7<<(64-24) | v7>>24
|
|
||||||
v3 += m[s[11]]
|
|
||||||
v3 += v4
|
|
||||||
v14 ^= v3
|
|
||||||
v14 = v14<<(64-32) | v14>>32
|
|
||||||
v9 += v14
|
|
||||||
v4 ^= v9
|
|
||||||
v4 = v4<<(64-24) | v4>>24
|
|
||||||
|
|
||||||
v0 += m[s[12]]
|
|
||||||
v0 += v5
|
|
||||||
v15 ^= v0
|
|
||||||
v15 = v15<<(64-16) | v15>>16
|
|
||||||
v10 += v15
|
|
||||||
v5 ^= v10
|
|
||||||
v5 = v5<<(64-63) | v5>>63
|
|
||||||
v1 += m[s[13]]
|
|
||||||
v1 += v6
|
|
||||||
v12 ^= v1
|
|
||||||
v12 = v12<<(64-16) | v12>>16
|
|
||||||
v11 += v12
|
|
||||||
v6 ^= v11
|
|
||||||
v6 = v6<<(64-63) | v6>>63
|
|
||||||
v2 += m[s[14]]
|
|
||||||
v2 += v7
|
|
||||||
v13 ^= v2
|
|
||||||
v13 = v13<<(64-16) | v13>>16
|
|
||||||
v8 += v13
|
|
||||||
v7 ^= v8
|
|
||||||
v7 = v7<<(64-63) | v7>>63
|
|
||||||
v3 += m[s[15]]
|
|
||||||
v3 += v4
|
|
||||||
v14 ^= v3
|
|
||||||
v14 = v14<<(64-16) | v14>>16
|
|
||||||
v9 += v14
|
|
||||||
v4 ^= v9
|
|
||||||
v4 = v4<<(64-63) | 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
|
|
||||||
}
|
|
11
vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
generated
vendored
11
vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
generated
vendored
|
@ -1,11 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !amd64 appengine gccgo
|
|
||||||
|
|
||||||
package blake2b
|
|
||||||
|
|
||||||
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
|
|
||||||
hashBlocksGeneric(h, c, flag, blocks)
|
|
||||||
}
|
|
448
vendor/golang.org/x/crypto/blake2b/blake2b_test.go
generated
vendored
448
vendor/golang.org/x/crypto/blake2b/blake2b_test.go
generated
vendored
|
@ -1,448 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package blake2b
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"hash"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func fromHex(s string) []byte {
|
|
||||||
b, err := hex.DecodeString(s)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHashes(t *testing.T) {
|
|
||||||
defer func(sse4, avx, avx2 bool) {
|
|
||||||
useSSE4, useAVX, useAVX2 = sse4, avx, avx2
|
|
||||||
}(useSSE4, useAVX, useAVX2)
|
|
||||||
|
|
||||||
if useAVX2 {
|
|
||||||
t.Log("AVX2 version")
|
|
||||||
testHashes(t)
|
|
||||||
useAVX2 = false
|
|
||||||
}
|
|
||||||
if useAVX {
|
|
||||||
t.Log("AVX version")
|
|
||||||
testHashes(t)
|
|
||||||
useAVX = false
|
|
||||||
}
|
|
||||||
if useSSE4 {
|
|
||||||
t.Log("SSE4 version")
|
|
||||||
testHashes(t)
|
|
||||||
useSSE4 = false
|
|
||||||
}
|
|
||||||
t.Log("generic version")
|
|
||||||
testHashes(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testHashes(t *testing.T) {
|
|
||||||
key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f")
|
|
||||||
|
|
||||||
input := make([]byte, 255)
|
|
||||||
for i := range input {
|
|
||||||
input[i] = byte(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, expectedHex := range hashes {
|
|
||||||
h, err := New512(key)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("#%d: error from New512: %v", i, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.Write(input[:i])
|
|
||||||
sum := h.Sum(nil)
|
|
||||||
|
|
||||||
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
|
|
||||||
t.Fatalf("#%d (single write): got %s, wanted %s", i, gotHex, expectedHex)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
for j := 0; j < i; j++ {
|
|
||||||
h.Write(input[j : j+1])
|
|
||||||
}
|
|
||||||
|
|
||||||
sum = h.Sum(sum[:0])
|
|
||||||
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
|
|
||||||
t.Fatalf("#%d (byte-by-byte): got %s, wanted %s", i, gotHex, expectedHex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateSequence(out []byte, seed uint32) {
|
|
||||||
a := 0xDEAD4BAD * seed // prime
|
|
||||||
b := uint32(1)
|
|
||||||
|
|
||||||
for i := range out { // fill the buf
|
|
||||||
a, b = b, a+b
|
|
||||||
out[i] = byte(b >> 24)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func computeMAC(msg []byte, hashSize int, key []byte) (sum []byte) {
|
|
||||||
var h hash.Hash
|
|
||||||
switch hashSize {
|
|
||||||
case Size:
|
|
||||||
h, _ = New512(key)
|
|
||||||
case Size384:
|
|
||||||
h, _ = New384(key)
|
|
||||||
case Size256:
|
|
||||||
h, _ = New256(key)
|
|
||||||
case 20:
|
|
||||||
h, _ = newDigest(20, key)
|
|
||||||
default:
|
|
||||||
panic("unexpected hashSize")
|
|
||||||
}
|
|
||||||
|
|
||||||
h.Write(msg)
|
|
||||||
return h.Sum(sum)
|
|
||||||
}
|
|
||||||
|
|
||||||
func computeHash(msg []byte, hashSize int) (sum []byte) {
|
|
||||||
switch hashSize {
|
|
||||||
case Size:
|
|
||||||
hash := Sum512(msg)
|
|
||||||
return hash[:]
|
|
||||||
case Size384:
|
|
||||||
hash := Sum384(msg)
|
|
||||||
return hash[:]
|
|
||||||
case Size256:
|
|
||||||
hash := Sum256(msg)
|
|
||||||
return hash[:]
|
|
||||||
case 20:
|
|
||||||
var hash [64]byte
|
|
||||||
checkSum(&hash, 20, msg)
|
|
||||||
return hash[:20]
|
|
||||||
default:
|
|
||||||
panic("unexpected hashSize")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test function from RFC 7693.
|
|
||||||
func TestSelfTest(t *testing.T) {
|
|
||||||
hashLens := [4]int{20, 32, 48, 64}
|
|
||||||
msgLens := [6]int{0, 3, 128, 129, 255, 1024}
|
|
||||||
|
|
||||||
msg := make([]byte, 1024)
|
|
||||||
key := make([]byte, 64)
|
|
||||||
|
|
||||||
h, _ := New256(nil)
|
|
||||||
for _, hashSize := range hashLens {
|
|
||||||
for _, msgLength := range msgLens {
|
|
||||||
generateSequence(msg[:msgLength], uint32(msgLength)) // unkeyed hash
|
|
||||||
|
|
||||||
md := computeHash(msg[:msgLength], hashSize)
|
|
||||||
h.Write(md)
|
|
||||||
|
|
||||||
generateSequence(key[:], uint32(hashSize)) // keyed hash
|
|
||||||
md = computeMAC(msg[:msgLength], hashSize, key[:hashSize])
|
|
||||||
h.Write(md)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sum := h.Sum(nil)
|
|
||||||
expected := [32]byte{
|
|
||||||
0xc2, 0x3a, 0x78, 0x00, 0xd9, 0x81, 0x23, 0xbd,
|
|
||||||
0x10, 0xf5, 0x06, 0xc6, 0x1e, 0x29, 0xda, 0x56,
|
|
||||||
0x03, 0xd7, 0x63, 0xb8, 0xbb, 0xad, 0x2e, 0x73,
|
|
||||||
0x7f, 0x5e, 0x76, 0x5a, 0x7b, 0xcc, 0xd4, 0x75,
|
|
||||||
}
|
|
||||||
if !bytes.Equal(sum, expected[:]) {
|
|
||||||
t.Fatalf("got %x, wanted %x", sum, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Benchmarks
|
|
||||||
|
|
||||||
func benchmarkSum(b *testing.B, size int) {
|
|
||||||
data := make([]byte, size)
|
|
||||||
b.SetBytes(int64(size))
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
Sum512(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkWrite(b *testing.B, size int) {
|
|
||||||
data := make([]byte, size)
|
|
||||||
h, _ := New512(nil)
|
|
||||||
b.SetBytes(int64(size))
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
h.Write(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkWrite128(b *testing.B) { benchmarkWrite(b, 128) }
|
|
||||||
func BenchmarkWrite1K(b *testing.B) { benchmarkWrite(b, 1024) }
|
|
||||||
|
|
||||||
func BenchmarkSum128(b *testing.B) { benchmarkSum(b, 128) }
|
|
||||||
func BenchmarkSum1K(b *testing.B) { benchmarkSum(b, 1024) }
|
|
||||||
|
|
||||||
// These values were taken from https://blake2.net/blake2b-test.txt.
|
|
||||||
var hashes = []string{
|
|
||||||
"10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568",
|
|
||||||
"961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd",
|
|
||||||
"da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965",
|
|
||||||
"33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1",
|
|
||||||
"beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac",
|
|
||||||
"098084b51fd13deae5f4320de94a688ee07baea2800486689a8636117b46c1f4c1f6af7f74ae7c857600456a58a3af251dc4723a64cc7c0a5ab6d9cac91c20bb",
|
|
||||||
"6044540d560853eb1c57df0077dd381094781cdb9073e5b1b3d3f6c7829e12066bbaca96d989a690de72ca3133a83652ba284a6d62942b271ffa2620c9e75b1f",
|
|
||||||
"7a8cfe9b90f75f7ecb3acc053aaed6193112b6f6a4aeeb3f65d3de541942deb9e2228152a3c4bbbe72fc3b12629528cfbb09fe630f0474339f54abf453e2ed52",
|
|
||||||
"380beaf6ea7cc9365e270ef0e6f3a64fb902acae51dd5512f84259ad2c91f4bc4108db73192a5bbfb0cbcf71e46c3e21aee1c5e860dc96e8eb0b7b8426e6abe9",
|
|
||||||
"60fe3c4535e1b59d9a61ea8500bfac41a69dffb1ceadd9aca323e9a625b64da5763bad7226da02b9c8c4f1a5de140ac5a6c1124e4f718ce0b28ea47393aa6637",
|
|
||||||
"4fe181f54ad63a2983feaaf77d1e7235c2beb17fa328b6d9505bda327df19fc37f02c4b6f0368ce23147313a8e5738b5fa2a95b29de1c7f8264eb77b69f585cd",
|
|
||||||
"f228773ce3f3a42b5f144d63237a72d99693adb8837d0e112a8a0f8ffff2c362857ac49c11ec740d1500749dac9b1f4548108bf3155794dcc9e4082849e2b85b",
|
|
||||||
"962452a8455cc56c8511317e3b1f3b2c37df75f588e94325fdd77070359cf63a9ae6e930936fdf8e1e08ffca440cfb72c28f06d89a2151d1c46cd5b268ef8563",
|
|
||||||
"43d44bfa18768c59896bf7ed1765cb2d14af8c260266039099b25a603e4ddc5039d6ef3a91847d1088d401c0c7e847781a8a590d33a3c6cb4df0fab1c2f22355",
|
|
||||||
"dcffa9d58c2a4ca2cdbb0c7aa4c4c1d45165190089f4e983bb1c2cab4aaeff1fa2b5ee516fecd780540240bf37e56c8bcca7fab980e1e61c9400d8a9a5b14ac6",
|
|
||||||
"6fbf31b45ab0c0b8dad1c0f5f4061379912dde5aa922099a030b725c73346c524291adef89d2f6fd8dfcda6d07dad811a9314536c2915ed45da34947e83de34e",
|
|
||||||
"a0c65bddde8adef57282b04b11e7bc8aab105b99231b750c021f4a735cb1bcfab87553bba3abb0c3e64a0b6955285185a0bd35fb8cfde557329bebb1f629ee93",
|
|
||||||
"f99d815550558e81eca2f96718aed10d86f3f1cfb675cce06b0eff02f617c5a42c5aa760270f2679da2677c5aeb94f1142277f21c7f79f3c4f0cce4ed8ee62b1",
|
|
||||||
"95391da8fc7b917a2044b3d6f5374e1ca072b41454d572c7356c05fd4bc1e0f40b8bb8b4a9f6bce9be2c4623c399b0dca0dab05cb7281b71a21b0ebcd9e55670",
|
|
||||||
"04b9cd3d20d221c09ac86913d3dc63041989a9a1e694f1e639a3ba7e451840f750c2fc191d56ad61f2e7936bc0ac8e094b60caeed878c18799045402d61ceaf9",
|
|
||||||
"ec0e0ef707e4ed6c0c66f9e089e4954b058030d2dd86398fe84059631f9ee591d9d77375355149178c0cf8f8e7c49ed2a5e4f95488a2247067c208510fadc44c",
|
|
||||||
"9a37cce273b79c09913677510eaf7688e89b3314d3532fd2764c39de022a2945b5710d13517af8ddc0316624e73bec1ce67df15228302036f330ab0cb4d218dd",
|
|
||||||
"4cf9bb8fb3d4de8b38b2f262d3c40f46dfe747e8fc0a414c193d9fcf753106ce47a18f172f12e8a2f1c26726545358e5ee28c9e2213a8787aafbc516d2343152",
|
|
||||||
"64e0c63af9c808fd893137129867fd91939d53f2af04be4fa268006100069b2d69daa5c5d8ed7fddcb2a70eeecdf2b105dd46a1e3b7311728f639ab489326bc9",
|
|
||||||
"5e9c93158d659b2def06b0c3c7565045542662d6eee8a96a89b78ade09fe8b3dcc096d4fe48815d88d8f82620156602af541955e1f6ca30dce14e254c326b88f",
|
|
||||||
"7775dff889458dd11aef417276853e21335eb88e4dec9cfb4e9edb49820088551a2ca60339f12066101169f0dfe84b098fddb148d9da6b3d613df263889ad64b",
|
|
||||||
"f0d2805afbb91f743951351a6d024f9353a23c7ce1fc2b051b3a8b968c233f46f50f806ecb1568ffaa0b60661e334b21dde04f8fa155ac740eeb42e20b60d764",
|
|
||||||
"86a2af316e7d7754201b942e275364ac12ea8962ab5bd8d7fb276dc5fbffc8f9a28cae4e4867df6780d9b72524160927c855da5b6078e0b554aa91e31cb9ca1d",
|
|
||||||
"10bdf0caa0802705e706369baf8a3f79d72c0a03a80675a7bbb00be3a45e516424d1ee88efb56f6d5777545ae6e27765c3a8f5e493fc308915638933a1dfee55",
|
|
||||||
"b01781092b1748459e2e4ec178696627bf4ebafebba774ecf018b79a68aeb84917bf0b84bb79d17b743151144cd66b7b33a4b9e52c76c4e112050ff5385b7f0b",
|
|
||||||
"c6dbc61dec6eaeac81e3d5f755203c8e220551534a0b2fd105a91889945a638550204f44093dd998c076205dffad703a0e5cd3c7f438a7e634cd59fededb539e",
|
|
||||||
"eba51acffb4cea31db4b8d87e9bf7dd48fe97b0253ae67aa580f9ac4a9d941f2bea518ee286818cc9f633f2a3b9fb68e594b48cdd6d515bf1d52ba6c85a203a7",
|
|
||||||
"86221f3ada52037b72224f105d7999231c5e5534d03da9d9c0a12acb68460cd375daf8e24386286f9668f72326dbf99ba094392437d398e95bb8161d717f8991",
|
|
||||||
"5595e05c13a7ec4dc8f41fb70cb50a71bce17c024ff6de7af618d0cc4e9c32d9570d6d3ea45b86525491030c0d8f2b1836d5778c1ce735c17707df364d054347",
|
|
||||||
"ce0f4f6aca89590a37fe034dd74dd5fa65eb1cbd0a41508aaddc09351a3cea6d18cb2189c54b700c009f4cbf0521c7ea01be61c5ae09cb54f27bc1b44d658c82",
|
|
||||||
"7ee80b06a215a3bca970c77cda8761822bc103d44fa4b33f4d07dcb997e36d55298bceae12241b3fa07fa63be5576068da387b8d5859aeab701369848b176d42",
|
|
||||||
"940a84b6a84d109aab208c024c6ce9647676ba0aaa11f86dbb7018f9fd2220a6d901a9027f9abcf935372727cbf09ebd61a2a2eeb87653e8ecad1bab85dc8327",
|
|
||||||
"2020b78264a82d9f4151141adba8d44bf20c5ec062eee9b595a11f9e84901bf148f298e0c9f8777dcdbc7cc4670aac356cc2ad8ccb1629f16f6a76bcefbee760",
|
|
||||||
"d1b897b0e075ba68ab572adf9d9c436663e43eb3d8e62d92fc49c9be214e6f27873fe215a65170e6bea902408a25b49506f47babd07cecf7113ec10c5dd31252",
|
|
||||||
"b14d0c62abfa469a357177e594c10c194243ed2025ab8aa5ad2fa41ad318e0ff48cd5e60bec07b13634a711d2326e488a985f31e31153399e73088efc86a5c55",
|
|
||||||
"4169c5cc808d2697dc2a82430dc23e3cd356dc70a94566810502b8d655b39abf9e7f902fe717e0389219859e1945df1af6ada42e4ccda55a197b7100a30c30a1",
|
|
||||||
"258a4edb113d66c839c8b1c91f15f35ade609f11cd7f8681a4045b9fef7b0b24c82cda06a5f2067b368825e3914e53d6948ede92efd6e8387fa2e537239b5bee",
|
|
||||||
"79d2d8696d30f30fb34657761171a11e6c3f1e64cbe7bebee159cb95bfaf812b4f411e2f26d9c421dc2c284a3342d823ec293849e42d1e46b0a4ac1e3c86abaa",
|
|
||||||
"8b9436010dc5dee992ae38aea97f2cd63b946d94fedd2ec9671dcde3bd4ce9564d555c66c15bb2b900df72edb6b891ebcadfeff63c9ea4036a998be7973981e7",
|
|
||||||
"c8f68e696ed28242bf997f5b3b34959508e42d613810f1e2a435c96ed2ff560c7022f361a9234b9837feee90bf47922ee0fd5f8ddf823718d86d1e16c6090071",
|
|
||||||
"b02d3eee4860d5868b2c39ce39bfe81011290564dd678c85e8783f29302dfc1399ba95b6b53cd9ebbf400cca1db0ab67e19a325f2d115812d25d00978ad1bca4",
|
|
||||||
"7693ea73af3ac4dad21ca0d8da85b3118a7d1c6024cfaf557699868217bc0c2f44a199bc6c0edd519798ba05bd5b1b4484346a47c2cadf6bf30b785cc88b2baf",
|
|
||||||
"a0e5c1c0031c02e48b7f09a5e896ee9aef2f17fc9e18e997d7f6cac7ae316422c2b1e77984e5f3a73cb45deed5d3f84600105e6ee38f2d090c7d0442ea34c46d",
|
|
||||||
"41daa6adcfdb69f1440c37b596440165c15ada596813e2e22f060fcd551f24dee8e04ba6890387886ceec4a7a0d7fc6b44506392ec3822c0d8c1acfc7d5aebe8",
|
|
||||||
"14d4d40d5984d84c5cf7523b7798b254e275a3a8cc0a1bd06ebc0bee726856acc3cbf516ff667cda2058ad5c3412254460a82c92187041363cc77a4dc215e487",
|
|
||||||
"d0e7a1e2b9a447fee83e2277e9ff8010c2f375ae12fa7aaa8ca5a6317868a26a367a0b69fbc1cf32a55d34eb370663016f3d2110230eba754028a56f54acf57c",
|
|
||||||
"e771aa8db5a3e043e8178f39a0857ba04a3f18e4aa05743cf8d222b0b095825350ba422f63382a23d92e4149074e816a36c1cd28284d146267940b31f8818ea2",
|
|
||||||
"feb4fd6f9e87a56bef398b3284d2bda5b5b0e166583a66b61e538457ff0584872c21a32962b9928ffab58de4af2edd4e15d8b35570523207ff4e2a5aa7754caa",
|
|
||||||
"462f17bf005fb1c1b9e671779f665209ec2873e3e411f98dabf240a1d5ec3f95ce6796b6fc23fe171903b502023467dec7273ff74879b92967a2a43a5a183d33",
|
|
||||||
"d3338193b64553dbd38d144bea71c5915bb110e2d88180dbc5db364fd6171df317fc7268831b5aef75e4342b2fad8797ba39eddcef80e6ec08159350b1ad696d",
|
|
||||||
"e1590d585a3d39f7cb599abd479070966409a6846d4377acf4471d065d5db94129cc9be92573b05ed226be1e9b7cb0cabe87918589f80dadd4ef5ef25a93d28e",
|
|
||||||
"f8f3726ac5a26cc80132493a6fedcb0e60760c09cfc84cad178175986819665e76842d7b9fedf76dddebf5d3f56faaad4477587af21606d396ae570d8e719af2",
|
|
||||||
"30186055c07949948183c850e9a756cc09937e247d9d928e869e20bafc3cd9721719d34e04a0899b92c736084550186886efba2e790d8be6ebf040b209c439a4",
|
|
||||||
"f3c4276cb863637712c241c444c5cc1e3554e0fddb174d035819dd83eb700b4ce88df3ab3841ba02085e1a99b4e17310c5341075c0458ba376c95a6818fbb3e2",
|
|
||||||
"0aa007c4dd9d5832393040a1583c930bca7dc5e77ea53add7e2b3f7c8e231368043520d4a3ef53c969b6bbfd025946f632bd7f765d53c21003b8f983f75e2a6a",
|
|
||||||
"08e9464720533b23a04ec24f7ae8c103145f765387d738777d3d343477fd1c58db052142cab754ea674378e18766c53542f71970171cc4f81694246b717d7564",
|
|
||||||
"d37ff7ad297993e7ec21e0f1b4b5ae719cdc83c5db687527f27516cbffa822888a6810ee5c1ca7bfe3321119be1ab7bfa0a502671c8329494df7ad6f522d440f",
|
|
||||||
"dd9042f6e464dcf86b1262f6accfafbd8cfd902ed3ed89abf78ffa482dbdeeb6969842394c9a1168ae3d481a017842f660002d42447c6b22f7b72f21aae021c9",
|
|
||||||
"bd965bf31e87d70327536f2a341cebc4768eca275fa05ef98f7f1b71a0351298de006fba73fe6733ed01d75801b4a928e54231b38e38c562b2e33ea1284992fa",
|
|
||||||
"65676d800617972fbd87e4b9514e1c67402b7a331096d3bfac22f1abb95374abc942f16e9ab0ead33b87c91968a6e509e119ff07787b3ef483e1dcdccf6e3022",
|
|
||||||
"939fa189699c5d2c81ddd1ffc1fa207c970b6a3685bb29ce1d3e99d42f2f7442da53e95a72907314f4588399a3ff5b0a92beb3f6be2694f9f86ecf2952d5b41c",
|
|
||||||
"c516541701863f91005f314108ceece3c643e04fc8c42fd2ff556220e616aaa6a48aeb97a84bad74782e8dff96a1a2fa949339d722edcaa32b57067041df88cc",
|
|
||||||
"987fd6e0d6857c553eaebb3d34970a2c2f6e89a3548f492521722b80a1c21a153892346d2cba6444212d56da9a26e324dccbc0dcde85d4d2ee4399eec5a64e8f",
|
|
||||||
"ae56deb1c2328d9c4017706bce6e99d41349053ba9d336d677c4c27d9fd50ae6aee17e853154e1f4fe7672346da2eaa31eea53fcf24a22804f11d03da6abfc2b",
|
|
||||||
"49d6a608c9bde4491870498572ac31aac3fa40938b38a7818f72383eb040ad39532bc06571e13d767e6945ab77c0bdc3b0284253343f9f6c1244ebf2ff0df866",
|
|
||||||
"da582ad8c5370b4469af862aa6467a2293b2b28bd80ae0e91f425ad3d47249fdf98825cc86f14028c3308c9804c78bfeeeee461444ce243687e1a50522456a1d",
|
|
||||||
"d5266aa3331194aef852eed86d7b5b2633a0af1c735906f2e13279f14931a9fc3b0eac5ce9245273bd1aa92905abe16278ef7efd47694789a7283b77da3c70f8",
|
|
||||||
"2962734c28252186a9a1111c732ad4de4506d4b4480916303eb7991d659ccda07a9911914bc75c418ab7a4541757ad054796e26797feaf36e9f6ad43f14b35a4",
|
|
||||||
"e8b79ec5d06e111bdfafd71e9f5760f00ac8ac5d8bf768f9ff6f08b8f026096b1cc3a4c973333019f1e3553e77da3f98cb9f542e0a90e5f8a940cc58e59844b3",
|
|
||||||
"dfb320c44f9d41d1efdcc015f08dd5539e526e39c87d509ae6812a969e5431bf4fa7d91ffd03b981e0d544cf72d7b1c0374f8801482e6dea2ef903877eba675e",
|
|
||||||
"d88675118fdb55a5fb365ac2af1d217bf526ce1ee9c94b2f0090b2c58a06ca58187d7fe57c7bed9d26fca067b4110eefcd9a0a345de872abe20de368001b0745",
|
|
||||||
"b893f2fc41f7b0dd6e2f6aa2e0370c0cff7df09e3acfcc0e920b6e6fad0ef747c40668417d342b80d2351e8c175f20897a062e9765e6c67b539b6ba8b9170545",
|
|
||||||
"6c67ec5697accd235c59b486d7b70baeedcbd4aa64ebd4eef3c7eac189561a726250aec4d48cadcafbbe2ce3c16ce2d691a8cce06e8879556d4483ed7165c063",
|
|
||||||
"f1aa2b044f8f0c638a3f362e677b5d891d6fd2ab0765f6ee1e4987de057ead357883d9b405b9d609eea1b869d97fb16d9b51017c553f3b93c0a1e0f1296fedcd",
|
|
||||||
"cbaa259572d4aebfc1917acddc582b9f8dfaa928a198ca7acd0f2aa76a134a90252e6298a65b08186a350d5b7626699f8cb721a3ea5921b753ae3a2dce24ba3a",
|
|
||||||
"fa1549c9796cd4d303dcf452c1fbd5744fd9b9b47003d920b92de34839d07ef2a29ded68f6fc9e6c45e071a2e48bd50c5084e96b657dd0404045a1ddefe282ed",
|
|
||||||
"5cf2ac897ab444dcb5c8d87c495dbdb34e1838b6b629427caa51702ad0f9688525f13bec503a3c3a2c80a65e0b5715e8afab00ffa56ec455a49a1ad30aa24fcd",
|
|
||||||
"9aaf80207bace17bb7ab145757d5696bde32406ef22b44292ef65d4519c3bb2ad41a59b62cc3e94b6fa96d32a7faadae28af7d35097219aa3fd8cda31e40c275",
|
|
||||||
"af88b163402c86745cb650c2988fb95211b94b03ef290eed9662034241fd51cf398f8073e369354c43eae1052f9b63b08191caa138aa54fea889cc7024236897",
|
|
||||||
"48fa7d64e1ceee27b9864db5ada4b53d00c9bc7626555813d3cd6730ab3cc06ff342d727905e33171bde6e8476e77fb1720861e94b73a2c538d254746285f430",
|
|
||||||
"0e6fd97a85e904f87bfe85bbeb34f69e1f18105cf4ed4f87aec36c6e8b5f68bd2a6f3dc8a9ecb2b61db4eedb6b2ea10bf9cb0251fb0f8b344abf7f366b6de5ab",
|
|
||||||
"06622da5787176287fdc8fed440bad187d830099c94e6d04c8e9c954cda70c8bb9e1fc4a6d0baa831b9b78ef6648681a4867a11da93ee36e5e6a37d87fc63f6f",
|
|
||||||
"1da6772b58fabf9c61f68d412c82f182c0236d7d575ef0b58dd22458d643cd1dfc93b03871c316d8430d312995d4197f0874c99172ba004a01ee295abac24e46",
|
|
||||||
"3cd2d9320b7b1d5fb9aab951a76023fa667be14a9124e394513918a3f44096ae4904ba0ffc150b63bc7ab1eeb9a6e257e5c8f000a70394a5afd842715de15f29",
|
|
||||||
"04cdc14f7434e0b4be70cb41db4c779a88eaef6accebcb41f2d42fffe7f32a8e281b5c103a27021d0d08362250753cdf70292195a53a48728ceb5844c2d98bab",
|
|
||||||
"9071b7a8a075d0095b8fb3ae5113785735ab98e2b52faf91d5b89e44aac5b5d4ebbf91223b0ff4c71905da55342e64655d6ef8c89a4768c3f93a6dc0366b5bc8",
|
|
||||||
"ebb30240dd96c7bc8d0abe49aa4edcbb4afdc51ff9aaf720d3f9e7fbb0f9c6d6571350501769fc4ebd0b2141247ff400d4fd4be414edf37757bb90a32ac5c65a",
|
|
||||||
"8532c58bf3c8015d9d1cbe00eef1f5082f8f3632fbe9f1ed4f9dfb1fa79e8283066d77c44c4af943d76b300364aecbd0648c8a8939bd204123f4b56260422dec",
|
|
||||||
"fe9846d64f7c7708696f840e2d76cb4408b6595c2f81ec6a28a7f2f20cb88cfe6ac0b9e9b8244f08bd7095c350c1d0842f64fb01bb7f532dfcd47371b0aeeb79",
|
|
||||||
"28f17ea6fb6c42092dc264257e29746321fb5bdaea9873c2a7fa9d8f53818e899e161bc77dfe8090afd82bf2266c5c1bc930a8d1547624439e662ef695f26f24",
|
|
||||||
"ec6b7d7f030d4850acae3cb615c21dd25206d63e84d1db8d957370737ba0e98467ea0ce274c66199901eaec18a08525715f53bfdb0aacb613d342ebdceeddc3b",
|
|
||||||
"b403d3691c03b0d3418df327d5860d34bbfcc4519bfbce36bf33b208385fadb9186bc78a76c489d89fd57e7dc75412d23bcd1dae8470ce9274754bb8585b13c5",
|
|
||||||
"31fc79738b8772b3f55cd8178813b3b52d0db5a419d30ba9495c4b9da0219fac6df8e7c23a811551a62b827f256ecdb8124ac8a6792ccfecc3b3012722e94463",
|
|
||||||
"bb2039ec287091bcc9642fc90049e73732e02e577e2862b32216ae9bedcd730c4c284ef3968c368b7d37584f97bd4b4dc6ef6127acfe2e6ae2509124e66c8af4",
|
|
||||||
"f53d68d13f45edfcb9bd415e2831e938350d5380d3432278fc1c0c381fcb7c65c82dafe051d8c8b0d44e0974a0e59ec7bf7ed0459f86e96f329fc79752510fd3",
|
|
||||||
"8d568c7984f0ecdf7640fbc483b5d8c9f86634f6f43291841b309a350ab9c1137d24066b09da9944bac54d5bb6580d836047aac74ab724b887ebf93d4b32eca9",
|
|
||||||
"c0b65ce5a96ff774c456cac3b5f2c4cd359b4ff53ef93a3da0778be4900d1e8da1601e769e8f1b02d2a2f8c5b9fa10b44f1c186985468feeb008730283a6657d",
|
|
||||||
"4900bba6f5fb103ece8ec96ada13a5c3c85488e05551da6b6b33d988e611ec0fe2e3c2aa48ea6ae8986a3a231b223c5d27cec2eadde91ce07981ee652862d1e4",
|
|
||||||
"c7f5c37c7285f927f76443414d4357ff789647d7a005a5a787e03c346b57f49f21b64fa9cf4b7e45573e23049017567121a9c3d4b2b73ec5e9413577525db45a",
|
|
||||||
"ec7096330736fdb2d64b5653e7475da746c23a4613a82687a28062d3236364284ac01720ffb406cfe265c0df626a188c9e5963ace5d3d5bb363e32c38c2190a6",
|
|
||||||
"82e744c75f4649ec52b80771a77d475a3bc091989556960e276a5f9ead92a03f718742cdcfeaee5cb85c44af198adc43a4a428f5f0c2ddb0be36059f06d7df73",
|
|
||||||
"2834b7a7170f1f5b68559ab78c1050ec21c919740b784a9072f6e5d69f828d70c919c5039fb148e39e2c8a52118378b064ca8d5001cd10a5478387b966715ed6",
|
|
||||||
"16b4ada883f72f853bb7ef253efcab0c3e2161687ad61543a0d2824f91c1f81347d86be709b16996e17f2dd486927b0288ad38d13063c4a9672c39397d3789b6",
|
|
||||||
"78d048f3a69d8b54ae0ed63a573ae350d89f7c6cf1f3688930de899afa037697629b314e5cd303aa62feea72a25bf42b304b6c6bcb27fae21c16d925e1fbdac3",
|
|
||||||
"0f746a48749287ada77a82961f05a4da4abdb7d77b1220f836d09ec814359c0ec0239b8c7b9ff9e02f569d1b301ef67c4612d1de4f730f81c12c40cc063c5caa",
|
|
||||||
"f0fc859d3bd195fbdc2d591e4cdac15179ec0f1dc821c11df1f0c1d26e6260aaa65b79fafacafd7d3ad61e600f250905f5878c87452897647a35b995bcadc3a3",
|
|
||||||
"2620f687e8625f6a412460b42e2cef67634208ce10a0cbd4dff7044a41b7880077e9f8dc3b8d1216d3376a21e015b58fb279b521d83f9388c7382c8505590b9b",
|
|
||||||
"227e3aed8d2cb10b918fcb04f9de3e6d0a57e08476d93759cd7b2ed54a1cbf0239c528fb04bbf288253e601d3bc38b21794afef90b17094a182cac557745e75f",
|
|
||||||
"1a929901b09c25f27d6b35be7b2f1c4745131fdebca7f3e2451926720434e0db6e74fd693ad29b777dc3355c592a361c4873b01133a57c2e3b7075cbdb86f4fc",
|
|
||||||
"5fd7968bc2fe34f220b5e3dc5af9571742d73b7d60819f2888b629072b96a9d8ab2d91b82d0a9aaba61bbd39958132fcc4257023d1eca591b3054e2dc81c8200",
|
|
||||||
"dfcce8cf32870cc6a503eadafc87fd6f78918b9b4d0737db6810be996b5497e7e5cc80e312f61e71ff3e9624436073156403f735f56b0b01845c18f6caf772e6",
|
|
||||||
"02f7ef3a9ce0fff960f67032b296efca3061f4934d690749f2d01c35c81c14f39a67fa350bc8a0359bf1724bffc3bca6d7c7bba4791fd522a3ad353c02ec5aa8",
|
|
||||||
"64be5c6aba65d594844ae78bb022e5bebe127fd6b6ffa5a13703855ab63b624dcd1a363f99203f632ec386f3ea767fc992e8ed9686586aa27555a8599d5b808f",
|
|
||||||
"f78585505c4eaa54a8b5be70a61e735e0ff97af944ddb3001e35d86c4e2199d976104b6ae31750a36a726ed285064f5981b503889fef822fcdc2898dddb7889a",
|
|
||||||
"e4b5566033869572edfd87479a5bb73c80e8759b91232879d96b1dda36c012076ee5a2ed7ae2de63ef8406a06aea82c188031b560beafb583fb3de9e57952a7e",
|
|
||||||
"e1b3e7ed867f6c9484a2a97f7715f25e25294e992e41f6a7c161ffc2adc6daaeb7113102d5e6090287fe6ad94ce5d6b739c6ca240b05c76fb73f25dd024bf935",
|
|
||||||
"85fd085fdc12a080983df07bd7012b0d402a0f4043fcb2775adf0bad174f9b08d1676e476985785c0a5dcc41dbff6d95ef4d66a3fbdc4a74b82ba52da0512b74",
|
|
||||||
"aed8fa764b0fbff821e05233d2f7b0900ec44d826f95e93c343c1bc3ba5a24374b1d616e7e7aba453a0ada5e4fab5382409e0d42ce9c2bc7fb39a99c340c20f0",
|
|
||||||
"7ba3b2e297233522eeb343bd3ebcfd835a04007735e87f0ca300cbee6d416565162171581e4020ff4cf176450f1291ea2285cb9ebffe4c56660627685145051c",
|
|
||||||
"de748bcf89ec88084721e16b85f30adb1a6134d664b5843569babc5bbd1a15ca9b61803c901a4fef32965a1749c9f3a4e243e173939dc5a8dc495c671ab52145",
|
|
||||||
"aaf4d2bdf200a919706d9842dce16c98140d34bc433df320aba9bd429e549aa7a3397652a4d768277786cf993cde2338673ed2e6b66c961fefb82cd20c93338f",
|
|
||||||
"c408218968b788bf864f0997e6bc4c3dba68b276e2125a4843296052ff93bf5767b8cdce7131f0876430c1165fec6c4f47adaa4fd8bcfacef463b5d3d0fa61a0",
|
|
||||||
"76d2d819c92bce55fa8e092ab1bf9b9eab237a25267986cacf2b8ee14d214d730dc9a5aa2d7b596e86a1fd8fa0804c77402d2fcd45083688b218b1cdfa0dcbcb",
|
|
||||||
"72065ee4dd91c2d8509fa1fc28a37c7fc9fa7d5b3f8ad3d0d7a25626b57b1b44788d4caf806290425f9890a3a2a35a905ab4b37acfd0da6e4517b2525c9651e4",
|
|
||||||
"64475dfe7600d7171bea0b394e27c9b00d8e74dd1e416a79473682ad3dfdbb706631558055cfc8a40e07bd015a4540dcdea15883cbbf31412df1de1cd4152b91",
|
|
||||||
"12cd1674a4488a5d7c2b3160d2e2c4b58371bedad793418d6f19c6ee385d70b3e06739369d4df910edb0b0a54cbff43d54544cd37ab3a06cfa0a3ddac8b66c89",
|
|
||||||
"60756966479dedc6dd4bcff8ea7d1d4ce4d4af2e7b097e32e3763518441147cc12b3c0ee6d2ecabf1198cec92e86a3616fba4f4e872f5825330adbb4c1dee444",
|
|
||||||
"a7803bcb71bc1d0f4383dde1e0612e04f872b715ad30815c2249cf34abb8b024915cb2fc9f4e7cc4c8cfd45be2d5a91eab0941c7d270e2da4ca4a9f7ac68663a",
|
|
||||||
"b84ef6a7229a34a750d9a98ee2529871816b87fbe3bc45b45fa5ae82d5141540211165c3c5d7a7476ba5a4aa06d66476f0d9dc49a3f1ee72c3acabd498967414",
|
|
||||||
"fae4b6d8efc3f8c8e64d001dabec3a21f544e82714745251b2b4b393f2f43e0da3d403c64db95a2cb6e23ebb7b9e94cdd5ddac54f07c4a61bd3cb10aa6f93b49",
|
|
||||||
"34f7286605a122369540141ded79b8957255da2d4155abbf5a8dbb89c8eb7ede8eeef1daa46dc29d751d045dc3b1d658bb64b80ff8589eddb3824b13da235a6b",
|
|
||||||
"3b3b48434be27b9eababba43bf6b35f14b30f6a88dc2e750c358470d6b3aa3c18e47db4017fa55106d8252f016371a00f5f8b070b74ba5f23cffc5511c9f09f0",
|
|
||||||
"ba289ebd6562c48c3e10a8ad6ce02e73433d1e93d7c9279d4d60a7e879ee11f441a000f48ed9f7c4ed87a45136d7dccdca482109c78a51062b3ba4044ada2469",
|
|
||||||
"022939e2386c5a37049856c850a2bb10a13dfea4212b4c732a8840a9ffa5faf54875c5448816b2785a007da8a8d2bc7d71a54e4e6571f10b600cbdb25d13ede3",
|
|
||||||
"e6fec19d89ce8717b1a087024670fe026f6c7cbda11caef959bb2d351bf856f8055d1c0ebdaaa9d1b17886fc2c562b5e99642fc064710c0d3488a02b5ed7f6fd",
|
|
||||||
"94c96f02a8f576aca32ba61c2b206f907285d9299b83ac175c209a8d43d53bfe683dd1d83e7549cb906c28f59ab7c46f8751366a28c39dd5fe2693c9019666c8",
|
|
||||||
"31a0cd215ebd2cb61de5b9edc91e6195e31c59a5648d5c9f737e125b2605708f2e325ab3381c8dce1a3e958886f1ecdc60318f882cfe20a24191352e617b0f21",
|
|
||||||
"91ab504a522dce78779f4c6c6ba2e6b6db5565c76d3e7e7c920caf7f757ef9db7c8fcf10e57f03379ea9bf75eb59895d96e149800b6aae01db778bb90afbc989",
|
|
||||||
"d85cabc6bd5b1a01a5afd8c6734740da9fd1c1acc6db29bfc8a2e5b668b028b6b3154bfb8703fa3180251d589ad38040ceb707c4bad1b5343cb426b61eaa49c1",
|
|
||||||
"d62efbec2ca9c1f8bd66ce8b3f6a898cb3f7566ba6568c618ad1feb2b65b76c3ce1dd20f7395372faf28427f61c9278049cf0140df434f5633048c86b81e0399",
|
|
||||||
"7c8fdc6175439e2c3db15bafa7fb06143a6a23bc90f449e79deef73c3d492a671715c193b6fea9f036050b946069856b897e08c00768f5ee5ddcf70b7cd6d0e0",
|
|
||||||
"58602ee7468e6bc9df21bd51b23c005f72d6cb013f0a1b48cbec5eca299299f97f09f54a9a01483eaeb315a6478bad37ba47ca1347c7c8fc9e6695592c91d723",
|
|
||||||
"27f5b79ed256b050993d793496edf4807c1d85a7b0a67c9c4fa99860750b0ae66989670a8ffd7856d7ce411599e58c4d77b232a62bef64d15275be46a68235ff",
|
|
||||||
"3957a976b9f1887bf004a8dca942c92d2b37ea52600f25e0c9bc5707d0279c00c6e85a839b0d2d8eb59c51d94788ebe62474a791cadf52cccf20f5070b6573fc",
|
|
||||||
"eaa2376d55380bf772ecca9cb0aa4668c95c707162fa86d518c8ce0ca9bf7362b9f2a0adc3ff59922df921b94567e81e452f6c1a07fc817cebe99604b3505d38",
|
|
||||||
"c1e2c78b6b2734e2480ec550434cb5d613111adcc21d475545c3b1b7e6ff12444476e5c055132e2229dc0f807044bb919b1a5662dd38a9ee65e243a3911aed1a",
|
|
||||||
"8ab48713389dd0fcf9f965d3ce66b1e559a1f8c58741d67683cd971354f452e62d0207a65e436c5d5d8f8ee71c6abfe50e669004c302b31a7ea8311d4a916051",
|
|
||||||
"24ce0addaa4c65038bd1b1c0f1452a0b128777aabc94a29df2fd6c7e2f85f8ab9ac7eff516b0e0a825c84a24cfe492eaad0a6308e46dd42fe8333ab971bb30ca",
|
|
||||||
"5154f929ee03045b6b0c0004fa778edee1d139893267cc84825ad7b36c63de32798e4a166d24686561354f63b00709a1364b3c241de3febf0754045897467cd4",
|
|
||||||
"e74e907920fd87bd5ad636dd11085e50ee70459c443e1ce5809af2bc2eba39f9e6d7128e0e3712c316da06f4705d78a4838e28121d4344a2c79c5e0db307a677",
|
|
||||||
"bf91a22334bac20f3fd80663b3cd06c4e8802f30e6b59f90d3035cc9798a217ed5a31abbda7fa6842827bdf2a7a1c21f6fcfccbb54c6c52926f32da816269be1",
|
|
||||||
"d9d5c74be5121b0bd742f26bffb8c89f89171f3f934913492b0903c271bbe2b3395ef259669bef43b57f7fcc3027db01823f6baee66e4f9fead4d6726c741fce",
|
|
||||||
"50c8b8cf34cd879f80e2faab3230b0c0e1cc3e9dcadeb1b9d97ab923415dd9a1fe38addd5c11756c67990b256e95ad6d8f9fedce10bf1c90679cde0ecf1be347",
|
|
||||||
"0a386e7cd5dd9b77a035e09fe6fee2c8ce61b5383c87ea43205059c5e4cd4f4408319bb0a82360f6a58e6c9ce3f487c446063bf813bc6ba535e17fc1826cfc91",
|
|
||||||
"1f1459cb6b61cbac5f0efe8fc487538f42548987fcd56221cfa7beb22504769e792c45adfb1d6b3d60d7b749c8a75b0bdf14e8ea721b95dca538ca6e25711209",
|
|
||||||
"e58b3836b7d8fedbb50ca5725c6571e74c0785e97821dab8b6298c10e4c079d4a6cdf22f0fedb55032925c16748115f01a105e77e00cee3d07924dc0d8f90659",
|
|
||||||
"b929cc6505f020158672deda56d0db081a2ee34c00c1100029bdf8ea98034fa4bf3e8655ec697fe36f40553c5bb46801644a627d3342f4fc92b61f03290fb381",
|
|
||||||
"72d353994b49d3e03153929a1e4d4f188ee58ab9e72ee8e512f29bc773913819ce057ddd7002c0433ee0a16114e3d156dd2c4a7e80ee53378b8670f23e33ef56",
|
|
||||||
"c70ef9bfd775d408176737a0736d68517ce1aaad7e81a93c8c1ed967ea214f56c8a377b1763e676615b60f3988241eae6eab9685a5124929d28188f29eab06f7",
|
|
||||||
"c230f0802679cb33822ef8b3b21bf7a9a28942092901d7dac3760300831026cf354c9232df3e084d9903130c601f63c1f4a4a4b8106e468cd443bbe5a734f45f",
|
|
||||||
"6f43094cafb5ebf1f7a4937ec50f56a4c9da303cbb55ac1f27f1f1976cd96beda9464f0e7b9c54620b8a9fba983164b8be3578425a024f5fe199c36356b88972",
|
|
||||||
"3745273f4c38225db2337381871a0c6aafd3af9b018c88aa02025850a5dc3a42a1a3e03e56cbf1b0876d63a441f1d2856a39b8801eb5af325201c415d65e97fe",
|
|
||||||
"c50c44cca3ec3edaae779a7e179450ebdda2f97067c690aa6c5a4ac7c30139bb27c0df4db3220e63cb110d64f37ffe078db72653e2daacf93ae3f0a2d1a7eb2e",
|
|
||||||
"8aef263e385cbc61e19b28914243262af5afe8726af3ce39a79c27028cf3ecd3f8d2dfd9cfc9ad91b58f6f20778fd5f02894a3d91c7d57d1e4b866a7f364b6be",
|
|
||||||
"28696141de6e2d9bcb3235578a66166c1448d3e905a1b482d423be4bc5369bc8c74dae0acc9cc123e1d8ddce9f97917e8c019c552da32d39d2219b9abf0fa8c8",
|
|
||||||
"2fb9eb2085830181903a9dafe3db428ee15be7662224efd643371fb25646aee716e531eca69b2bdc8233f1a8081fa43da1500302975a77f42fa592136710e9dc",
|
|
||||||
"66f9a7143f7a3314a669bf2e24bbb35014261d639f495b6c9c1f104fe8e320aca60d4550d69d52edbd5a3cdeb4014ae65b1d87aa770b69ae5c15f4330b0b0ad8",
|
|
||||||
"f4c4dd1d594c3565e3e25ca43dad82f62abea4835ed4cd811bcd975e46279828d44d4c62c3679f1b7f7b9dd4571d7b49557347b8c5460cbdc1bef690fb2a08c0",
|
|
||||||
"8f1dc9649c3a84551f8f6e91cac68242a43b1f8f328ee92280257387fa7559aa6db12e4aeadc2d26099178749c6864b357f3f83b2fb3efa8d2a8db056bed6bcc",
|
|
||||||
"3139c1a7f97afd1675d460ebbc07f2728aa150df849624511ee04b743ba0a833092f18c12dc91b4dd243f333402f59fe28abdbbbae301e7b659c7a26d5c0f979",
|
|
||||||
"06f94a2996158a819fe34c40de3cf0379fd9fb85b3e363ba3926a0e7d960e3f4c2e0c70c7ce0ccb2a64fc29869f6e7ab12bd4d3f14fce943279027e785fb5c29",
|
|
||||||
"c29c399ef3eee8961e87565c1ce263925fc3d0ce267d13e48dd9e732ee67b0f69fad56401b0f10fcaac119201046cca28c5b14abdea3212ae65562f7f138db3d",
|
|
||||||
"4cec4c9df52eef05c3f6faaa9791bc7445937183224ecc37a1e58d0132d35617531d7e795f52af7b1eb9d147de1292d345fe341823f8e6bc1e5badca5c656108",
|
|
||||||
"898bfbae93b3e18d00697eab7d9704fa36ec339d076131cefdf30edbe8d9cc81c3a80b129659b163a323bab9793d4feed92d54dae966c77529764a09be88db45",
|
|
||||||
"ee9bd0469d3aaf4f14035be48a2c3b84d9b4b1fff1d945e1f1c1d38980a951be197b25fe22c731f20aeacc930ba9c4a1f4762227617ad350fdabb4e80273a0f4",
|
|
||||||
"3d4d3113300581cd96acbf091c3d0f3c310138cd6979e6026cde623e2dd1b24d4a8638bed1073344783ad0649cc6305ccec04beb49f31c633088a99b65130267",
|
|
||||||
"95c0591ad91f921ac7be6d9ce37e0663ed8011c1cfd6d0162a5572e94368bac02024485e6a39854aa46fe38e97d6c6b1947cd272d86b06bb5b2f78b9b68d559d",
|
|
||||||
"227b79ded368153bf46c0a3ca978bfdbef31f3024a5665842468490b0ff748ae04e7832ed4c9f49de9b1706709d623e5c8c15e3caecae8d5e433430ff72f20eb",
|
|
||||||
"5d34f3952f0105eef88ae8b64c6ce95ebfade0e02c69b08762a8712d2e4911ad3f941fc4034dc9b2e479fdbcd279b902faf5d838bb2e0c6495d372b5b7029813",
|
|
||||||
"7f939bf8353abce49e77f14f3750af20b7b03902e1a1e7fb6aaf76d0259cd401a83190f15640e74f3e6c5a90e839c7821f6474757f75c7bf9002084ddc7a62dc",
|
|
||||||
"062b61a2f9a33a71d7d0a06119644c70b0716a504de7e5e1be49bd7b86e7ed6817714f9f0fc313d06129597e9a2235ec8521de36f7290a90ccfc1ffa6d0aee29",
|
|
||||||
"f29e01eeae64311eb7f1c6422f946bf7bea36379523e7b2bbaba7d1d34a22d5ea5f1c5a09d5ce1fe682cced9a4798d1a05b46cd72dff5c1b355440b2a2d476bc",
|
|
||||||
"ec38cd3bbab3ef35d7cb6d5c914298351d8a9dc97fcee051a8a02f58e3ed6184d0b7810a5615411ab1b95209c3c810114fdeb22452084e77f3f847c6dbaafe16",
|
|
||||||
"c2aef5e0ca43e82641565b8cb943aa8ba53550caef793b6532fafad94b816082f0113a3ea2f63608ab40437ecc0f0229cb8fa224dcf1c478a67d9b64162b92d1",
|
|
||||||
"15f534efff7105cd1c254d074e27d5898b89313b7d366dc2d7d87113fa7d53aae13f6dba487ad8103d5e854c91fdb6e1e74b2ef6d1431769c30767dde067a35c",
|
|
||||||
"89acbca0b169897a0a2714c2df8c95b5b79cb69390142b7d6018bb3e3076b099b79a964152a9d912b1b86412b7e372e9cecad7f25d4cbab8a317be36492a67d7",
|
|
||||||
"e3c0739190ed849c9c962fd9dbb55e207e624fcac1eb417691515499eea8d8267b7e8f1287a63633af5011fde8c4ddf55bfdf722edf88831414f2cfaed59cb9a",
|
|
||||||
"8d6cf87c08380d2d1506eee46fd4222d21d8c04e585fbfd08269c98f702833a156326a0724656400ee09351d57b440175e2a5de93cc5f80db6daf83576cf75fa",
|
|
||||||
"da24bede383666d563eeed37f6319baf20d5c75d1635a6ba5ef4cfa1ac95487e96f8c08af600aab87c986ebad49fc70a58b4890b9c876e091016daf49e1d322e",
|
|
||||||
"f9d1d1b1e87ea7ae753a029750cc1cf3d0157d41805e245c5617bb934e732f0ae3180b78e05bfe76c7c3051e3e3ac78b9b50c05142657e1e03215d6ec7bfd0fc",
|
|
||||||
"11b7bc1668032048aa43343de476395e814bbbc223678db951a1b03a021efac948cfbe215f97fe9a72a2f6bc039e3956bfa417c1a9f10d6d7ba5d3d32ff323e5",
|
|
||||||
"b8d9000e4fc2b066edb91afee8e7eb0f24e3a201db8b6793c0608581e628ed0bcc4e5aa6787992a4bcc44e288093e63ee83abd0bc3ec6d0934a674a4da13838a",
|
|
||||||
"ce325e294f9b6719d6b61278276ae06a2564c03bb0b783fafe785bdf89c7d5acd83e78756d301b445699024eaeb77b54d477336ec2a4f332f2b3f88765ddb0c3",
|
|
||||||
"29acc30e9603ae2fccf90bf97e6cc463ebe28c1b2f9b4b765e70537c25c702a29dcbfbf14c99c54345ba2b51f17b77b5f15db92bbad8fa95c471f5d070a137cc",
|
|
||||||
"3379cbaae562a87b4c0425550ffdd6bfe1203f0d666cc7ea095be407a5dfe61ee91441cd5154b3e53b4f5fb31ad4c7a9ad5c7af4ae679aa51a54003a54ca6b2d",
|
|
||||||
"3095a349d245708c7cf550118703d7302c27b60af5d4e67fc978f8a4e60953c7a04f92fcf41aee64321ccb707a895851552b1e37b00bc5e6b72fa5bcef9e3fff",
|
|
||||||
"07262d738b09321f4dbccec4bb26f48cb0f0ed246ce0b31b9a6e7bc683049f1f3e5545f28ce932dd985c5ab0f43bd6de0770560af329065ed2e49d34624c2cbb",
|
|
||||||
"b6405eca8ee3316c87061cc6ec18dba53e6c250c63ba1f3bae9e55dd3498036af08cd272aa24d713c6020d77ab2f3919af1a32f307420618ab97e73953994fb4",
|
|
||||||
"7ee682f63148ee45f6e5315da81e5c6e557c2c34641fc509c7a5701088c38a74756168e2cd8d351e88fd1a451f360a01f5b2580f9b5a2e8cfc138f3dd59a3ffc",
|
|
||||||
"1d263c179d6b268f6fa016f3a4f29e943891125ed8593c81256059f5a7b44af2dcb2030d175c00e62ecaf7ee96682aa07ab20a611024a28532b1c25b86657902",
|
|
||||||
"106d132cbdb4cd2597812846e2bc1bf732fec5f0a5f65dbb39ec4e6dc64ab2ce6d24630d0f15a805c3540025d84afa98e36703c3dbee713e72dde8465bc1be7e",
|
|
||||||
"0e79968226650667a8d862ea8da4891af56a4e3a8b6d1750e394f0dea76d640d85077bcec2cc86886e506751b4f6a5838f7f0b5fef765d9dc90dcdcbaf079f08",
|
|
||||||
"521156a82ab0c4e566e5844d5e31ad9aaf144bbd5a464fdca34dbd5717e8ff711d3ffebbfa085d67fe996a34f6d3e4e60b1396bf4b1610c263bdbb834d560816",
|
|
||||||
"1aba88befc55bc25efbce02db8b9933e46f57661baeabeb21cc2574d2a518a3cba5dc5a38e49713440b25f9c744e75f6b85c9d8f4681f676160f6105357b8406",
|
|
||||||
"5a9949fcb2c473cda968ac1b5d08566dc2d816d960f57e63b898fa701cf8ebd3f59b124d95bfbbedc5f1cf0e17d5eaed0c02c50b69d8a402cabcca4433b51fd4",
|
|
||||||
"b0cead09807c672af2eb2b0f06dde46cf5370e15a4096b1a7d7cbb36ec31c205fbefca00b7a4162fa89fb4fb3eb78d79770c23f44e7206664ce3cd931c291e5d",
|
|
||||||
"bb6664931ec97044e45b2ae420ae1c551a8874bc937d08e969399c3964ebdba8346cdd5d09caafe4c28ba7ec788191ceca65ddd6f95f18583e040d0f30d0364d",
|
|
||||||
"65bc770a5faa3792369803683e844b0be7ee96f29f6d6a35568006bd5590f9a4ef639b7a8061c7b0424b66b60ac34af3119905f33a9d8c3ae18382ca9b689900",
|
|
||||||
"ea9b4dca333336aaf839a45c6eaa48b8cb4c7ddabffea4f643d6357ea6628a480a5b45f2b052c1b07d1fedca918b6f1139d80f74c24510dcbaa4be70eacc1b06",
|
|
||||||
"e6342fb4a780ad975d0e24bce149989b91d360557e87994f6b457b895575cc02d0c15bad3ce7577f4c63927ff13f3e381ff7e72bdbe745324844a9d27e3f1c01",
|
|
||||||
"3e209c9b33e8e461178ab46b1c64b49a07fb745f1c8bc95fbfb94c6b87c69516651b264ef980937fad41238b91ddc011a5dd777c7efd4494b4b6ecd3a9c22ac0",
|
|
||||||
"fd6a3d5b1875d80486d6e69694a56dbb04a99a4d051f15db2689776ba1c4882e6d462a603b7015dc9f4b7450f05394303b8652cfb404a266962c41bae6e18a94",
|
|
||||||
"951e27517e6bad9e4195fc8671dee3e7e9be69cee1422cb9fecfce0dba875f7b310b93ee3a3d558f941f635f668ff832d2c1d033c5e2f0997e4c66f147344e02",
|
|
||||||
"8eba2f874f1ae84041903c7c4253c82292530fc8509550bfdc34c95c7e2889d5650b0ad8cb988e5c4894cb87fbfbb19612ea93ccc4c5cad17158b9763464b492",
|
|
||||||
"16f712eaa1b7c6354719a8e7dbdfaf55e4063a4d277d947550019b38dfb564830911057d50506136e2394c3b28945cc964967d54e3000c2181626cfb9b73efd2",
|
|
||||||
"c39639e7d5c7fb8cdd0fd3e6a52096039437122f21c78f1679cea9d78a734c56ecbeb28654b4f18e342c331f6f7229ec4b4bc281b2d80a6eb50043f31796c88c",
|
|
||||||
"72d081af99f8a173dcc9a0ac4eb3557405639a29084b54a40172912a2f8a395129d5536f0918e902f9e8fa6000995f4168ddc5f893011be6a0dbc9b8a1a3f5bb",
|
|
||||||
"c11aa81e5efd24d5fc27ee586cfd8847fbb0e27601ccece5ecca0198e3c7765393bb74457c7e7a27eb9170350e1fb53857177506be3e762cc0f14d8c3afe9077",
|
|
||||||
"c28f2150b452e6c0c424bcde6f8d72007f9310fed7f2f87de0dbb64f4479d6c1441ba66f44b2accee61609177ed340128b407ecec7c64bbe50d63d22d8627727",
|
|
||||||
"f63d88122877ec30b8c8b00d22e89000a966426112bd44166e2f525b769ccbe9b286d437a0129130dde1a86c43e04bedb594e671d98283afe64ce331de9828fd",
|
|
||||||
"348b0532880b88a6614a8d7408c3f913357fbb60e995c60205be9139e74998aede7f4581e42f6b52698f7fa1219708c14498067fd1e09502de83a77dd281150c",
|
|
||||||
"5133dc8bef725359dff59792d85eaf75b7e1dcd1978b01c35b1b85fcebc63388ad99a17b6346a217dc1a9622ebd122ecf6913c4d31a6b52a695b86af00d741a0",
|
|
||||||
"2753c4c0e98ecad806e88780ec27fccd0f5c1ab547f9e4bf1659d192c23aa2cc971b58b6802580baef8adc3b776ef7086b2545c2987f348ee3719cdef258c403",
|
|
||||||
"b1663573ce4b9d8caefc865012f3e39714b9898a5da6ce17c25a6a47931a9ddb9bbe98adaa553beed436e89578455416c2a52a525cf2862b8d1d49a2531b7391",
|
|
||||||
"64f58bd6bfc856f5e873b2a2956ea0eda0d6db0da39c8c7fc67c9f9feefcff3072cdf9e6ea37f69a44f0c61aa0da3693c2db5b54960c0281a088151db42b11e8",
|
|
||||||
"0764c7be28125d9065c4b98a69d60aede703547c66a12e17e1c618994132f5ef82482c1e3fe3146cc65376cc109f0138ed9a80e49f1f3c7d610d2f2432f20605",
|
|
||||||
"f748784398a2ff03ebeb07e155e66116a839741a336e32da71ec696001f0ad1b25cd48c69cfca7265eca1dd71904a0ce748ac4124f3571076dfa7116a9cf00e9",
|
|
||||||
"3f0dbc0186bceb6b785ba78d2a2a013c910be157bdaffae81bb6663b1a73722f7f1228795f3ecada87cf6ef0078474af73f31eca0cc200ed975b6893f761cb6d",
|
|
||||||
"d4762cd4599876ca75b2b8fe249944dbd27ace741fdab93616cbc6e425460feb51d4e7adcc38180e7fc47c89024a7f56191adb878dfde4ead62223f5a2610efe",
|
|
||||||
"cd36b3d5b4c91b90fcbba79513cfee1907d8645a162afd0cd4cf4192d4a5f4c892183a8eacdb2b6b6a9d9aa8c11ac1b261b380dbee24ca468f1bfd043c58eefe",
|
|
||||||
"98593452281661a53c48a9d8cd790826c1a1ce567738053d0bee4a91a3d5bd92eefdbabebe3204f2031ca5f781bda99ef5d8ae56e5b04a9e1ecd21b0eb05d3e1",
|
|
||||||
"771f57dd2775ccdab55921d3e8e30ccf484d61fe1c1b9c2ae819d0fb2a12fab9be70c4a7a138da84e8280435daade5bbe66af0836a154f817fb17f3397e725a3",
|
|
||||||
"c60897c6f828e21f16fbb5f15b323f87b6c8955eabf1d38061f707f608abdd993fac3070633e286cf8339ce295dd352df4b4b40b2f29da1dd50b3a05d079e6bb",
|
|
||||||
"8210cd2c2d3b135c2cf07fa0d1433cd771f325d075c6469d9c7f1ba0943cd4ab09808cabf4acb9ce5bb88b498929b4b847f681ad2c490d042db2aec94214b06b",
|
|
||||||
"1d4edfffd8fd80f7e4107840fa3aa31e32598491e4af7013c197a65b7f36dd3ac4b478456111cd4309d9243510782fa31b7c4c95fa951520d020eb7e5c36e4ef",
|
|
||||||
"af8e6e91fab46ce4873e1a50a8ef448cc29121f7f74deef34a71ef89cc00d9274bc6c2454bbb3230d8b2ec94c62b1dec85f3593bfa30ea6f7a44d7c09465a253",
|
|
||||||
"29fd384ed4906f2d13aa9fe7af905990938bed807f1832454a372ab412eea1f5625a1fcc9ac8343b7c67c5aba6e0b1cc4644654913692c6b39eb9187ceacd3ec",
|
|
||||||
"a268c7885d9874a51c44dffed8ea53e94f78456e0b2ed99ff5a3924760813826d960a15edbedbb5de5226ba4b074e71b05c55b9756bb79e55c02754c2c7b6c8a",
|
|
||||||
"0cf8545488d56a86817cd7ecb10f7116b7ea530a45b6ea497b6c72c997e09e3d0da8698f46bb006fc977c2cd3d1177463ac9057fdd1662c85d0c126443c10473",
|
|
||||||
"b39614268fdd8781515e2cfebf89b4d5402bab10c226e6344e6b9ae000fb0d6c79cb2f3ec80e80eaeb1980d2f8698916bd2e9f747236655116649cd3ca23a837",
|
|
||||||
"74bef092fc6f1e5dba3663a3fb003b2a5ba257496536d99f62b9d73f8f9eb3ce9ff3eec709eb883655ec9eb896b9128f2afc89cf7d1ab58a72f4a3bf034d2b4a",
|
|
||||||
"3a988d38d75611f3ef38b8774980b33e573b6c57bee0469ba5eed9b44f29945e7347967fba2c162e1c3be7f310f2f75ee2381e7bfd6b3f0baea8d95dfb1dafb1",
|
|
||||||
"58aedfce6f67ddc85a28c992f1c0bd0969f041e66f1ee88020a125cbfcfebcd61709c9c4eba192c15e69f020d462486019fa8dea0cd7a42921a19d2fe546d43d",
|
|
||||||
"9347bd291473e6b4e368437b8e561e065f649a6d8ada479ad09b1999a8f26b91cf6120fd3bfe014e83f23acfa4c0ad7b3712b2c3c0733270663112ccd9285cd9",
|
|
||||||
"b32163e7c5dbb5f51fdc11d2eac875efbbcb7e7699090a7e7ff8a8d50795af5d74d9ff98543ef8cdf89ac13d0485278756e0ef00c817745661e1d59fe38e7537",
|
|
||||||
"1085d78307b1c4b008c57a2e7e5b234658a0a82e4ff1e4aaac72b312fda0fe27d233bc5b10e9cc17fdc7697b540c7d95eb215a19a1a0e20e1abfa126efd568c7",
|
|
||||||
"4e5c734c7dde011d83eac2b7347b373594f92d7091b9ca34cb9c6f39bdf5a8d2f134379e16d822f6522170ccf2ddd55c84b9e6c64fc927ac4cf8dfb2a17701f2",
|
|
||||||
"695d83bd990a1117b3d0ce06cc888027d12a054c2677fd82f0d4fbfc93575523e7991a5e35a3752e9b70ce62992e268a877744cdd435f5f130869c9a2074b338",
|
|
||||||
"a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15",
|
|
||||||
"d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9",
|
|
||||||
"142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461",
|
|
||||||
}
|
|
32
vendor/golang.org/x/crypto/blake2b/register.go
generated
vendored
32
vendor/golang.org/x/crypto/blake2b/register.go
generated
vendored
|
@ -1,32 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.9
|
|
||||||
|
|
||||||
package blake2b
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto"
|
|
||||||
"hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
newHash256 := func() hash.Hash {
|
|
||||||
h, _ := New256(nil)
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
newHash384 := func() hash.Hash {
|
|
||||||
h, _ := New384(nil)
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
newHash512 := func() hash.Hash {
|
|
||||||
h, _ := New512(nil)
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
crypto.RegisterHash(crypto.BLAKE2b_256, newHash256)
|
|
||||||
crypto.RegisterHash(crypto.BLAKE2b_384, newHash384)
|
|
||||||
crypto.RegisterHash(crypto.BLAKE2b_512, newHash512)
|
|
||||||
}
|
|
175
vendor/golang.org/x/crypto/blake2s/blake2s.go
generated
vendored
175
vendor/golang.org/x/crypto/blake2s/blake2s.go
generated
vendored
|
@ -1,175 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package blake2s implements the BLAKE2s hash algorithm as
|
|
||||||
// defined in RFC 7693.
|
|
||||||
package blake2s // import "golang.org/x/crypto/blake2s"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// The blocksize of BLAKE2s in bytes.
|
|
||||||
BlockSize = 64
|
|
||||||
|
|
||||||
// The hash size of BLAKE2s-256 in bytes.
|
|
||||||
Size = 32
|
|
||||||
|
|
||||||
// The hash size of BLAKE2s-128 in bytes.
|
|
||||||
Size128 = 16
|
|
||||||
)
|
|
||||||
|
|
||||||
var errKeySize = errors.New("blake2s: invalid key size")
|
|
||||||
|
|
||||||
var iv = [8]uint32{
|
|
||||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
|
||||||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sum256 returns the BLAKE2s-256 checksum of the data.
|
|
||||||
func Sum256(data []byte) [Size]byte {
|
|
||||||
var sum [Size]byte
|
|
||||||
checkSum(&sum, Size, data)
|
|
||||||
return sum
|
|
||||||
}
|
|
||||||
|
|
||||||
// New256 returns a new hash.Hash computing the BLAKE2s-256 checksum. A non-nil
|
|
||||||
// key turns the hash into a MAC. The key must between zero and 32 bytes long.
|
|
||||||
func New256(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
|
|
||||||
|
|
||||||
// New128 returns a new hash.Hash computing the BLAKE2s-128 checksum given a
|
|
||||||
// non-empty key. Note that a 128-bit digest is too small to be secure as a
|
|
||||||
// cryptographic hash and should only be used as a MAC, thus the key argument
|
|
||||||
// is not optional.
|
|
||||||
func New128(key []byte) (hash.Hash, error) {
|
|
||||||
if len(key) == 0 {
|
|
||||||
return nil, errors.New("blake2s: a key is required for a 128-bit hash")
|
|
||||||
}
|
|
||||||
return newDigest(Size128, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDigest(hashSize int, key []byte) (*digest, error) {
|
|
||||||
if len(key) > Size {
|
|
||||||
return nil, errKeySize
|
|
||||||
}
|
|
||||||
d := &digest{
|
|
||||||
size: hashSize,
|
|
||||||
keyLen: len(key),
|
|
||||||
}
|
|
||||||
copy(d.key[:], key)
|
|
||||||
d.Reset()
|
|
||||||
return d, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkSum(sum *[Size]byte, hashSize int, data []byte) {
|
|
||||||
var (
|
|
||||||
h [8]uint32
|
|
||||||
c [2]uint32
|
|
||||||
)
|
|
||||||
|
|
||||||
h = iv
|
|
||||||
h[0] ^= uint32(hashSize) | (1 << 16) | (1 << 24)
|
|
||||||
|
|
||||||
if length := len(data); length > BlockSize {
|
|
||||||
n := length &^ (BlockSize - 1)
|
|
||||||
if length == n {
|
|
||||||
n -= BlockSize
|
|
||||||
}
|
|
||||||
hashBlocks(&h, &c, 0, data[:n])
|
|
||||||
data = data[n:]
|
|
||||||
}
|
|
||||||
|
|
||||||
var block [BlockSize]byte
|
|
||||||
offset := copy(block[:], data)
|
|
||||||
remaining := uint32(BlockSize - offset)
|
|
||||||
|
|
||||||
if c[0] < remaining {
|
|
||||||
c[1]--
|
|
||||||
}
|
|
||||||
c[0] -= remaining
|
|
||||||
|
|
||||||
hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
|
|
||||||
|
|
||||||
for i, v := range h {
|
|
||||||
binary.LittleEndian.PutUint32(sum[4*i:], v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type digest struct {
|
|
||||||
h [8]uint32
|
|
||||||
c [2]uint32
|
|
||||||
size int
|
|
||||||
block [BlockSize]byte
|
|
||||||
offset int
|
|
||||||
|
|
||||||
key [BlockSize]byte
|
|
||||||
keyLen int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *digest) BlockSize() int { return BlockSize }
|
|
||||||
|
|
||||||
func (d *digest) Size() int { return d.size }
|
|
||||||
|
|
||||||
func (d *digest) Reset() {
|
|
||||||
d.h = iv
|
|
||||||
d.h[0] ^= uint32(d.size) | (uint32(d.keyLen) << 8) | (1 << 16) | (1 << 24)
|
|
||||||
d.offset, d.c[0], d.c[1] = 0, 0, 0
|
|
||||||
if d.keyLen > 0 {
|
|
||||||
d.block = d.key
|
|
||||||
d.offset = BlockSize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *digest) Write(p []byte) (n int, err error) {
|
|
||||||
n = len(p)
|
|
||||||
|
|
||||||
if d.offset > 0 {
|
|
||||||
remaining := BlockSize - d.offset
|
|
||||||
if n <= remaining {
|
|
||||||
d.offset += copy(d.block[d.offset:], p)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
copy(d.block[d.offset:], p[:remaining])
|
|
||||||
hashBlocks(&d.h, &d.c, 0, d.block[:])
|
|
||||||
d.offset = 0
|
|
||||||
p = p[remaining:]
|
|
||||||
}
|
|
||||||
|
|
||||||
if length := len(p); length > BlockSize {
|
|
||||||
nn := length &^ (BlockSize - 1)
|
|
||||||
if length == nn {
|
|
||||||
nn -= BlockSize
|
|
||||||
}
|
|
||||||
hashBlocks(&d.h, &d.c, 0, p[:nn])
|
|
||||||
p = p[nn:]
|
|
||||||
}
|
|
||||||
|
|
||||||
d.offset += copy(d.block[:], p)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *digest) Sum(b []byte) []byte {
|
|
||||||
var block [BlockSize]byte
|
|
||||||
h := d.h
|
|
||||||
c := d.c
|
|
||||||
|
|
||||||
copy(block[:], d.block[:d.offset])
|
|
||||||
remaining := uint32(BlockSize - d.offset)
|
|
||||||
if c[0] < remaining {
|
|
||||||
c[1]--
|
|
||||||
}
|
|
||||||
c[0] -= remaining
|
|
||||||
|
|
||||||
hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
|
|
||||||
|
|
||||||
var sum [Size]byte
|
|
||||||
for i, v := range h {
|
|
||||||
binary.LittleEndian.PutUint32(sum[4*i:], v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return append(b, sum[:d.size]...)
|
|
||||||
}
|
|
36
vendor/golang.org/x/crypto/blake2s/blake2s_386.go
generated
vendored
36
vendor/golang.org/x/crypto/blake2s/blake2s_386.go
generated
vendored
|
@ -1,36 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build 386,!gccgo,!appengine
|
|
||||||
|
|
||||||
package blake2s
|
|
||||||
|
|
||||||
var (
|
|
||||||
useSSE4 = false
|
|
||||||
useSSSE3 = supportSSSE3()
|
|
||||||
useSSE2 = supportSSE2()
|
|
||||||
useGeneric = true
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func supportSSE2() bool
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func supportSSSE3() bool
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
|
|
||||||
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
|
|
||||||
if useSSSE3 {
|
|
||||||
hashBlocksSSSE3(h, c, flag, blocks)
|
|
||||||
} else if useSSE2 {
|
|
||||||
hashBlocksSSE2(h, c, flag, blocks)
|
|
||||||
} else {
|
|
||||||
hashBlocksGeneric(h, c, flag, blocks)
|
|
||||||
}
|
|
||||||
}
|
|
460
vendor/golang.org/x/crypto/blake2s/blake2s_386.s
generated
vendored
460
vendor/golang.org/x/crypto/blake2s/blake2s_386.s
generated
vendored
|
@ -1,460 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build 386,!gccgo,!appengine
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
DATA iv0<>+0x00(SB)/4, $0x6a09e667
|
|
||||||
DATA iv0<>+0x04(SB)/4, $0xbb67ae85
|
|
||||||
DATA iv0<>+0x08(SB)/4, $0x3c6ef372
|
|
||||||
DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
|
|
||||||
GLOBL iv0<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
DATA iv1<>+0x00(SB)/4, $0x510e527f
|
|
||||||
DATA iv1<>+0x04(SB)/4, $0x9b05688c
|
|
||||||
DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
|
|
||||||
DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
|
|
||||||
GLOBL iv1<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
DATA rol16<>+0x00(SB)/8, $0x0504070601000302
|
|
||||||
DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
|
|
||||||
GLOBL rol16<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
DATA rol8<>+0x00(SB)/8, $0x0407060500030201
|
|
||||||
DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
|
|
||||||
GLOBL rol8<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
DATA counter<>+0x00(SB)/8, $0x40
|
|
||||||
DATA counter<>+0x08(SB)/8, $0x0
|
|
||||||
GLOBL counter<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
#define ROTL_SSE2(n, t, v) \
|
|
||||||
MOVO v, t; \
|
|
||||||
PSLLL $n, t; \
|
|
||||||
PSRLL $(32-n), v; \
|
|
||||||
PXOR t, v
|
|
||||||
|
|
||||||
#define ROTL_SSSE3(c, v) \
|
|
||||||
PSHUFB c, v
|
|
||||||
|
|
||||||
#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
|
|
||||||
PADDL m0, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSE2(16, t, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(20, t, v1); \
|
|
||||||
PADDL m1, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSE2(24, t, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(25, t, v1); \
|
|
||||||
PSHUFL $0x39, v1, v1; \
|
|
||||||
PSHUFL $0x4E, v2, v2; \
|
|
||||||
PSHUFL $0x93, v3, v3; \
|
|
||||||
PADDL m2, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSE2(16, t, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(20, t, v1); \
|
|
||||||
PADDL m3, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSE2(24, t, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(25, t, v1); \
|
|
||||||
PSHUFL $0x39, v3, v3; \
|
|
||||||
PSHUFL $0x4E, v2, v2; \
|
|
||||||
PSHUFL $0x93, v1, v1
|
|
||||||
|
|
||||||
#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
|
|
||||||
PADDL m0, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSSE3(c16, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(20, t, v1); \
|
|
||||||
PADDL m1, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSSE3(c8, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(25, t, v1); \
|
|
||||||
PSHUFL $0x39, v1, v1; \
|
|
||||||
PSHUFL $0x4E, v2, v2; \
|
|
||||||
PSHUFL $0x93, v3, v3; \
|
|
||||||
PADDL m2, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSSE3(c16, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(20, t, v1); \
|
|
||||||
PADDL m3, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSSE3(c8, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(25, t, v1); \
|
|
||||||
PSHUFL $0x39, v3, v3; \
|
|
||||||
PSHUFL $0x4E, v2, v2; \
|
|
||||||
PSHUFL $0x93, v1, v1
|
|
||||||
|
|
||||||
#define PRECOMPUTE(dst, off, src, t) \
|
|
||||||
MOVL 0*4(src), t; \
|
|
||||||
MOVL t, 0*4+off+0(dst); \
|
|
||||||
MOVL t, 9*4+off+64(dst); \
|
|
||||||
MOVL t, 5*4+off+128(dst); \
|
|
||||||
MOVL t, 14*4+off+192(dst); \
|
|
||||||
MOVL t, 4*4+off+256(dst); \
|
|
||||||
MOVL t, 2*4+off+320(dst); \
|
|
||||||
MOVL t, 8*4+off+384(dst); \
|
|
||||||
MOVL t, 12*4+off+448(dst); \
|
|
||||||
MOVL t, 3*4+off+512(dst); \
|
|
||||||
MOVL t, 15*4+off+576(dst); \
|
|
||||||
MOVL 1*4(src), t; \
|
|
||||||
MOVL t, 4*4+off+0(dst); \
|
|
||||||
MOVL t, 8*4+off+64(dst); \
|
|
||||||
MOVL t, 14*4+off+128(dst); \
|
|
||||||
MOVL t, 5*4+off+192(dst); \
|
|
||||||
MOVL t, 12*4+off+256(dst); \
|
|
||||||
MOVL t, 11*4+off+320(dst); \
|
|
||||||
MOVL t, 1*4+off+384(dst); \
|
|
||||||
MOVL t, 6*4+off+448(dst); \
|
|
||||||
MOVL t, 10*4+off+512(dst); \
|
|
||||||
MOVL t, 3*4+off+576(dst); \
|
|
||||||
MOVL 2*4(src), t; \
|
|
||||||
MOVL t, 1*4+off+0(dst); \
|
|
||||||
MOVL t, 13*4+off+64(dst); \
|
|
||||||
MOVL t, 6*4+off+128(dst); \
|
|
||||||
MOVL t, 8*4+off+192(dst); \
|
|
||||||
MOVL t, 2*4+off+256(dst); \
|
|
||||||
MOVL t, 0*4+off+320(dst); \
|
|
||||||
MOVL t, 14*4+off+384(dst); \
|
|
||||||
MOVL t, 11*4+off+448(dst); \
|
|
||||||
MOVL t, 12*4+off+512(dst); \
|
|
||||||
MOVL t, 4*4+off+576(dst); \
|
|
||||||
MOVL 3*4(src), t; \
|
|
||||||
MOVL t, 5*4+off+0(dst); \
|
|
||||||
MOVL t, 15*4+off+64(dst); \
|
|
||||||
MOVL t, 9*4+off+128(dst); \
|
|
||||||
MOVL t, 1*4+off+192(dst); \
|
|
||||||
MOVL t, 11*4+off+256(dst); \
|
|
||||||
MOVL t, 7*4+off+320(dst); \
|
|
||||||
MOVL t, 13*4+off+384(dst); \
|
|
||||||
MOVL t, 3*4+off+448(dst); \
|
|
||||||
MOVL t, 6*4+off+512(dst); \
|
|
||||||
MOVL t, 10*4+off+576(dst); \
|
|
||||||
MOVL 4*4(src), t; \
|
|
||||||
MOVL t, 2*4+off+0(dst); \
|
|
||||||
MOVL t, 1*4+off+64(dst); \
|
|
||||||
MOVL t, 15*4+off+128(dst); \
|
|
||||||
MOVL t, 10*4+off+192(dst); \
|
|
||||||
MOVL t, 6*4+off+256(dst); \
|
|
||||||
MOVL t, 8*4+off+320(dst); \
|
|
||||||
MOVL t, 3*4+off+384(dst); \
|
|
||||||
MOVL t, 13*4+off+448(dst); \
|
|
||||||
MOVL t, 14*4+off+512(dst); \
|
|
||||||
MOVL t, 5*4+off+576(dst); \
|
|
||||||
MOVL 5*4(src), t; \
|
|
||||||
MOVL t, 6*4+off+0(dst); \
|
|
||||||
MOVL t, 11*4+off+64(dst); \
|
|
||||||
MOVL t, 2*4+off+128(dst); \
|
|
||||||
MOVL t, 9*4+off+192(dst); \
|
|
||||||
MOVL t, 1*4+off+256(dst); \
|
|
||||||
MOVL t, 13*4+off+320(dst); \
|
|
||||||
MOVL t, 4*4+off+384(dst); \
|
|
||||||
MOVL t, 8*4+off+448(dst); \
|
|
||||||
MOVL t, 15*4+off+512(dst); \
|
|
||||||
MOVL t, 7*4+off+576(dst); \
|
|
||||||
MOVL 6*4(src), t; \
|
|
||||||
MOVL t, 3*4+off+0(dst); \
|
|
||||||
MOVL t, 7*4+off+64(dst); \
|
|
||||||
MOVL t, 13*4+off+128(dst); \
|
|
||||||
MOVL t, 12*4+off+192(dst); \
|
|
||||||
MOVL t, 10*4+off+256(dst); \
|
|
||||||
MOVL t, 1*4+off+320(dst); \
|
|
||||||
MOVL t, 9*4+off+384(dst); \
|
|
||||||
MOVL t, 14*4+off+448(dst); \
|
|
||||||
MOVL t, 0*4+off+512(dst); \
|
|
||||||
MOVL t, 6*4+off+576(dst); \
|
|
||||||
MOVL 7*4(src), t; \
|
|
||||||
MOVL t, 7*4+off+0(dst); \
|
|
||||||
MOVL t, 14*4+off+64(dst); \
|
|
||||||
MOVL t, 10*4+off+128(dst); \
|
|
||||||
MOVL t, 0*4+off+192(dst); \
|
|
||||||
MOVL t, 5*4+off+256(dst); \
|
|
||||||
MOVL t, 9*4+off+320(dst); \
|
|
||||||
MOVL t, 12*4+off+384(dst); \
|
|
||||||
MOVL t, 1*4+off+448(dst); \
|
|
||||||
MOVL t, 13*4+off+512(dst); \
|
|
||||||
MOVL t, 2*4+off+576(dst); \
|
|
||||||
MOVL 8*4(src), t; \
|
|
||||||
MOVL t, 8*4+off+0(dst); \
|
|
||||||
MOVL t, 5*4+off+64(dst); \
|
|
||||||
MOVL t, 4*4+off+128(dst); \
|
|
||||||
MOVL t, 15*4+off+192(dst); \
|
|
||||||
MOVL t, 14*4+off+256(dst); \
|
|
||||||
MOVL t, 3*4+off+320(dst); \
|
|
||||||
MOVL t, 11*4+off+384(dst); \
|
|
||||||
MOVL t, 10*4+off+448(dst); \
|
|
||||||
MOVL t, 7*4+off+512(dst); \
|
|
||||||
MOVL t, 1*4+off+576(dst); \
|
|
||||||
MOVL 9*4(src), t; \
|
|
||||||
MOVL t, 12*4+off+0(dst); \
|
|
||||||
MOVL t, 2*4+off+64(dst); \
|
|
||||||
MOVL t, 11*4+off+128(dst); \
|
|
||||||
MOVL t, 4*4+off+192(dst); \
|
|
||||||
MOVL t, 0*4+off+256(dst); \
|
|
||||||
MOVL t, 15*4+off+320(dst); \
|
|
||||||
MOVL t, 10*4+off+384(dst); \
|
|
||||||
MOVL t, 7*4+off+448(dst); \
|
|
||||||
MOVL t, 5*4+off+512(dst); \
|
|
||||||
MOVL t, 9*4+off+576(dst); \
|
|
||||||
MOVL 10*4(src), t; \
|
|
||||||
MOVL t, 9*4+off+0(dst); \
|
|
||||||
MOVL t, 4*4+off+64(dst); \
|
|
||||||
MOVL t, 8*4+off+128(dst); \
|
|
||||||
MOVL t, 13*4+off+192(dst); \
|
|
||||||
MOVL t, 3*4+off+256(dst); \
|
|
||||||
MOVL t, 5*4+off+320(dst); \
|
|
||||||
MOVL t, 7*4+off+384(dst); \
|
|
||||||
MOVL t, 15*4+off+448(dst); \
|
|
||||||
MOVL t, 11*4+off+512(dst); \
|
|
||||||
MOVL t, 0*4+off+576(dst); \
|
|
||||||
MOVL 11*4(src), t; \
|
|
||||||
MOVL t, 13*4+off+0(dst); \
|
|
||||||
MOVL t, 10*4+off+64(dst); \
|
|
||||||
MOVL t, 0*4+off+128(dst); \
|
|
||||||
MOVL t, 3*4+off+192(dst); \
|
|
||||||
MOVL t, 9*4+off+256(dst); \
|
|
||||||
MOVL t, 6*4+off+320(dst); \
|
|
||||||
MOVL t, 15*4+off+384(dst); \
|
|
||||||
MOVL t, 4*4+off+448(dst); \
|
|
||||||
MOVL t, 2*4+off+512(dst); \
|
|
||||||
MOVL t, 12*4+off+576(dst); \
|
|
||||||
MOVL 12*4(src), t; \
|
|
||||||
MOVL t, 10*4+off+0(dst); \
|
|
||||||
MOVL t, 12*4+off+64(dst); \
|
|
||||||
MOVL t, 1*4+off+128(dst); \
|
|
||||||
MOVL t, 6*4+off+192(dst); \
|
|
||||||
MOVL t, 13*4+off+256(dst); \
|
|
||||||
MOVL t, 4*4+off+320(dst); \
|
|
||||||
MOVL t, 0*4+off+384(dst); \
|
|
||||||
MOVL t, 2*4+off+448(dst); \
|
|
||||||
MOVL t, 8*4+off+512(dst); \
|
|
||||||
MOVL t, 14*4+off+576(dst); \
|
|
||||||
MOVL 13*4(src), t; \
|
|
||||||
MOVL t, 14*4+off+0(dst); \
|
|
||||||
MOVL t, 3*4+off+64(dst); \
|
|
||||||
MOVL t, 7*4+off+128(dst); \
|
|
||||||
MOVL t, 2*4+off+192(dst); \
|
|
||||||
MOVL t, 15*4+off+256(dst); \
|
|
||||||
MOVL t, 12*4+off+320(dst); \
|
|
||||||
MOVL t, 6*4+off+384(dst); \
|
|
||||||
MOVL t, 0*4+off+448(dst); \
|
|
||||||
MOVL t, 9*4+off+512(dst); \
|
|
||||||
MOVL t, 11*4+off+576(dst); \
|
|
||||||
MOVL 14*4(src), t; \
|
|
||||||
MOVL t, 11*4+off+0(dst); \
|
|
||||||
MOVL t, 0*4+off+64(dst); \
|
|
||||||
MOVL t, 12*4+off+128(dst); \
|
|
||||||
MOVL t, 7*4+off+192(dst); \
|
|
||||||
MOVL t, 8*4+off+256(dst); \
|
|
||||||
MOVL t, 14*4+off+320(dst); \
|
|
||||||
MOVL t, 2*4+off+384(dst); \
|
|
||||||
MOVL t, 5*4+off+448(dst); \
|
|
||||||
MOVL t, 1*4+off+512(dst); \
|
|
||||||
MOVL t, 13*4+off+576(dst); \
|
|
||||||
MOVL 15*4(src), t; \
|
|
||||||
MOVL t, 15*4+off+0(dst); \
|
|
||||||
MOVL t, 6*4+off+64(dst); \
|
|
||||||
MOVL t, 3*4+off+128(dst); \
|
|
||||||
MOVL t, 11*4+off+192(dst); \
|
|
||||||
MOVL t, 7*4+off+256(dst); \
|
|
||||||
MOVL t, 10*4+off+320(dst); \
|
|
||||||
MOVL t, 5*4+off+384(dst); \
|
|
||||||
MOVL t, 9*4+off+448(dst); \
|
|
||||||
MOVL t, 4*4+off+512(dst); \
|
|
||||||
MOVL t, 8*4+off+576(dst)
|
|
||||||
|
|
||||||
// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
TEXT ·hashBlocksSSE2(SB), 0, $672-24 // frame = 656 + 16 byte alignment
|
|
||||||
MOVL h+0(FP), AX
|
|
||||||
MOVL c+4(FP), BX
|
|
||||||
MOVL flag+8(FP), CX
|
|
||||||
MOVL blocks_base+12(FP), SI
|
|
||||||
MOVL blocks_len+16(FP), DX
|
|
||||||
|
|
||||||
MOVL SP, BP
|
|
||||||
MOVL SP, DI
|
|
||||||
ADDL $15, DI
|
|
||||||
ANDL $~15, DI
|
|
||||||
MOVL DI, SP
|
|
||||||
|
|
||||||
MOVL CX, 8(SP)
|
|
||||||
MOVL 0(BX), CX
|
|
||||||
MOVL CX, 0(SP)
|
|
||||||
MOVL 4(BX), CX
|
|
||||||
MOVL CX, 4(SP)
|
|
||||||
XORL CX, CX
|
|
||||||
MOVL CX, 12(SP)
|
|
||||||
|
|
||||||
MOVOU 0(AX), X0
|
|
||||||
MOVOU 16(AX), X1
|
|
||||||
MOVOU counter<>(SB), X2
|
|
||||||
|
|
||||||
loop:
|
|
||||||
MOVO X0, X4
|
|
||||||
MOVO X1, X5
|
|
||||||
MOVOU iv0<>(SB), X6
|
|
||||||
MOVOU iv1<>(SB), X7
|
|
||||||
|
|
||||||
MOVO 0(SP), X3
|
|
||||||
PADDQ X2, X3
|
|
||||||
PXOR X3, X7
|
|
||||||
MOVO X3, 0(SP)
|
|
||||||
|
|
||||||
PRECOMPUTE(SP, 16, SI, CX)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X3)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X3)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X3)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X3)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X3)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X3)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X3)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X3)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X3)
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X3)
|
|
||||||
|
|
||||||
PXOR X4, X0
|
|
||||||
PXOR X5, X1
|
|
||||||
PXOR X6, X0
|
|
||||||
PXOR X7, X1
|
|
||||||
|
|
||||||
LEAL 64(SI), SI
|
|
||||||
SUBL $64, DX
|
|
||||||
JNE loop
|
|
||||||
|
|
||||||
MOVL 0(SP), CX
|
|
||||||
MOVL CX, 0(BX)
|
|
||||||
MOVL 4(SP), CX
|
|
||||||
MOVL CX, 4(BX)
|
|
||||||
|
|
||||||
MOVOU X0, 0(AX)
|
|
||||||
MOVOU X1, 16(AX)
|
|
||||||
|
|
||||||
MOVL BP, SP
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
TEXT ·hashBlocksSSSE3(SB), 0, $704-24 // frame = 688 + 16 byte alignment
|
|
||||||
MOVL h+0(FP), AX
|
|
||||||
MOVL c+4(FP), BX
|
|
||||||
MOVL flag+8(FP), CX
|
|
||||||
MOVL blocks_base+12(FP), SI
|
|
||||||
MOVL blocks_len+16(FP), DX
|
|
||||||
|
|
||||||
MOVL SP, BP
|
|
||||||
MOVL SP, DI
|
|
||||||
ADDL $15, DI
|
|
||||||
ANDL $~15, DI
|
|
||||||
MOVL DI, SP
|
|
||||||
|
|
||||||
MOVL CX, 8(SP)
|
|
||||||
MOVL 0(BX), CX
|
|
||||||
MOVL CX, 0(SP)
|
|
||||||
MOVL 4(BX), CX
|
|
||||||
MOVL CX, 4(SP)
|
|
||||||
XORL CX, CX
|
|
||||||
MOVL CX, 12(SP)
|
|
||||||
|
|
||||||
MOVOU 0(AX), X0
|
|
||||||
MOVOU 16(AX), X1
|
|
||||||
MOVOU counter<>(SB), X2
|
|
||||||
|
|
||||||
loop:
|
|
||||||
MOVO X0, 656(SP)
|
|
||||||
MOVO X1, 672(SP)
|
|
||||||
MOVO X0, X4
|
|
||||||
MOVO X1, X5
|
|
||||||
MOVOU iv0<>(SB), X6
|
|
||||||
MOVOU iv1<>(SB), X7
|
|
||||||
|
|
||||||
MOVO 0(SP), X3
|
|
||||||
PADDQ X2, X3
|
|
||||||
PXOR X3, X7
|
|
||||||
MOVO X3, 0(SP)
|
|
||||||
|
|
||||||
MOVOU rol16<>(SB), X0
|
|
||||||
MOVOU rol8<>(SB), X1
|
|
||||||
|
|
||||||
PRECOMPUTE(SP, 16, SI, CX)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X3, X0, X1)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X3, X0, X1)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X3, X0, X1)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X3, X0, X1)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X3, X0, X1)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X3, X0, X1)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X3, X0, X1)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X3, X0, X1)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X3, X0, X1)
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X3, X0, X1)
|
|
||||||
|
|
||||||
MOVO 656(SP), X0
|
|
||||||
MOVO 672(SP), X1
|
|
||||||
PXOR X4, X0
|
|
||||||
PXOR X5, X1
|
|
||||||
PXOR X6, X0
|
|
||||||
PXOR X7, X1
|
|
||||||
|
|
||||||
LEAL 64(SI), SI
|
|
||||||
SUBL $64, DX
|
|
||||||
JNE loop
|
|
||||||
|
|
||||||
MOVL 0(SP), CX
|
|
||||||
MOVL CX, 0(BX)
|
|
||||||
MOVL 4(SP), CX
|
|
||||||
MOVL CX, 4(BX)
|
|
||||||
|
|
||||||
MOVOU X0, 0(AX)
|
|
||||||
MOVOU X1, 16(AX)
|
|
||||||
|
|
||||||
MOVL BP, SP
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func supportSSSE3() bool
|
|
||||||
TEXT ·supportSSSE3(SB), 4, $0-1
|
|
||||||
MOVL $1, AX
|
|
||||||
CPUID
|
|
||||||
MOVL CX, BX
|
|
||||||
ANDL $0x1, BX // supports SSE3
|
|
||||||
JZ FALSE
|
|
||||||
ANDL $0x200, CX // supports SSSE3
|
|
||||||
JZ FALSE
|
|
||||||
MOVB $1, ret+0(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
FALSE:
|
|
||||||
MOVB $0, ret+0(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func supportSSE2() bool
|
|
||||||
TEXT ·supportSSE2(SB), 4, $0-1
|
|
||||||
MOVL $1, AX
|
|
||||||
CPUID
|
|
||||||
SHRL $26, DX
|
|
||||||
ANDL $1, DX // DX != 0 if support SSE2
|
|
||||||
MOVB DX, ret+0(FP)
|
|
||||||
RET
|
|
39
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
generated
vendored
39
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
generated
vendored
|
@ -1,39 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
|
||||||
|
|
||||||
package blake2s
|
|
||||||
|
|
||||||
var (
|
|
||||||
useSSE4 = supportSSE4()
|
|
||||||
useSSSE3 = supportSSSE3()
|
|
||||||
useSSE2 = true // Always available on amd64
|
|
||||||
useGeneric = false
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func supportSSSE3() bool
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func supportSSE4() bool
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
|
|
||||||
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
|
|
||||||
if useSSE4 {
|
|
||||||
hashBlocksSSE4(h, c, flag, blocks)
|
|
||||||
} else if useSSSE3 {
|
|
||||||
hashBlocksSSSE3(h, c, flag, blocks)
|
|
||||||
} else {
|
|
||||||
hashBlocksSSE2(h, c, flag, blocks)
|
|
||||||
}
|
|
||||||
}
|
|
463
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
generated
vendored
463
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
generated
vendored
|
@ -1,463 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
DATA iv0<>+0x00(SB)/4, $0x6a09e667
|
|
||||||
DATA iv0<>+0x04(SB)/4, $0xbb67ae85
|
|
||||||
DATA iv0<>+0x08(SB)/4, $0x3c6ef372
|
|
||||||
DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
|
|
||||||
GLOBL iv0<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
DATA iv1<>+0x00(SB)/4, $0x510e527f
|
|
||||||
DATA iv1<>+0x04(SB)/4, $0x9b05688c
|
|
||||||
DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
|
|
||||||
DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
|
|
||||||
GLOBL iv1<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
DATA rol16<>+0x00(SB)/8, $0x0504070601000302
|
|
||||||
DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
|
|
||||||
GLOBL rol16<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
DATA rol8<>+0x00(SB)/8, $0x0407060500030201
|
|
||||||
DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
|
|
||||||
GLOBL rol8<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
DATA counter<>+0x00(SB)/8, $0x40
|
|
||||||
DATA counter<>+0x08(SB)/8, $0x0
|
|
||||||
GLOBL counter<>(SB), (NOPTR+RODATA), $16
|
|
||||||
|
|
||||||
#define ROTL_SSE2(n, t, v) \
|
|
||||||
MOVO v, t; \
|
|
||||||
PSLLL $n, t; \
|
|
||||||
PSRLL $(32-n), v; \
|
|
||||||
PXOR t, v
|
|
||||||
|
|
||||||
#define ROTL_SSSE3(c, v) \
|
|
||||||
PSHUFB c, v
|
|
||||||
|
|
||||||
#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
|
|
||||||
PADDL m0, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSE2(16, t, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(20, t, v1); \
|
|
||||||
PADDL m1, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSE2(24, t, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(25, t, v1); \
|
|
||||||
PSHUFL $0x39, v1, v1; \
|
|
||||||
PSHUFL $0x4E, v2, v2; \
|
|
||||||
PSHUFL $0x93, v3, v3; \
|
|
||||||
PADDL m2, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSE2(16, t, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(20, t, v1); \
|
|
||||||
PADDL m3, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSE2(24, t, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(25, t, v1); \
|
|
||||||
PSHUFL $0x39, v3, v3; \
|
|
||||||
PSHUFL $0x4E, v2, v2; \
|
|
||||||
PSHUFL $0x93, v1, v1
|
|
||||||
|
|
||||||
#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
|
|
||||||
PADDL m0, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSSE3(c16, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(20, t, v1); \
|
|
||||||
PADDL m1, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSSE3(c8, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(25, t, v1); \
|
|
||||||
PSHUFL $0x39, v1, v1; \
|
|
||||||
PSHUFL $0x4E, v2, v2; \
|
|
||||||
PSHUFL $0x93, v3, v3; \
|
|
||||||
PADDL m2, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSSE3(c16, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(20, t, v1); \
|
|
||||||
PADDL m3, v0; \
|
|
||||||
PADDL v1, v0; \
|
|
||||||
PXOR v0, v3; \
|
|
||||||
ROTL_SSSE3(c8, v3); \
|
|
||||||
PADDL v3, v2; \
|
|
||||||
PXOR v2, v1; \
|
|
||||||
ROTL_SSE2(25, t, v1); \
|
|
||||||
PSHUFL $0x39, v3, v3; \
|
|
||||||
PSHUFL $0x4E, v2, v2; \
|
|
||||||
PSHUFL $0x93, v1, v1
|
|
||||||
|
|
||||||
|
|
||||||
#define LOAD_MSG_SSE4(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15) \
|
|
||||||
MOVL i0*4(src), m0; \
|
|
||||||
PINSRD $1, i1*4(src), m0; \
|
|
||||||
PINSRD $2, i2*4(src), m0; \
|
|
||||||
PINSRD $3, i3*4(src), m0; \
|
|
||||||
MOVL i4*4(src), m1; \
|
|
||||||
PINSRD $1, i5*4(src), m1; \
|
|
||||||
PINSRD $2, i6*4(src), m1; \
|
|
||||||
PINSRD $3, i7*4(src), m1; \
|
|
||||||
MOVL i8*4(src), m2; \
|
|
||||||
PINSRD $1, i9*4(src), m2; \
|
|
||||||
PINSRD $2, i10*4(src), m2; \
|
|
||||||
PINSRD $3, i11*4(src), m2; \
|
|
||||||
MOVL i12*4(src), m3; \
|
|
||||||
PINSRD $1, i13*4(src), m3; \
|
|
||||||
PINSRD $2, i14*4(src), m3; \
|
|
||||||
PINSRD $3, i15*4(src), m3
|
|
||||||
|
|
||||||
#define PRECOMPUTE_MSG(dst, off, src, R8, R9, R10, R11, R12, R13, R14, R15) \
|
|
||||||
MOVQ 0*4(src), R8; \
|
|
||||||
MOVQ 2*4(src), R9; \
|
|
||||||
MOVQ 4*4(src), R10; \
|
|
||||||
MOVQ 6*4(src), R11; \
|
|
||||||
MOVQ 8*4(src), R12; \
|
|
||||||
MOVQ 10*4(src), R13; \
|
|
||||||
MOVQ 12*4(src), R14; \
|
|
||||||
MOVQ 14*4(src), R15; \
|
|
||||||
\
|
|
||||||
MOVL R8, 0*4+off+0(dst); \
|
|
||||||
MOVL R8, 9*4+off+64(dst); \
|
|
||||||
MOVL R8, 5*4+off+128(dst); \
|
|
||||||
MOVL R8, 14*4+off+192(dst); \
|
|
||||||
MOVL R8, 4*4+off+256(dst); \
|
|
||||||
MOVL R8, 2*4+off+320(dst); \
|
|
||||||
MOVL R8, 8*4+off+384(dst); \
|
|
||||||
MOVL R8, 12*4+off+448(dst); \
|
|
||||||
MOVL R8, 3*4+off+512(dst); \
|
|
||||||
MOVL R8, 15*4+off+576(dst); \
|
|
||||||
SHRQ $32, R8; \
|
|
||||||
MOVL R8, 4*4+off+0(dst); \
|
|
||||||
MOVL R8, 8*4+off+64(dst); \
|
|
||||||
MOVL R8, 14*4+off+128(dst); \
|
|
||||||
MOVL R8, 5*4+off+192(dst); \
|
|
||||||
MOVL R8, 12*4+off+256(dst); \
|
|
||||||
MOVL R8, 11*4+off+320(dst); \
|
|
||||||
MOVL R8, 1*4+off+384(dst); \
|
|
||||||
MOVL R8, 6*4+off+448(dst); \
|
|
||||||
MOVL R8, 10*4+off+512(dst); \
|
|
||||||
MOVL R8, 3*4+off+576(dst); \
|
|
||||||
\
|
|
||||||
MOVL R9, 1*4+off+0(dst); \
|
|
||||||
MOVL R9, 13*4+off+64(dst); \
|
|
||||||
MOVL R9, 6*4+off+128(dst); \
|
|
||||||
MOVL R9, 8*4+off+192(dst); \
|
|
||||||
MOVL R9, 2*4+off+256(dst); \
|
|
||||||
MOVL R9, 0*4+off+320(dst); \
|
|
||||||
MOVL R9, 14*4+off+384(dst); \
|
|
||||||
MOVL R9, 11*4+off+448(dst); \
|
|
||||||
MOVL R9, 12*4+off+512(dst); \
|
|
||||||
MOVL R9, 4*4+off+576(dst); \
|
|
||||||
SHRQ $32, R9; \
|
|
||||||
MOVL R9, 5*4+off+0(dst); \
|
|
||||||
MOVL R9, 15*4+off+64(dst); \
|
|
||||||
MOVL R9, 9*4+off+128(dst); \
|
|
||||||
MOVL R9, 1*4+off+192(dst); \
|
|
||||||
MOVL R9, 11*4+off+256(dst); \
|
|
||||||
MOVL R9, 7*4+off+320(dst); \
|
|
||||||
MOVL R9, 13*4+off+384(dst); \
|
|
||||||
MOVL R9, 3*4+off+448(dst); \
|
|
||||||
MOVL R9, 6*4+off+512(dst); \
|
|
||||||
MOVL R9, 10*4+off+576(dst); \
|
|
||||||
\
|
|
||||||
MOVL R10, 2*4+off+0(dst); \
|
|
||||||
MOVL R10, 1*4+off+64(dst); \
|
|
||||||
MOVL R10, 15*4+off+128(dst); \
|
|
||||||
MOVL R10, 10*4+off+192(dst); \
|
|
||||||
MOVL R10, 6*4+off+256(dst); \
|
|
||||||
MOVL R10, 8*4+off+320(dst); \
|
|
||||||
MOVL R10, 3*4+off+384(dst); \
|
|
||||||
MOVL R10, 13*4+off+448(dst); \
|
|
||||||
MOVL R10, 14*4+off+512(dst); \
|
|
||||||
MOVL R10, 5*4+off+576(dst); \
|
|
||||||
SHRQ $32, R10; \
|
|
||||||
MOVL R10, 6*4+off+0(dst); \
|
|
||||||
MOVL R10, 11*4+off+64(dst); \
|
|
||||||
MOVL R10, 2*4+off+128(dst); \
|
|
||||||
MOVL R10, 9*4+off+192(dst); \
|
|
||||||
MOVL R10, 1*4+off+256(dst); \
|
|
||||||
MOVL R10, 13*4+off+320(dst); \
|
|
||||||
MOVL R10, 4*4+off+384(dst); \
|
|
||||||
MOVL R10, 8*4+off+448(dst); \
|
|
||||||
MOVL R10, 15*4+off+512(dst); \
|
|
||||||
MOVL R10, 7*4+off+576(dst); \
|
|
||||||
\
|
|
||||||
MOVL R11, 3*4+off+0(dst); \
|
|
||||||
MOVL R11, 7*4+off+64(dst); \
|
|
||||||
MOVL R11, 13*4+off+128(dst); \
|
|
||||||
MOVL R11, 12*4+off+192(dst); \
|
|
||||||
MOVL R11, 10*4+off+256(dst); \
|
|
||||||
MOVL R11, 1*4+off+320(dst); \
|
|
||||||
MOVL R11, 9*4+off+384(dst); \
|
|
||||||
MOVL R11, 14*4+off+448(dst); \
|
|
||||||
MOVL R11, 0*4+off+512(dst); \
|
|
||||||
MOVL R11, 6*4+off+576(dst); \
|
|
||||||
SHRQ $32, R11; \
|
|
||||||
MOVL R11, 7*4+off+0(dst); \
|
|
||||||
MOVL R11, 14*4+off+64(dst); \
|
|
||||||
MOVL R11, 10*4+off+128(dst); \
|
|
||||||
MOVL R11, 0*4+off+192(dst); \
|
|
||||||
MOVL R11, 5*4+off+256(dst); \
|
|
||||||
MOVL R11, 9*4+off+320(dst); \
|
|
||||||
MOVL R11, 12*4+off+384(dst); \
|
|
||||||
MOVL R11, 1*4+off+448(dst); \
|
|
||||||
MOVL R11, 13*4+off+512(dst); \
|
|
||||||
MOVL R11, 2*4+off+576(dst); \
|
|
||||||
\
|
|
||||||
MOVL R12, 8*4+off+0(dst); \
|
|
||||||
MOVL R12, 5*4+off+64(dst); \
|
|
||||||
MOVL R12, 4*4+off+128(dst); \
|
|
||||||
MOVL R12, 15*4+off+192(dst); \
|
|
||||||
MOVL R12, 14*4+off+256(dst); \
|
|
||||||
MOVL R12, 3*4+off+320(dst); \
|
|
||||||
MOVL R12, 11*4+off+384(dst); \
|
|
||||||
MOVL R12, 10*4+off+448(dst); \
|
|
||||||
MOVL R12, 7*4+off+512(dst); \
|
|
||||||
MOVL R12, 1*4+off+576(dst); \
|
|
||||||
SHRQ $32, R12; \
|
|
||||||
MOVL R12, 12*4+off+0(dst); \
|
|
||||||
MOVL R12, 2*4+off+64(dst); \
|
|
||||||
MOVL R12, 11*4+off+128(dst); \
|
|
||||||
MOVL R12, 4*4+off+192(dst); \
|
|
||||||
MOVL R12, 0*4+off+256(dst); \
|
|
||||||
MOVL R12, 15*4+off+320(dst); \
|
|
||||||
MOVL R12, 10*4+off+384(dst); \
|
|
||||||
MOVL R12, 7*4+off+448(dst); \
|
|
||||||
MOVL R12, 5*4+off+512(dst); \
|
|
||||||
MOVL R12, 9*4+off+576(dst); \
|
|
||||||
\
|
|
||||||
MOVL R13, 9*4+off+0(dst); \
|
|
||||||
MOVL R13, 4*4+off+64(dst); \
|
|
||||||
MOVL R13, 8*4+off+128(dst); \
|
|
||||||
MOVL R13, 13*4+off+192(dst); \
|
|
||||||
MOVL R13, 3*4+off+256(dst); \
|
|
||||||
MOVL R13, 5*4+off+320(dst); \
|
|
||||||
MOVL R13, 7*4+off+384(dst); \
|
|
||||||
MOVL R13, 15*4+off+448(dst); \
|
|
||||||
MOVL R13, 11*4+off+512(dst); \
|
|
||||||
MOVL R13, 0*4+off+576(dst); \
|
|
||||||
SHRQ $32, R13; \
|
|
||||||
MOVL R13, 13*4+off+0(dst); \
|
|
||||||
MOVL R13, 10*4+off+64(dst); \
|
|
||||||
MOVL R13, 0*4+off+128(dst); \
|
|
||||||
MOVL R13, 3*4+off+192(dst); \
|
|
||||||
MOVL R13, 9*4+off+256(dst); \
|
|
||||||
MOVL R13, 6*4+off+320(dst); \
|
|
||||||
MOVL R13, 15*4+off+384(dst); \
|
|
||||||
MOVL R13, 4*4+off+448(dst); \
|
|
||||||
MOVL R13, 2*4+off+512(dst); \
|
|
||||||
MOVL R13, 12*4+off+576(dst); \
|
|
||||||
\
|
|
||||||
MOVL R14, 10*4+off+0(dst); \
|
|
||||||
MOVL R14, 12*4+off+64(dst); \
|
|
||||||
MOVL R14, 1*4+off+128(dst); \
|
|
||||||
MOVL R14, 6*4+off+192(dst); \
|
|
||||||
MOVL R14, 13*4+off+256(dst); \
|
|
||||||
MOVL R14, 4*4+off+320(dst); \
|
|
||||||
MOVL R14, 0*4+off+384(dst); \
|
|
||||||
MOVL R14, 2*4+off+448(dst); \
|
|
||||||
MOVL R14, 8*4+off+512(dst); \
|
|
||||||
MOVL R14, 14*4+off+576(dst); \
|
|
||||||
SHRQ $32, R14; \
|
|
||||||
MOVL R14, 14*4+off+0(dst); \
|
|
||||||
MOVL R14, 3*4+off+64(dst); \
|
|
||||||
MOVL R14, 7*4+off+128(dst); \
|
|
||||||
MOVL R14, 2*4+off+192(dst); \
|
|
||||||
MOVL R14, 15*4+off+256(dst); \
|
|
||||||
MOVL R14, 12*4+off+320(dst); \
|
|
||||||
MOVL R14, 6*4+off+384(dst); \
|
|
||||||
MOVL R14, 0*4+off+448(dst); \
|
|
||||||
MOVL R14, 9*4+off+512(dst); \
|
|
||||||
MOVL R14, 11*4+off+576(dst); \
|
|
||||||
\
|
|
||||||
MOVL R15, 11*4+off+0(dst); \
|
|
||||||
MOVL R15, 0*4+off+64(dst); \
|
|
||||||
MOVL R15, 12*4+off+128(dst); \
|
|
||||||
MOVL R15, 7*4+off+192(dst); \
|
|
||||||
MOVL R15, 8*4+off+256(dst); \
|
|
||||||
MOVL R15, 14*4+off+320(dst); \
|
|
||||||
MOVL R15, 2*4+off+384(dst); \
|
|
||||||
MOVL R15, 5*4+off+448(dst); \
|
|
||||||
MOVL R15, 1*4+off+512(dst); \
|
|
||||||
MOVL R15, 13*4+off+576(dst); \
|
|
||||||
SHRQ $32, R15; \
|
|
||||||
MOVL R15, 15*4+off+0(dst); \
|
|
||||||
MOVL R15, 6*4+off+64(dst); \
|
|
||||||
MOVL R15, 3*4+off+128(dst); \
|
|
||||||
MOVL R15, 11*4+off+192(dst); \
|
|
||||||
MOVL R15, 7*4+off+256(dst); \
|
|
||||||
MOVL R15, 10*4+off+320(dst); \
|
|
||||||
MOVL R15, 5*4+off+384(dst); \
|
|
||||||
MOVL R15, 9*4+off+448(dst); \
|
|
||||||
MOVL R15, 4*4+off+512(dst); \
|
|
||||||
MOVL R15, 8*4+off+576(dst)
|
|
||||||
|
|
||||||
#define BLAKE2s_SSE2() \
|
|
||||||
PRECOMPUTE_MSG(SP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X8); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X8); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X8); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X8); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X8); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X8); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X8); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X8); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X8); \
|
|
||||||
ROUND_SSE2(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X8)
|
|
||||||
|
|
||||||
#define BLAKE2s_SSSE3() \
|
|
||||||
PRECOMPUTE_MSG(SP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X8, X13, X14); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X8, X13, X14); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X8, X13, X14); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X8, X13, X14); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X8, X13, X14); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X8, X13, X14); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X8, X13, X14); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X8, X13, X14); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X8, X13, X14); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X8, X13, X14)
|
|
||||||
|
|
||||||
#define BLAKE2s_SSE4() \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
|
|
||||||
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0); \
|
|
||||||
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14)
|
|
||||||
|
|
||||||
#define HASH_BLOCKS(h, c, flag, blocks_base, blocks_len, BLAKE2s_FUNC) \
|
|
||||||
MOVQ h, AX; \
|
|
||||||
MOVQ c, BX; \
|
|
||||||
MOVL flag, CX; \
|
|
||||||
MOVQ blocks_base, SI; \
|
|
||||||
MOVQ blocks_len, DX; \
|
|
||||||
\
|
|
||||||
MOVQ SP, BP; \
|
|
||||||
MOVQ SP, R9; \
|
|
||||||
ADDQ $15, R9; \
|
|
||||||
ANDQ $~15, R9; \
|
|
||||||
MOVQ R9, SP; \
|
|
||||||
\
|
|
||||||
MOVQ 0(BX), R9; \
|
|
||||||
MOVQ R9, 0(SP); \
|
|
||||||
XORQ R9, R9; \
|
|
||||||
MOVQ R9, 8(SP); \
|
|
||||||
MOVL CX, 8(SP); \
|
|
||||||
\
|
|
||||||
MOVOU 0(AX), X0; \
|
|
||||||
MOVOU 16(AX), X1; \
|
|
||||||
MOVOU iv0<>(SB), X2; \
|
|
||||||
MOVOU iv1<>(SB), X3 \
|
|
||||||
\
|
|
||||||
MOVOU counter<>(SB), X12; \
|
|
||||||
MOVOU rol16<>(SB), X13; \
|
|
||||||
MOVOU rol8<>(SB), X14; \
|
|
||||||
MOVO 0(SP), X15; \
|
|
||||||
\
|
|
||||||
loop: \
|
|
||||||
MOVO X0, X4; \
|
|
||||||
MOVO X1, X5; \
|
|
||||||
MOVO X2, X6; \
|
|
||||||
MOVO X3, X7; \
|
|
||||||
\
|
|
||||||
PADDQ X12, X15; \
|
|
||||||
PXOR X15, X7; \
|
|
||||||
\
|
|
||||||
BLAKE2s_FUNC(); \
|
|
||||||
\
|
|
||||||
PXOR X4, X0; \
|
|
||||||
PXOR X5, X1; \
|
|
||||||
PXOR X6, X0; \
|
|
||||||
PXOR X7, X1; \
|
|
||||||
\
|
|
||||||
LEAQ 64(SI), SI; \
|
|
||||||
SUBQ $64, DX; \
|
|
||||||
JNE loop; \
|
|
||||||
\
|
|
||||||
MOVO X15, 0(SP); \
|
|
||||||
MOVQ 0(SP), R9; \
|
|
||||||
MOVQ R9, 0(BX); \
|
|
||||||
\
|
|
||||||
MOVOU X0, 0(AX); \
|
|
||||||
MOVOU X1, 16(AX); \
|
|
||||||
\
|
|
||||||
MOVQ BP, SP
|
|
||||||
|
|
||||||
// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
TEXT ·hashBlocksSSE2(SB), 0, $672-48 // frame = 656 + 16 byte alignment
|
|
||||||
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE2)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
TEXT ·hashBlocksSSSE3(SB), 0, $672-48 // frame = 656 + 16 byte alignment
|
|
||||||
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSSE3)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
|
||||||
TEXT ·hashBlocksSSE4(SB), 0, $32-48 // frame = 16 + 16 byte alignment
|
|
||||||
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE4)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func supportSSE4() bool
|
|
||||||
TEXT ·supportSSE4(SB), 4, $0-1
|
|
||||||
MOVL $1, AX
|
|
||||||
CPUID
|
|
||||||
SHRL $19, CX // Bit 19 indicates SSE4.1.
|
|
||||||
ANDL $1, CX
|
|
||||||
MOVB CX, ret+0(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func supportSSSE3() bool
|
|
||||||
TEXT ·supportSSSE3(SB), 4, $0-1
|
|
||||||
MOVL $1, AX
|
|
||||||
CPUID
|
|
||||||
MOVL CX, BX
|
|
||||||
ANDL $0x1, BX // Bit zero indicates SSE3 support.
|
|
||||||
JZ FALSE
|
|
||||||
ANDL $0x200, CX // Bit nine indicates SSSE3 support.
|
|
||||||
JZ FALSE
|
|
||||||
MOVB $1, ret+0(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
FALSE:
|
|
||||||
MOVB $0, ret+0(FP)
|
|
||||||
RET
|
|
174
vendor/golang.org/x/crypto/blake2s/blake2s_generic.go
generated
vendored
174
vendor/golang.org/x/crypto/blake2s/blake2s_generic.go
generated
vendored
|
@ -1,174 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package blake2s
|
|
||||||
|
|
||||||
// the precomputed values for BLAKE2s
|
|
||||||
// there are 10 16-byte arrays - one for each round
|
|
||||||
// the entries are calculated from the sigma constants.
|
|
||||||
var precomputed = [10][16]byte{
|
|
||||||
{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
|
|
||||||
{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
|
|
||||||
{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
|
|
||||||
{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
|
|
||||||
{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
|
|
||||||
{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
|
|
||||||
{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
|
|
||||||
{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
|
|
||||||
{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
|
|
||||||
{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
|
|
||||||
}
|
|
||||||
|
|
||||||
func hashBlocksGeneric(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
|
|
||||||
var m [16]uint32
|
|
||||||
c0, c1 := c[0], c[1]
|
|
||||||
|
|
||||||
for i := 0; i < len(blocks); {
|
|
||||||
c0 += BlockSize
|
|
||||||
if c0 < BlockSize {
|
|
||||||
c1++
|
|
||||||
}
|
|
||||||
|
|
||||||
v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
|
|
||||||
v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
|
|
||||||
v12 ^= c0
|
|
||||||
v13 ^= c1
|
|
||||||
v14 ^= flag
|
|
||||||
|
|
||||||
for j := range m {
|
|
||||||
m[j] = uint32(blocks[i]) | uint32(blocks[i+1])<<8 | uint32(blocks[i+2])<<16 | uint32(blocks[i+3])<<24
|
|
||||||
i += 4
|
|
||||||
}
|
|
||||||
|
|
||||||
for k := range precomputed {
|
|
||||||
s := &(precomputed[k])
|
|
||||||
|
|
||||||
v0 += m[s[0]]
|
|
||||||
v0 += v4
|
|
||||||
v12 ^= v0
|
|
||||||
v12 = v12<<(32-16) | v12>>16
|
|
||||||
v8 += v12
|
|
||||||
v4 ^= v8
|
|
||||||
v4 = v4<<(32-12) | v4>>12
|
|
||||||
v1 += m[s[1]]
|
|
||||||
v1 += v5
|
|
||||||
v13 ^= v1
|
|
||||||
v13 = v13<<(32-16) | v13>>16
|
|
||||||
v9 += v13
|
|
||||||
v5 ^= v9
|
|
||||||
v5 = v5<<(32-12) | v5>>12
|
|
||||||
v2 += m[s[2]]
|
|
||||||
v2 += v6
|
|
||||||
v14 ^= v2
|
|
||||||
v14 = v14<<(32-16) | v14>>16
|
|
||||||
v10 += v14
|
|
||||||
v6 ^= v10
|
|
||||||
v6 = v6<<(32-12) | v6>>12
|
|
||||||
v3 += m[s[3]]
|
|
||||||
v3 += v7
|
|
||||||
v15 ^= v3
|
|
||||||
v15 = v15<<(32-16) | v15>>16
|
|
||||||
v11 += v15
|
|
||||||
v7 ^= v11
|
|
||||||
v7 = v7<<(32-12) | v7>>12
|
|
||||||
|
|
||||||
v0 += m[s[4]]
|
|
||||||
v0 += v4
|
|
||||||
v12 ^= v0
|
|
||||||
v12 = v12<<(32-8) | v12>>8
|
|
||||||
v8 += v12
|
|
||||||
v4 ^= v8
|
|
||||||
v4 = v4<<(32-7) | v4>>7
|
|
||||||
v1 += m[s[5]]
|
|
||||||
v1 += v5
|
|
||||||
v13 ^= v1
|
|
||||||
v13 = v13<<(32-8) | v13>>8
|
|
||||||
v9 += v13
|
|
||||||
v5 ^= v9
|
|
||||||
v5 = v5<<(32-7) | v5>>7
|
|
||||||
v2 += m[s[6]]
|
|
||||||
v2 += v6
|
|
||||||
v14 ^= v2
|
|
||||||
v14 = v14<<(32-8) | v14>>8
|
|
||||||
v10 += v14
|
|
||||||
v6 ^= v10
|
|
||||||
v6 = v6<<(32-7) | v6>>7
|
|
||||||
v3 += m[s[7]]
|
|
||||||
v3 += v7
|
|
||||||
v15 ^= v3
|
|
||||||
v15 = v15<<(32-8) | v15>>8
|
|
||||||
v11 += v15
|
|
||||||
v7 ^= v11
|
|
||||||
v7 = v7<<(32-7) | v7>>7
|
|
||||||
|
|
||||||
v0 += m[s[8]]
|
|
||||||
v0 += v5
|
|
||||||
v15 ^= v0
|
|
||||||
v15 = v15<<(32-16) | v15>>16
|
|
||||||
v10 += v15
|
|
||||||
v5 ^= v10
|
|
||||||
v5 = v5<<(32-12) | v5>>12
|
|
||||||
v1 += m[s[9]]
|
|
||||||
v1 += v6
|
|
||||||
v12 ^= v1
|
|
||||||
v12 = v12<<(32-16) | v12>>16
|
|
||||||
v11 += v12
|
|
||||||
v6 ^= v11
|
|
||||||
v6 = v6<<(32-12) | v6>>12
|
|
||||||
v2 += m[s[10]]
|
|
||||||
v2 += v7
|
|
||||||
v13 ^= v2
|
|
||||||
v13 = v13<<(32-16) | v13>>16
|
|
||||||
v8 += v13
|
|
||||||
v7 ^= v8
|
|
||||||
v7 = v7<<(32-12) | v7>>12
|
|
||||||
v3 += m[s[11]]
|
|
||||||
v3 += v4
|
|
||||||
v14 ^= v3
|
|
||||||
v14 = v14<<(32-16) | v14>>16
|
|
||||||
v9 += v14
|
|
||||||
v4 ^= v9
|
|
||||||
v4 = v4<<(32-12) | v4>>12
|
|
||||||
|
|
||||||
v0 += m[s[12]]
|
|
||||||
v0 += v5
|
|
||||||
v15 ^= v0
|
|
||||||
v15 = v15<<(32-8) | v15>>8
|
|
||||||
v10 += v15
|
|
||||||
v5 ^= v10
|
|
||||||
v5 = v5<<(32-7) | v5>>7
|
|
||||||
v1 += m[s[13]]
|
|
||||||
v1 += v6
|
|
||||||
v12 ^= v1
|
|
||||||
v12 = v12<<(32-8) | v12>>8
|
|
||||||
v11 += v12
|
|
||||||
v6 ^= v11
|
|
||||||
v6 = v6<<(32-7) | v6>>7
|
|
||||||
v2 += m[s[14]]
|
|
||||||
v2 += v7
|
|
||||||
v13 ^= v2
|
|
||||||
v13 = v13<<(32-8) | v13>>8
|
|
||||||
v8 += v13
|
|
||||||
v7 ^= v8
|
|
||||||
v7 = v7<<(32-7) | v7>>7
|
|
||||||
v3 += m[s[15]]
|
|
||||||
v3 += v4
|
|
||||||
v14 ^= v3
|
|
||||||
v14 = v14<<(32-8) | v14>>8
|
|
||||||
v9 += v14
|
|
||||||
v4 ^= v9
|
|
||||||
v4 = v4<<(32-7) | v4>>7
|
|
||||||
}
|
|
||||||
|
|
||||||
h[0] ^= v0 ^ v8
|
|
||||||
h[1] ^= v1 ^ v9
|
|
||||||
h[2] ^= v2 ^ v10
|
|
||||||
h[3] ^= v3 ^ v11
|
|
||||||
h[4] ^= v4 ^ v12
|
|
||||||
h[5] ^= v5 ^ v13
|
|
||||||
h[6] ^= v6 ^ v14
|
|
||||||
h[7] ^= v7 ^ v15
|
|
||||||
}
|
|
||||||
c[0], c[1] = c0, c1
|
|
||||||
}
|
|
18
vendor/golang.org/x/crypto/blake2s/blake2s_ref.go
generated
vendored
18
vendor/golang.org/x/crypto/blake2s/blake2s_ref.go
generated
vendored
|
@ -1,18 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !amd64,!386 gccgo appengine
|
|
||||||
|
|
||||||
package blake2s
|
|
||||||
|
|
||||||
var (
|
|
||||||
useSSE4 = false
|
|
||||||
useSSSE3 = false
|
|
||||||
useSSE2 = false
|
|
||||||
useGeneric = true
|
|
||||||
)
|
|
||||||
|
|
||||||
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
|
|
||||||
hashBlocksGeneric(h, c, flag, blocks)
|
|
||||||
}
|
|
653
vendor/golang.org/x/crypto/blake2s/blake2s_test.go
generated
vendored
653
vendor/golang.org/x/crypto/blake2s/blake2s_test.go
generated
vendored
|
@ -1,653 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package blake2s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestHashes(t *testing.T) {
|
|
||||||
defer func(sse2, ssse3, sse4 bool) {
|
|
||||||
useSSE2, useSSSE3, useSSE4 = sse2, ssse3, sse4
|
|
||||||
}(useSSE2, useSSSE3, useSSE4)
|
|
||||||
|
|
||||||
if useSSE4 {
|
|
||||||
t.Log("SSE4 version")
|
|
||||||
testHashes(t)
|
|
||||||
testHashes128(t)
|
|
||||||
useSSE4 = false
|
|
||||||
}
|
|
||||||
if useSSSE3 {
|
|
||||||
t.Log("SSSE3 version")
|
|
||||||
testHashes(t)
|
|
||||||
testHashes128(t)
|
|
||||||
useSSSE3 = false
|
|
||||||
}
|
|
||||||
if useSSE2 {
|
|
||||||
t.Log("SSE2 version")
|
|
||||||
testHashes(t)
|
|
||||||
testHashes128(t)
|
|
||||||
useSSE2 = false
|
|
||||||
}
|
|
||||||
if useGeneric {
|
|
||||||
t.Log("generic version")
|
|
||||||
testHashes(t)
|
|
||||||
testHashes128(t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testHashes(t *testing.T) {
|
|
||||||
key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
|
|
||||||
|
|
||||||
input := make([]byte, 255)
|
|
||||||
for i := range input {
|
|
||||||
input[i] = byte(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, expectedHex := range hashes {
|
|
||||||
h, err := New256(key)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("#%d: error from New256: %v", i, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.Write(input[:i])
|
|
||||||
sum := h.Sum(nil)
|
|
||||||
|
|
||||||
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
|
|
||||||
t.Fatalf("#%d (single write): got %s, wanted %s", i, gotHex, expectedHex)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
for j := 0; j < i; j++ {
|
|
||||||
h.Write(input[j : j+1])
|
|
||||||
}
|
|
||||||
|
|
||||||
sum = h.Sum(sum[:0])
|
|
||||||
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
|
|
||||||
t.Fatalf("#%d (byte-by-byte): got %s, wanted %s", i, gotHex, expectedHex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testHashes128(t *testing.T) {
|
|
||||||
key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
|
|
||||||
|
|
||||||
input := make([]byte, 255)
|
|
||||||
for i := range input {
|
|
||||||
input[i] = byte(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, expectedHex := range hashes128 {
|
|
||||||
h, err := New128(key)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("#%d: error from New128: %v", i, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.Write(input[:i])
|
|
||||||
sum := h.Sum(nil)
|
|
||||||
|
|
||||||
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
|
|
||||||
t.Fatalf("#%d (single write): got %s, wanted %s", i, gotHex, expectedHex)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
for j := 0; j < i; j++ {
|
|
||||||
h.Write(input[j : j+1])
|
|
||||||
}
|
|
||||||
|
|
||||||
sum = h.Sum(sum[:0])
|
|
||||||
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
|
|
||||||
t.Fatalf("#%d (byte-by-byte): got %s, wanted %s", i, gotHex, expectedHex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Benchmarks
|
|
||||||
|
|
||||||
func benchmarkSum(b *testing.B, size int) {
|
|
||||||
data := make([]byte, size)
|
|
||||||
b.SetBytes(int64(size))
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
Sum256(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkWrite(b *testing.B, size int) {
|
|
||||||
data := make([]byte, size)
|
|
||||||
h, _ := New256(nil)
|
|
||||||
b.SetBytes(int64(size))
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
h.Write(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkWrite64(b *testing.B) { benchmarkWrite(b, 64) }
|
|
||||||
func BenchmarkWrite1K(b *testing.B) { benchmarkWrite(b, 1024) }
|
|
||||||
|
|
||||||
func BenchmarkSum64(b *testing.B) { benchmarkSum(b, 64) }
|
|
||||||
func BenchmarkSum1K(b *testing.B) { benchmarkSum(b, 1024) }
|
|
||||||
|
|
||||||
// hashes is taken from https://blake2.net/blake2s-test.txt
|
|
||||||
var hashes = []string{
|
|
||||||
"48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49",
|
|
||||||
"40d15fee7c328830166ac3f918650f807e7e01e177258cdc0a39b11f598066f1",
|
|
||||||
"6bb71300644cd3991b26ccd4d274acd1adeab8b1d7914546c1198bbe9fc9d803",
|
|
||||||
"1d220dbe2ee134661fdf6d9e74b41704710556f2f6e5a091b227697445dbea6b",
|
|
||||||
"f6c3fbadb4cc687a0064a5be6e791bec63b868ad62fba61b3757ef9ca52e05b2",
|
|
||||||
"49c1f21188dfd769aea0e911dd6b41f14dab109d2b85977aa3088b5c707e8598",
|
|
||||||
"fdd8993dcd43f696d44f3cea0ff35345234ec8ee083eb3cada017c7f78c17143",
|
|
||||||
"e6c8125637438d0905b749f46560ac89fd471cf8692e28fab982f73f019b83a9",
|
|
||||||
"19fc8ca6979d60e6edd3b4541e2f967ced740df6ec1eaebbfe813832e96b2974",
|
|
||||||
"a6ad777ce881b52bb5a4421ab6cdd2dfba13e963652d4d6d122aee46548c14a7",
|
|
||||||
"f5c4b2ba1a00781b13aba0425242c69cb1552f3f71a9a3bb22b4a6b4277b46dd",
|
|
||||||
"e33c4c9bd0cc7e45c80e65c77fa5997fec7002738541509e68a9423891e822a3",
|
|
||||||
"fba16169b2c3ee105be6e1e650e5cbf40746b6753d036ab55179014ad7ef6651",
|
|
||||||
"f5c4bec6d62fc608bf41cc115f16d61c7efd3ff6c65692bbe0afffb1fede7475",
|
|
||||||
"a4862e76db847f05ba17ede5da4e7f91b5925cf1ad4ba12732c3995742a5cd6e",
|
|
||||||
"65f4b860cd15b38ef814a1a804314a55be953caa65fd758ad989ff34a41c1eea",
|
|
||||||
"19ba234f0a4f38637d1839f9d9f76ad91c8522307143c97d5f93f69274cec9a7",
|
|
||||||
"1a67186ca4a5cb8e65fca0e2ecbc5ddc14ae381bb8bffeb9e0a103449e3ef03c",
|
|
||||||
"afbea317b5a2e89c0bd90ccf5d7fd0ed57fe585e4be3271b0a6bf0f5786b0f26",
|
|
||||||
"f1b01558ce541262f5ec34299d6fb4090009e3434be2f49105cf46af4d2d4124",
|
|
||||||
"13a0a0c86335635eaa74ca2d5d488c797bbb4f47dc07105015ed6a1f3309efce",
|
|
||||||
"1580afeebebb346f94d59fe62da0b79237ead7b1491f5667a90e45edf6ca8b03",
|
|
||||||
"20be1a875b38c573dd7faaa0de489d655c11efb6a552698e07a2d331b5f655c3",
|
|
||||||
"be1fe3c4c04018c54c4a0f6b9a2ed3c53abe3a9f76b4d26de56fc9ae95059a99",
|
|
||||||
"e3e3ace537eb3edd8463d9ad3582e13cf86533ffde43d668dd2e93bbdbd7195a",
|
|
||||||
"110c50c0bf2c6e7aeb7e435d92d132ab6655168e78a2decdec3330777684d9c1",
|
|
||||||
"e9ba8f505c9c80c08666a701f3367e6cc665f34b22e73c3c0417eb1c2206082f",
|
|
||||||
"26cd66fca02379c76df12317052bcafd6cd8c3a7b890d805f36c49989782433a",
|
|
||||||
"213f3596d6e3a5d0e9932cd2159146015e2abc949f4729ee2632fe1edb78d337",
|
|
||||||
"1015d70108e03be1c702fe97253607d14aee591f2413ea6787427b6459ff219a",
|
|
||||||
"3ca989de10cfe609909472c8d35610805b2f977734cf652cc64b3bfc882d5d89",
|
|
||||||
"b6156f72d380ee9ea6acd190464f2307a5c179ef01fd71f99f2d0f7a57360aea",
|
|
||||||
"c03bc642b20959cbe133a0303e0c1abff3e31ec8e1a328ec8565c36decff5265",
|
|
||||||
"2c3e08176f760c6264c3a2cd66fec6c3d78de43fc192457b2a4a660a1e0eb22b",
|
|
||||||
"f738c02f3c1b190c512b1a32deabf353728e0e9ab034490e3c3409946a97aeec",
|
|
||||||
"8b1880df301cc963418811088964839287ff7fe31c49ea6ebd9e48bdeee497c5",
|
|
||||||
"1e75cb21c60989020375f1a7a242839f0b0b68973a4c2a05cf7555ed5aaec4c1",
|
|
||||||
"62bf8a9c32a5bccf290b6c474d75b2a2a4093f1a9e27139433a8f2b3bce7b8d7",
|
|
||||||
"166c8350d3173b5e702b783dfd33c66ee0432742e9b92b997fd23c60dc6756ca",
|
|
||||||
"044a14d822a90cacf2f5a101428adc8f4109386ccb158bf905c8618b8ee24ec3",
|
|
||||||
"387d397ea43a994be84d2d544afbe481a2000f55252696bba2c50c8ebd101347",
|
|
||||||
"56f8ccf1f86409b46ce36166ae9165138441577589db08cbc5f66ca29743b9fd",
|
|
||||||
"9706c092b04d91f53dff91fa37b7493d28b576b5d710469df79401662236fc03",
|
|
||||||
"877968686c068ce2f7e2adcff68bf8748edf3cf862cfb4d3947a3106958054e3",
|
|
||||||
"8817e5719879acf7024787eccdb271035566cfa333e049407c0178ccc57a5b9f",
|
|
||||||
"8938249e4b50cadaccdf5b18621326cbb15253e33a20f5636e995d72478de472",
|
|
||||||
"f164abba4963a44d107257e3232d90aca5e66a1408248c51741e991db5227756",
|
|
||||||
"d05563e2b1cba0c4a2a1e8bde3a1a0d9f5b40c85a070d6f5fb21066ead5d0601",
|
|
||||||
"03fbb16384f0a3866f4c3117877666efbf124597564b293d4aab0d269fabddfa",
|
|
||||||
"5fa8486ac0e52964d1881bbe338eb54be2f719549224892057b4da04ba8b3475",
|
|
||||||
"cdfabcee46911111236a31708b2539d71fc211d9b09c0d8530a11e1dbf6eed01",
|
|
||||||
"4f82de03b9504793b82a07a0bdcdff314d759e7b62d26b784946b0d36f916f52",
|
|
||||||
"259ec7f173bcc76a0994c967b4f5f024c56057fb79c965c4fae41875f06a0e4c",
|
|
||||||
"193cc8e7c3e08bb30f5437aa27ade1f142369b246a675b2383e6da9b49a9809e",
|
|
||||||
"5c10896f0e2856b2a2eee0fe4a2c1633565d18f0e93e1fab26c373e8f829654d",
|
|
||||||
"f16012d93f28851a1eb989f5d0b43f3f39ca73c9a62d5181bff237536bd348c3",
|
|
||||||
"2966b3cfae1e44ea996dc5d686cf25fa053fb6f67201b9e46eade85d0ad6b806",
|
|
||||||
"ddb8782485e900bc60bcf4c33a6fd585680cc683d516efa03eb9985fad8715fb",
|
|
||||||
"4c4d6e71aea05786413148fc7a786b0ecaf582cff1209f5a809fba8504ce662c",
|
|
||||||
"fb4c5e86d7b2229b99b8ba6d94c247ef964aa3a2bae8edc77569f28dbbff2d4e",
|
|
||||||
"e94f526de9019633ecd54ac6120f23958d7718f1e7717bf329211a4faeed4e6d",
|
|
||||||
"cbd6660a10db3f23f7a03d4b9d4044c7932b2801ac89d60bc9eb92d65a46c2a0",
|
|
||||||
"8818bbd3db4dc123b25cbba5f54c2bc4b3fcf9bf7d7a7709f4ae588b267c4ece",
|
|
||||||
"c65382513f07460da39833cb666c5ed82e61b9e998f4b0c4287cee56c3cc9bcd",
|
|
||||||
"8975b0577fd35566d750b362b0897a26c399136df07bababbde6203ff2954ed4",
|
|
||||||
"21fe0ceb0052be7fb0f004187cacd7de67fa6eb0938d927677f2398c132317a8",
|
|
||||||
"2ef73f3c26f12d93889f3c78b6a66c1d52b649dc9e856e2c172ea7c58ac2b5e3",
|
|
||||||
"388a3cd56d73867abb5f8401492b6e2681eb69851e767fd84210a56076fb3dd3",
|
|
||||||
"af533e022fc9439e4e3cb838ecd18692232adf6fe9839526d3c3dd1b71910b1a",
|
|
||||||
"751c09d41a9343882a81cd13ee40818d12eb44c6c7f40df16e4aea8fab91972a",
|
|
||||||
"5b73ddb68d9d2b0aa265a07988d6b88ae9aac582af83032f8a9b21a2e1b7bf18",
|
|
||||||
"3da29126c7c5d7f43e64242a79feaa4ef3459cdeccc898ed59a97f6ec93b9dab",
|
|
||||||
"566dc920293da5cb4fe0aa8abda8bbf56f552313bff19046641e3615c1e3ed3f",
|
|
||||||
"4115bea02f73f97f629e5c5590720c01e7e449ae2a6697d4d2783321303692f9",
|
|
||||||
"4ce08f4762468a7670012164878d68340c52a35e66c1884d5c864889abc96677",
|
|
||||||
"81ea0b7804124e0c22ea5fc71104a2afcb52a1fa816f3ecb7dcb5d9dea1786d0",
|
|
||||||
"fe362733b05f6bedaf9379d7f7936ede209b1f8323c3922549d9e73681b5db7b",
|
|
||||||
"eff37d30dfd20359be4e73fdf40d27734b3df90a97a55ed745297294ca85d09f",
|
|
||||||
"172ffc67153d12e0ca76a8b6cd5d4731885b39ce0cac93a8972a18006c8b8baf",
|
|
||||||
"c47957f1cc88e83ef9445839709a480a036bed5f88ac0fcc8e1e703ffaac132c",
|
|
||||||
"30f3548370cfdceda5c37b569b6175e799eef1a62aaa943245ae7669c227a7b5",
|
|
||||||
"c95dcb3cf1f27d0eef2f25d2413870904a877c4a56c2de1e83e2bc2ae2e46821",
|
|
||||||
"d5d0b5d705434cd46b185749f66bfb5836dcdf6ee549a2b7a4aee7f58007caaf",
|
|
||||||
"bbc124a712f15d07c300e05b668389a439c91777f721f8320c1c9078066d2c7e",
|
|
||||||
"a451b48c35a6c7854cfaae60262e76990816382ac0667e5a5c9e1b46c4342ddf",
|
|
||||||
"b0d150fb55e778d01147f0b5d89d99ecb20ff07e5e6760d6b645eb5b654c622b",
|
|
||||||
"34f737c0ab219951eee89a9f8dac299c9d4c38f33fa494c5c6eefc92b6db08bc",
|
|
||||||
"1a62cc3a00800dcbd99891080c1e098458193a8cc9f970ea99fbeff00318c289",
|
|
||||||
"cfce55ebafc840d7ae48281c7fd57ec8b482d4b704437495495ac414cf4a374b",
|
|
||||||
"6746facf71146d999dabd05d093ae586648d1ee28e72617b99d0f0086e1e45bf",
|
|
||||||
"571ced283b3f23b4e750bf12a2caf1781847bd890e43603cdc5976102b7bb11b",
|
|
||||||
"cfcb765b048e35022c5d089d26e85a36b005a2b80493d03a144e09f409b6afd1",
|
|
||||||
"4050c7a27705bb27f42089b299f3cbe5054ead68727e8ef9318ce6f25cd6f31d",
|
|
||||||
"184070bd5d265fbdc142cd1c5cd0d7e414e70369a266d627c8fba84fa5e84c34",
|
|
||||||
"9edda9a4443902a9588c0d0ccc62b930218479a6841e6fe7d43003f04b1fd643",
|
|
||||||
"e412feef7908324a6da1841629f35d3d358642019310ec57c614836b63d30763",
|
|
||||||
"1a2b8edff3f9acc1554fcbae3cf1d6298c6462e22e5eb0259684f835012bd13f",
|
|
||||||
"288c4ad9b9409762ea07c24a41f04f69a7d74bee2d95435374bde946d7241c7b",
|
|
||||||
"805691bb286748cfb591d3aebe7e6f4e4dc6e2808c65143cc004e4eb6fd09d43",
|
|
||||||
"d4ac8d3a0afc6cfa7b460ae3001baeb36dadb37da07d2e8ac91822df348aed3d",
|
|
||||||
"c376617014d20158bced3d3ba552b6eccf84e62aa3eb650e90029c84d13eea69",
|
|
||||||
"c41f09f43cecae7293d6007ca0a357087d5ae59be500c1cd5b289ee810c7b082",
|
|
||||||
"03d1ced1fba5c39155c44b7765cb760c78708dcfc80b0bd8ade3a56da8830b29",
|
|
||||||
"09bde6f152218dc92c41d7f45387e63e5869d807ec70b821405dbd884b7fcf4b",
|
|
||||||
"71c9036e18179b90b37d39e9f05eb89cc5fc341fd7c477d0d7493285faca08a4",
|
|
||||||
"5916833ebb05cd919ca7fe83b692d3205bef72392b2cf6bb0a6d43f994f95f11",
|
|
||||||
"f63aab3ec641b3b024964c2b437c04f6043c4c7e0279239995401958f86bbe54",
|
|
||||||
"f172b180bfb09740493120b6326cbdc561e477def9bbcfd28cc8c1c5e3379a31",
|
|
||||||
"cb9b89cc18381dd9141ade588654d4e6a231d5bf49d4d59ac27d869cbe100cf3",
|
|
||||||
"7bd8815046fdd810a923e1984aaebdcdf84d87c8992d68b5eeb460f93eb3c8d7",
|
|
||||||
"607be66862fd08ee5b19facac09dfdbcd40c312101d66e6ebd2b841f1b9a9325",
|
|
||||||
"9fe03bbe69ab1834f5219b0da88a08b30a66c5913f0151963c360560db0387b3",
|
|
||||||
"90a83585717b75f0e9b725e055eeeeb9e7a028ea7e6cbc07b20917ec0363e38c",
|
|
||||||
"336ea0530f4a7469126e0218587ebbde3358a0b31c29d200f7dc7eb15c6aadd8",
|
|
||||||
"a79e76dc0abca4396f0747cd7b748df913007626b1d659da0c1f78b9303d01a3",
|
|
||||||
"44e78a773756e0951519504d7038d28d0213a37e0ce375371757bc996311e3b8",
|
|
||||||
"77ac012a3f754dcfeab5eb996be9cd2d1f96111b6e49f3994df181f28569d825",
|
|
||||||
"ce5a10db6fccdaf140aaa4ded6250a9c06e9222bc9f9f3658a4aff935f2b9f3a",
|
|
||||||
"ecc203a7fe2be4abd55bb53e6e673572e0078da8cd375ef430cc97f9f80083af",
|
|
||||||
"14a5186de9d7a18b0412b8563e51cc5433840b4a129a8ff963b33a3c4afe8ebb",
|
|
||||||
"13f8ef95cb86e6a638931c8e107673eb76ba10d7c2cd70b9d9920bbeed929409",
|
|
||||||
"0b338f4ee12f2dfcb78713377941e0b0632152581d1332516e4a2cab1942cca4",
|
|
||||||
"eaab0ec37b3b8ab796e9f57238de14a264a076f3887d86e29bb5906db5a00e02",
|
|
||||||
"23cb68b8c0e6dc26dc27766ddc0a13a99438fd55617aa4095d8f969720c872df",
|
|
||||||
"091d8ee30d6f2968d46b687dd65292665742de0bb83dcc0004c72ce10007a549",
|
|
||||||
"7f507abc6d19ba00c065a876ec5657868882d18a221bc46c7a6912541f5bc7ba",
|
|
||||||
"a0607c24e14e8c223db0d70b4d30ee88014d603f437e9e02aa7dafa3cdfbad94",
|
|
||||||
"ddbfea75cc467882eb3483ce5e2e756a4f4701b76b445519e89f22d60fa86e06",
|
|
||||||
"0c311f38c35a4fb90d651c289d486856cd1413df9b0677f53ece2cd9e477c60a",
|
|
||||||
"46a73a8dd3e70f59d3942c01df599def783c9da82fd83222cd662b53dce7dbdf",
|
|
||||||
"ad038ff9b14de84a801e4e621ce5df029dd93520d0c2fa38bff176a8b1d1698c",
|
|
||||||
"ab70c5dfbd1ea817fed0cd067293abf319e5d7901c2141d5d99b23f03a38e748",
|
|
||||||
"1fffda67932b73c8ecaf009a3491a026953babfe1f663b0697c3c4ae8b2e7dcb",
|
|
||||||
"b0d2cc19472dd57f2b17efc03c8d58c2283dbb19da572f7755855aa9794317a0",
|
|
||||||
"a0d19a6ee33979c325510e276622df41f71583d07501b87071129a0ad94732a5",
|
|
||||||
"724642a7032d1062b89e52bea34b75df7d8fe772d9fe3c93ddf3c4545ab5a99b",
|
|
||||||
"ade5eaa7e61f672d587ea03dae7d7b55229c01d06bc0a5701436cbd18366a626",
|
|
||||||
"013b31ebd228fcdda51fabb03bb02d60ac20ca215aafa83bdd855e3755a35f0b",
|
|
||||||
"332ed40bb10dde3c954a75d7b8999d4b26a1c063c1dc6e32c1d91bab7bbb7d16",
|
|
||||||
"c7a197b3a05b566bcc9facd20e441d6f6c2860ac9651cd51d6b9d2cdeeea0390",
|
|
||||||
"bd9cf64ea8953c037108e6f654914f3958b68e29c16700dc184d94a21708ff60",
|
|
||||||
"8835b0ac021151df716474ce27ce4d3c15f0b2dab48003cf3f3efd0945106b9a",
|
|
||||||
"3bfefa3301aa55c080190cffda8eae51d9af488b4c1f24c3d9a75242fd8ea01d",
|
|
||||||
"08284d14993cd47d53ebaecf0df0478cc182c89c00e1859c84851686ddf2c1b7",
|
|
||||||
"1ed7ef9f04c2ac8db6a864db131087f27065098e69c3fe78718d9b947f4a39d0",
|
|
||||||
"c161f2dcd57e9c1439b31a9dd43d8f3d7dd8f0eb7cfac6fb25a0f28e306f0661",
|
|
||||||
"c01969ad34c52caf3dc4d80d19735c29731ac6e7a92085ab9250c48dea48a3fc",
|
|
||||||
"1720b3655619d2a52b3521ae0e49e345cb3389ebd6208acaf9f13fdacca8be49",
|
|
||||||
"756288361c83e24c617cf95c905b22d017cdc86f0bf1d658f4756c7379873b7f",
|
|
||||||
"e7d0eda3452693b752abcda1b55e276f82698f5f1605403eff830bea0071a394",
|
|
||||||
"2c82ecaa6b84803e044af63118afe544687cb6e6c7df49ed762dfd7c8693a1bc",
|
|
||||||
"6136cbf4b441056fa1e2722498125d6ded45e17b52143959c7f4d4e395218ac2",
|
|
||||||
"721d3245aafef27f6a624f47954b6c255079526ffa25e9ff77e5dcff473b1597",
|
|
||||||
"9dd2fbd8cef16c353c0ac21191d509eb28dd9e3e0d8cea5d26ca839393851c3a",
|
|
||||||
"b2394ceacdebf21bf9df2ced98e58f1c3a4bbbff660dd900f62202d6785cc46e",
|
|
||||||
"57089f222749ad7871765f062b114f43ba20ec56422a8b1e3f87192c0ea718c6",
|
|
||||||
"e49a9459961cd33cdf4aae1b1078a5dea7c040e0fea340c93a724872fc4af806",
|
|
||||||
"ede67f720effd2ca9c88994152d0201dee6b0a2d2c077aca6dae29f73f8b6309",
|
|
||||||
"e0f434bf22e3088039c21f719ffc67f0f2cb5e98a7a0194c76e96bf4e8e17e61",
|
|
||||||
"277c04e2853484a4eba910ad336d01b477b67cc200c59f3c8d77eef8494f29cd",
|
|
||||||
"156d5747d0c99c7f27097d7b7e002b2e185cb72d8dd7eb424a0321528161219f",
|
|
||||||
"20ddd1ed9b1ca803946d64a83ae4659da67fba7a1a3eddb1e103c0f5e03e3a2c",
|
|
||||||
"f0af604d3dabbf9a0f2a7d3dda6bd38bba72c6d09be494fcef713ff10189b6e6",
|
|
||||||
"9802bb87def4cc10c4a5fd49aa58dfe2f3fddb46b4708814ead81d23ba95139b",
|
|
||||||
"4f8ce1e51d2fe7f24043a904d898ebfc91975418753413aa099b795ecb35cedb",
|
|
||||||
"bddc6514d7ee6ace0a4ac1d0e068112288cbcf560454642705630177cba608bd",
|
|
||||||
"d635994f6291517b0281ffdd496afa862712e5b3c4e52e4cd5fdae8c0e72fb08",
|
|
||||||
"878d9ca600cf87e769cc305c1b35255186615a73a0da613b5f1c98dbf81283ea",
|
|
||||||
"a64ebe5dc185de9fdde7607b6998702eb23456184957307d2fa72e87a47702d6",
|
|
||||||
"ce50eab7b5eb52bdc9ad8e5a480ab780ca9320e44360b1fe37e03f2f7ad7de01",
|
|
||||||
"eeddb7c0db6e30abe66d79e327511e61fcebbc29f159b40a86b046ecf0513823",
|
|
||||||
"787fc93440c1ec96b5ad01c16cf77916a1405f9426356ec921d8dff3ea63b7e0",
|
|
||||||
"7f0d5eab47eefda696c0bf0fbf86ab216fce461e9303aba6ac374120e890e8df",
|
|
||||||
"b68004b42f14ad029f4c2e03b1d5eb76d57160e26476d21131bef20ada7d27f4",
|
|
||||||
"b0c4eb18ae250b51a41382ead92d0dc7455f9379fc9884428e4770608db0faec",
|
|
||||||
"f92b7a870c059f4d46464c824ec96355140bdce681322cc3a992ff103e3fea52",
|
|
||||||
"5364312614813398cc525d4c4e146edeb371265fba19133a2c3d2159298a1742",
|
|
||||||
"f6620e68d37fb2af5000fc28e23b832297ecd8bce99e8be4d04e85309e3d3374",
|
|
||||||
"5316a27969d7fe04ff27b283961bffc3bf5dfb32fb6a89d101c6c3b1937c2871",
|
|
||||||
"81d1664fdf3cb33c24eebac0bd64244b77c4abea90bbe8b5ee0b2aafcf2d6a53",
|
|
||||||
"345782f295b0880352e924a0467b5fbc3e8f3bfbc3c7e48b67091fb5e80a9442",
|
|
||||||
"794111ea6cd65e311f74ee41d476cb632ce1e4b051dc1d9e9d061a19e1d0bb49",
|
|
||||||
"2a85daf6138816b99bf8d08ba2114b7ab07975a78420c1a3b06a777c22dd8bcb",
|
|
||||||
"89b0d5f289ec16401a069a960d0b093e625da3cf41ee29b59b930c5820145455",
|
|
||||||
"d0fdcb543943fc27d20864f52181471b942cc77ca675bcb30df31d358ef7b1eb",
|
|
||||||
"b17ea8d77063c709d4dc6b879413c343e3790e9e62ca85b7900b086f6b75c672",
|
|
||||||
"e71a3e2c274db842d92114f217e2c0eac8b45093fdfd9df4ca7162394862d501",
|
|
||||||
"c0476759ab7aa333234f6b44f5fd858390ec23694c622cb986e769c78edd733e",
|
|
||||||
"9ab8eabb1416434d85391341d56993c55458167d4418b19a0f2ad8b79a83a75b",
|
|
||||||
"7992d0bbb15e23826f443e00505d68d3ed7372995a5c3e498654102fbcd0964e",
|
|
||||||
"c021b30085151435df33b007ccecc69df1269f39ba25092bed59d932ac0fdc28",
|
|
||||||
"91a25ec0ec0d9a567f89c4bfe1a65a0e432d07064b4190e27dfb81901fd3139b",
|
|
||||||
"5950d39a23e1545f301270aa1a12f2e6c453776e4d6355de425cc153f9818867",
|
|
||||||
"d79f14720c610af179a3765d4b7c0968f977962dbf655b521272b6f1e194488e",
|
|
||||||
"e9531bfc8b02995aeaa75ba27031fadbcbf4a0dab8961d9296cd7e84d25d6006",
|
|
||||||
"34e9c26a01d7f16181b454a9d1623c233cb99d31c694656e9413aca3e918692f",
|
|
||||||
"d9d7422f437bd439ddd4d883dae2a08350173414be78155133fff1964c3d7972",
|
|
||||||
"4aee0c7aaf075414ff1793ead7eaca601775c615dbd60b640b0a9f0ce505d435",
|
|
||||||
"6bfdd15459c83b99f096bfb49ee87b063d69c1974c6928acfcfb4099f8c4ef67",
|
|
||||||
"9fd1c408fd75c336193a2a14d94f6af5adf050b80387b4b010fb29f4cc72707c",
|
|
||||||
"13c88480a5d00d6c8c7ad2110d76a82d9b70f4fa6696d4e5dd42a066dcaf9920",
|
|
||||||
"820e725ee25fe8fd3a8d5abe4c46c3ba889de6fa9191aa22ba67d5705421542b",
|
|
||||||
"32d93a0eb02f42fbbcaf2bad0085b282e46046a4df7ad10657c9d6476375b93e",
|
|
||||||
"adc5187905b1669cd8ec9c721e1953786b9d89a9bae30780f1e1eab24a00523c",
|
|
||||||
"e90756ff7f9ad810b239a10ced2cf9b2284354c1f8c7e0accc2461dc796d6e89",
|
|
||||||
"1251f76e56978481875359801db589a0b22f86d8d634dc04506f322ed78f17e8",
|
|
||||||
"3afa899fd980e73ecb7f4d8b8f291dc9af796bc65d27f974c6f193c9191a09fd",
|
|
||||||
"aa305be26e5deddc3c1010cbc213f95f051c785c5b431e6a7cd048f161787528",
|
|
||||||
"8ea1884ff32e9d10f039b407d0d44e7e670abd884aeee0fb757ae94eaa97373d",
|
|
||||||
"d482b2155d4dec6b4736a1f1617b53aaa37310277d3fef0c37ad41768fc235b4",
|
|
||||||
"4d413971387e7a8898a8dc2a27500778539ea214a2dfe9b3d7e8ebdce5cf3db3",
|
|
||||||
"696e5d46e6c57e8796e4735d08916e0b7929b3cf298c296d22e9d3019653371c",
|
|
||||||
"1f5647c1d3b088228885865c8940908bf40d1a8272821973b160008e7a3ce2eb",
|
|
||||||
"b6e76c330f021a5bda65875010b0edf09126c0f510ea849048192003aef4c61c",
|
|
||||||
"3cd952a0beada41abb424ce47f94b42be64e1ffb0fd0782276807946d0d0bc55",
|
|
||||||
"98d92677439b41b7bb513312afb92bcc8ee968b2e3b238cecb9b0f34c9bb63d0",
|
|
||||||
"ecbca2cf08ae57d517ad16158a32bfa7dc0382eaeda128e91886734c24a0b29d",
|
|
||||||
"942cc7c0b52e2b16a4b89fa4fc7e0bf609e29a08c1a8543452b77c7bfd11bb28",
|
|
||||||
"8a065d8b61a0dffb170d5627735a76b0e9506037808cba16c345007c9f79cf8f",
|
|
||||||
"1b9fa19714659c78ff413871849215361029ac802b1cbcd54e408bd87287f81f",
|
|
||||||
"8dab071bcd6c7292a9ef727b4ae0d86713301da8618d9a48adce55f303a869a1",
|
|
||||||
"8253e3e7c7b684b9cb2beb014ce330ff3d99d17abbdbabe4f4d674ded53ffc6b",
|
|
||||||
"f195f321e9e3d6bd7d074504dd2ab0e6241f92e784b1aa271ff648b1cab6d7f6",
|
|
||||||
"27e4cc72090f241266476a7c09495f2db153d5bcbd761903ef79275ec56b2ed8",
|
|
||||||
"899c2405788e25b99a1846355e646d77cf400083415f7dc5afe69d6e17c00023",
|
|
||||||
"a59b78c4905744076bfee894de707d4f120b5c6893ea0400297d0bb834727632",
|
|
||||||
"59dc78b105649707a2bb4419c48f005400d3973de3736610230435b10424b24f",
|
|
||||||
"c0149d1d7e7a6353a6d906efe728f2f329fe14a4149a3ea77609bc42b975ddfa",
|
|
||||||
"a32f241474a6c16932e9243be0cf09bcdc7e0ca0e7a6a1b9b1a0f01e41502377",
|
|
||||||
"b239b2e4f81841361c1339f68e2c359f929af9ad9f34e01aab4631ad6d5500b0",
|
|
||||||
"85fb419c7002a3e0b4b6ea093b4c1ac6936645b65dac5ac15a8528b7b94c1754",
|
|
||||||
"9619720625f190b93a3fad186ab314189633c0d3a01e6f9bc8c4a8f82f383dbf",
|
|
||||||
"7d620d90fe69fa469a6538388970a1aa09bb48a2d59b347b97e8ce71f48c7f46",
|
|
||||||
"294383568596fb37c75bbacd979c5ff6f20a556bf8879cc72924855df9b8240e",
|
|
||||||
"16b18ab314359c2b833c1c6986d48c55a9fc97cde9a3c1f10a3177140f73f738",
|
|
||||||
"8cbbdd14bc33f04cf45813e4a153a273d36adad5ce71f499eeb87fb8ac63b729",
|
|
||||||
"69c9a498db174ecaefcc5a3ac9fdedf0f813a5bec727f1e775babdec7718816e",
|
|
||||||
"b462c3be40448f1d4f80626254e535b08bc9cdcff599a768578d4b2881a8e3f0",
|
|
||||||
"553e9d9c5f360ac0b74a7d44e5a391dad4ced03e0c24183b7e8ecabdf1715a64",
|
|
||||||
"7a7c55a56fa9ae51e655e01975d8a6ff4ae9e4b486fcbe4eac044588f245ebea",
|
|
||||||
"2afdf3c82abc4867f5de111286c2b3be7d6e48657ba923cfbf101a6dfcf9db9a",
|
|
||||||
"41037d2edcdce0c49b7fb4a6aa0999ca66976c7483afe631d4eda283144f6dfc",
|
|
||||||
"c4466f8497ca2eeb4583a0b08e9d9ac74395709fda109d24f2e4462196779c5d",
|
|
||||||
"75f609338aa67d969a2ae2a2362b2da9d77c695dfd1df7224a6901db932c3364",
|
|
||||||
"68606ceb989d5488fc7cf649f3d7c272ef055da1a93faecd55fe06f6967098ca",
|
|
||||||
"44346bdeb7e052f6255048f0d9b42c425bab9c3dd24168212c3ecf1ebf34e6ae",
|
|
||||||
"8e9cf6e1f366471f2ac7d2ee9b5e6266fda71f8f2e4109f2237ed5f8813fc718",
|
|
||||||
"84bbeb8406d250951f8c1b3e86a7c010082921833dfd9555a2f909b1086eb4b8",
|
|
||||||
"ee666f3eef0f7e2a9c222958c97eaf35f51ced393d714485ab09a069340fdf88",
|
|
||||||
"c153d34a65c47b4a62c5cacf24010975d0356b2f32c8f5da530d338816ad5de6",
|
|
||||||
"9fc5450109e1b779f6c7ae79d56c27635c8dd426c5a9d54e2578db989b8c3b4e",
|
|
||||||
"d12bf3732ef4af5c22fa90356af8fc50fcb40f8f2ea5c8594737a3b3d5abdbd7",
|
|
||||||
"11030b9289bba5af65260672ab6fee88b87420acef4a1789a2073b7ec2f2a09e",
|
|
||||||
"69cb192b8444005c8c0ceb12c846860768188cda0aec27a9c8a55cdee2123632",
|
|
||||||
"db444c15597b5f1a03d1f9edd16e4a9f43a667cc275175dfa2b704e3bb1a9b83",
|
|
||||||
"3fb735061abc519dfe979e54c1ee5bfad0a9d858b3315bad34bde999efd724dd",
|
|
||||||
}
|
|
||||||
|
|
||||||
var hashes128 = []string{
|
|
||||||
"9536f9b267655743dee97b8a670f9f53",
|
|
||||||
"13bacfb85b48a1223c595f8c1e7e82cb",
|
|
||||||
"d47a9b1645e2feae501cd5fe44ce6333",
|
|
||||||
"1e2a79436a7796a3e9826bfedf07659f",
|
|
||||||
"7640360ed3c4f3054dba79a21dda66b7",
|
|
||||||
"d1207ac2bf5ac84fc9ef016da5a46a86",
|
|
||||||
"3123987871e59305ece3125abfc0099a",
|
|
||||||
"cf9e072ad522f2cda2d825218086731c",
|
|
||||||
"95d22870392efe2846b12b6e8e84efbb",
|
|
||||||
"7d63c30e2d51333f245601b038c0b93b",
|
|
||||||
"ed608b98e13976bdf4bedc63fa35e443",
|
|
||||||
"ed704b5cd1abf8e0dd67a6ac667a3fa5",
|
|
||||||
"77dc70109827dc74c70fd26cba379ae5",
|
|
||||||
"d2bf34508b07825ee934f33958f4560e",
|
|
||||||
"a340baa7b8a93a6e658adef42e78eeb7",
|
|
||||||
"b85c5ceaecbe9a251eac76f6932ba395",
|
|
||||||
"246519722001f6e8e97a2183f5985e53",
|
|
||||||
"5bce5aa0b7c6cac2ecf6406183cd779a",
|
|
||||||
"13408f1647c02f6efd0047ad8344f695",
|
|
||||||
"a63970f196760aa36cb965ab62f0e0fa",
|
|
||||||
"bc26f48421dd99fd45e15e736d3e7dac",
|
|
||||||
"4c6f70f9e3237cde918afb52d26f1823",
|
|
||||||
"45ed610cfbc37db80c4bf0eef14ae8d6",
|
|
||||||
"87c4c150705ea5078209ec008200539c",
|
|
||||||
"54de21f5e0e6f2afe04daeb822b6931e",
|
|
||||||
"9732a04e505064e19de3d542e7e71631",
|
|
||||||
"d2bd27e95531d6957eef511c4ba64ad4",
|
|
||||||
"7a36c9f70dcc7c3063b547101a5f6c35",
|
|
||||||
"322007d1a44c4257bc7903b183305529",
|
|
||||||
"dbcc9a09f412290ca2e0d53dfd142ddb",
|
|
||||||
"df12ed43b8e53a56db20e0f83764002c",
|
|
||||||
"d114cc11e7d5b33a360c45f18d4c7c6e",
|
|
||||||
"c43b5e836af88620a8a71b1652cb8640",
|
|
||||||
"9491c653e8867ed73c1b4ac6b5a9bb4d",
|
|
||||||
"06d0e988df94ada6c6f9f36f588ab7c5",
|
|
||||||
"561efad2480e93262c8eeaa3677615c4",
|
|
||||||
"ba8ffc702e5adc93503045eca8702312",
|
|
||||||
"5782be6ccdc78c8425285e85de8ccdc6",
|
|
||||||
"aa1c4393e4c07b53ea6e2b5b1e970771",
|
|
||||||
"42a229dc50e52271c51e8666023ebc1e",
|
|
||||||
"53706110e919f84de7f8d6c7f0e7b831",
|
|
||||||
"fc5ac8ee39cc1dd1424391323e2901bd",
|
|
||||||
"bed27b62ff66cac2fbb68193c727106a",
|
|
||||||
"cd5e689b96d0b9ea7e08dac36f7b211e",
|
|
||||||
"0b4c7f604eba058d18e322c6e1baf173",
|
|
||||||
"eb838227fdfad09a27f0f8413120675d",
|
|
||||||
"3149cf9d19a7fd529e6154a8b4c3b3ad",
|
|
||||||
"ca1e20126df930fd5fb7afe4422191e5",
|
|
||||||
"b23398f910599f3c09b6549fa81bcb46",
|
|
||||||
"27fb17c11b34fa5d8b5afe5ee3321ead",
|
|
||||||
"0f665f5f04cf2d46b7fead1a1f328158",
|
|
||||||
"8f068be73b3681f99f3b282e3c02bba5",
|
|
||||||
"ba189bbd13808dcf4e002a4dd21660d5",
|
|
||||||
"2732dcd1b16668ae6ab6a61595d0d62a",
|
|
||||||
"d410ccdd059f0e02b472ec9ec54bdd3c",
|
|
||||||
"b2eaa07b055b3a03a399971327f7e8c2",
|
|
||||||
"2e8a225655e9f99b69c60dc8b4d8e566",
|
|
||||||
"4eb55416c853f2152e67f8a224133cec",
|
|
||||||
"49552403790d8de0505a8e317a443687",
|
|
||||||
"7f2747cd41f56942752e868212c7d5ac",
|
|
||||||
"02a28f10e193b430df7112d2d98cf759",
|
|
||||||
"d4213404a9f1cf759017747cf5958270",
|
|
||||||
"faa34884344f9c65e944882db8476d34",
|
|
||||||
"ece382a8bd5018f1de5da44b72cea75b",
|
|
||||||
"f1efa90d2547036841ecd3627fafbc36",
|
|
||||||
"811ff8686d23a435ecbd0bdafcd27b1b",
|
|
||||||
"b21beea9c7385f657a76558530438721",
|
|
||||||
"9cb969da4f1b4fc5b13bf78fe366f0c4",
|
|
||||||
"8850d16d7b614d3268ccfa009d33c7fc",
|
|
||||||
"aa98a2b6176ea86415b9aff3268c6f6d",
|
|
||||||
"ec3e1efa5ed195eff667e16b1af1e39e",
|
|
||||||
"e40787dca57411d2630db2de699beb08",
|
|
||||||
"554835890735babd06318de23d31e78a",
|
|
||||||
"493957feecddc302ee2bb2086b6ebfd3",
|
|
||||||
"f6069709ad5b0139163717e9ce1114ab",
|
|
||||||
"ba5ed386098da284484b211555505a01",
|
|
||||||
"9244c8dfad8cbb68c118fa51465b3ae4",
|
|
||||||
"51e309a5008eb1f5185e5cc007cfb36f",
|
|
||||||
"6ce9ff712121b4f6087955f4911eafd4",
|
|
||||||
"59b51d8dcda031218ccdd7c760828155",
|
|
||||||
"0012878767a3d4f1c8194458cf1f8832",
|
|
||||||
"82900708afd5b6582dc16f008c655edd",
|
|
||||||
"21302c7e39b5a4cdf1d6f86b4f00c9b4",
|
|
||||||
"e894c7431591eab8d1ce0fe2aa1f01df",
|
|
||||||
"b67e1c40ee9d988226d605621854d955",
|
|
||||||
"6237bdafa34137cbbec6be43ea9bd22c",
|
|
||||||
"4172a8e19b0dcb09b978bb9eff7af52b",
|
|
||||||
"5714abb55bd4448a5a6ad09fbd872fdf",
|
|
||||||
"7ce1700bef423e1f958a94a77a94d44a",
|
|
||||||
"3742ec50cded528527775833453e0b26",
|
|
||||||
"5d41b135724c7c9c689495324b162f18",
|
|
||||||
"85c523333c6442c202e9e6e0f1185f93",
|
|
||||||
"5c71f5222d40ff5d90e7570e71ab2d30",
|
|
||||||
"6e18912e83d012efb4c66250ced6f0d9",
|
|
||||||
"4add4448c2e35e0b138a0bac7b4b1775",
|
|
||||||
"c0376c6bc5e7b8b9d2108ec25d2aab53",
|
|
||||||
"f72261d5ed156765c977751c8a13fcc1",
|
|
||||||
"cff4156c48614b6ceed3dd6b9058f17e",
|
|
||||||
"36bfb513f76c15f514bcb593419835aa",
|
|
||||||
"166bf48c6bffaf8291e6fdf63854bef4",
|
|
||||||
"0b67d33f8b859c3157fbabd9e6e47ed0",
|
|
||||||
"e4da659ca76c88e73a9f9f10f3d51789",
|
|
||||||
"33c1ae2a86b3f51c0642e6ed5b5aa1f1",
|
|
||||||
"27469b56aca2334449c1cf4970dcd969",
|
|
||||||
"b7117b2e363378aa0901b0d6a9f6ddc0",
|
|
||||||
"a9578233b09e5cd5231943fdb12cd90d",
|
|
||||||
"486d7d75253598b716a068243c1c3e89",
|
|
||||||
"66f6b02d682b78ffdc85e9ec86852489",
|
|
||||||
"38a07b9a4b228fbcc305476e4d2e05d2",
|
|
||||||
"aedb61c7970e7d05bf9002dae3c6858c",
|
|
||||||
"c03ef441f7dd30fdb61ad2d4d8e4c7da",
|
|
||||||
"7f45cc1eea9a00cb6aeb2dd748361190",
|
|
||||||
"a59538b358459132e55160899e47bd65",
|
|
||||||
"137010fef72364411820c3fbed15c8df",
|
|
||||||
"d8362b93fc504500dbd33ac74e1b4d70",
|
|
||||||
"a7e49f12c8f47e3b29cf8c0889b0a9c8",
|
|
||||||
"072e94ffbfc684bd8ab2a1b9dade2fd5",
|
|
||||||
"5ab438584bd2229e452052e002631a5f",
|
|
||||||
"f233d14221097baef57d3ec205c9e086",
|
|
||||||
"3a95db000c4a8ff98dc5c89631a7f162",
|
|
||||||
"0544f18c2994ab4ddf1728f66041ff16",
|
|
||||||
"0bc02116c60a3cc331928d6c9d3ba37e",
|
|
||||||
"b189dca6cb5b813c74200834fba97f29",
|
|
||||||
"ac8aaab075b4a5bc24419da239212650",
|
|
||||||
"1e9f19323dc71c29ae99c479dc7e8df9",
|
|
||||||
"12d944c3fa7caa1b3d62adfc492274dd",
|
|
||||||
"b4c68f1fffe8f0030e9b18aad8c9dc96",
|
|
||||||
"25887fab1422700d7fa3edc0b20206e2",
|
|
||||||
"8c09f698d03eaf88abf69f8147865ef6",
|
|
||||||
"5c363ae42a5bec26fbc5e996428d9bd7",
|
|
||||||
"7fdfc2e854fbb3928150d5e3abcf56d6",
|
|
||||||
"f0c944023f714df115f9e4f25bcdb89b",
|
|
||||||
"6d19534b4c332741c8ddd79a9644de2d",
|
|
||||||
"32595eb23764fbfc2ee7822649f74a12",
|
|
||||||
"5a51391aab33c8d575019b6e76ae052a",
|
|
||||||
"98b861ce2c620f10f913af5d704a5afd",
|
|
||||||
"b7fe2fc8b77fb1ce434f8465c7ddf793",
|
|
||||||
"0e8406e0cf8e9cc840668ece2a0fc64e",
|
|
||||||
"b89922db99c58f6a128ccffe19b6ce60",
|
|
||||||
"e1be9af665f0932b77d7f5631a511db7",
|
|
||||||
"74b96f20f58de8dc9ff5e31f91828523",
|
|
||||||
"36a4cfef5a2a7d8548db6710e50b3009",
|
|
||||||
"007e95e8d3b91948a1dedb91f75de76b",
|
|
||||||
"a87a702ce08f5745edf765bfcd5fbe0d",
|
|
||||||
"847e69a388a749a9c507354d0dddfe09",
|
|
||||||
"07176eefbc107a78f058f3d424ca6a54",
|
|
||||||
"ad7e80682333b68296f6cb2b4a8e446d",
|
|
||||||
"53c4aba43896ae422e5de5b9edbd46bf",
|
|
||||||
"33bd6c20ca2a7ab916d6e98003c6c5f8",
|
|
||||||
"060d088ea94aa093f9981a79df1dfcc8",
|
|
||||||
"5617b214b9df08d4f11e58f5e76d9a56",
|
|
||||||
"ca3a60ee85bd971e1daf9f7db059d909",
|
|
||||||
"cd2b7754505d8c884eddf736f1ec613e",
|
|
||||||
"f496163b252f1439e7e113ba2ecabd8e",
|
|
||||||
"5719c7dcf9d9f756d6213354acb7d5cf",
|
|
||||||
"6f7dd40b245c54411e7a9be83ae5701c",
|
|
||||||
"c8994dd9fdeb077a45ea04a30358b637",
|
|
||||||
"4b1184f1e35458c1c747817d527a252f",
|
|
||||||
"fc7df674afeac7a3fd994183f4c67a74",
|
|
||||||
"4f68e05ce4dcc533acf9c7c01d95711e",
|
|
||||||
"d4ebc59e918400720035dfc88e0c486a",
|
|
||||||
"d3105dd6fa123e543b0b3a6e0eeaea9e",
|
|
||||||
"874196128ed443f5bdb2800ca048fcad",
|
|
||||||
"01645f134978dc8f9cf0abc93b53780e",
|
|
||||||
"5b8b64caa257873a0ffd47c981ef6c3f",
|
|
||||||
"4ee208fc50ba0a6e65c5b58cec44c923",
|
|
||||||
"53f409a52427b3b7ffabb057ca088428",
|
|
||||||
"c1d6cd616f5341a93d921e356e5887a9",
|
|
||||||
"e85c20fea67fa7320dc23379181183c8",
|
|
||||||
"7912b6409489df001b7372bc94aebde7",
|
|
||||||
"e559f761ec866a87f1f331767fafc60f",
|
|
||||||
"20a6f5a36bc37043d977ed7708465ef8",
|
|
||||||
"6a72f526965ab120826640dd784c6cc4",
|
|
||||||
"bf486d92ad68e87c613689dd370d001b",
|
|
||||||
"d339fd0eb35edf3abd6419c8d857acaf",
|
|
||||||
"9521cd7f32306d969ddabc4e6a617f52",
|
|
||||||
"a1cd9f3e81520842f3cf6cc301cb0021",
|
|
||||||
"18e879b6f154492d593edd3f4554e237",
|
|
||||||
"66e2329c1f5137589e051592587e521e",
|
|
||||||
"e899566dd6c3e82cbc83958e69feb590",
|
|
||||||
"8a4b41d7c47e4e80659d77b4e4bfc9ae",
|
|
||||||
"f1944f6fcfc17803405a1101998c57dd",
|
|
||||||
"f6bcec07567b4f72851b307139656b18",
|
|
||||||
"22e7bb256918fe9924dce9093e2d8a27",
|
|
||||||
"dd25b925815fe7b50b7079f5f65a3970",
|
|
||||||
"0457f10f299acf0c230dd4007612e58f",
|
|
||||||
"ecb420c19efd93814fae2964d69b54af",
|
|
||||||
"14eb47b06dff685d88751c6e32789db4",
|
|
||||||
"e8f072dbb50d1ab6654aa162604a892d",
|
|
||||||
"69cff9c62092332f03a166c7b0034469",
|
|
||||||
"d3619f98970b798ca32c6c14cd25af91",
|
|
||||||
"2246d423774ee9d51a551e89c0539d9e",
|
|
||||||
"75e5d1a1e374a04a699247dad827b6cf",
|
|
||||||
"6d087dd1d4cd15bf47db07c7a96b1db8",
|
|
||||||
"967e4c055ac51b4b2a3e506cebd5826f",
|
|
||||||
"7417aa79247e473401bfa92a25b62e2a",
|
|
||||||
"24f3f4956da34b5c533d9a551ccd7b16",
|
|
||||||
"0c40382de693a5304e2331eb951cc962",
|
|
||||||
"9436f949d51b347db5c8e6258dafaaac",
|
|
||||||
"d2084297fe84c4ba6e04e4fb73d734fe",
|
|
||||||
"42a6f8ff590af21b512e9e088257aa34",
|
|
||||||
"c484ad06b1cdb3a54f3f6464a7a2a6fd",
|
|
||||||
"1b8ac860f5ceb4365400a201ed2917aa",
|
|
||||||
"c43eadabbe7b7473f3f837fc52650f54",
|
|
||||||
"0e5d3205406126b1f838875deb150d6a",
|
|
||||||
"6bf4946f8ec8a9c417f50cd1e67565be",
|
|
||||||
"42f09a2522314799c95b3fc121a0e3e8",
|
|
||||||
"06b8f1487f691a3f7c3f74e133d55870",
|
|
||||||
"1a70a65fb4f314dcf6a31451a9d2704f",
|
|
||||||
"7d4acdd0823279fd28a1e48b49a04669",
|
|
||||||
"09545cc8822a5dfc93bbab708fd69174",
|
|
||||||
"efc063db625013a83c9a426d39a9bddb",
|
|
||||||
"213bbf89b3f5be0ffdb14854bbcb2588",
|
|
||||||
"b69624d89fe2774df9a6f43695d755d4",
|
|
||||||
"c0f9ff9ded82bd73c512e365a894774d",
|
|
||||||
"d1b68507ed89c17ead6f69012982db71",
|
|
||||||
"14cf16db04648978e35c44850855d1b0",
|
|
||||||
"9f254d4eccab74cd91d694df863650a8",
|
|
||||||
"8f8946e2967baa4a814d36ff01d20813",
|
|
||||||
"6b9dc4d24ecba166cb2915d7a6cba43b",
|
|
||||||
"eb35a80418a0042b850e294db7898d4d",
|
|
||||||
"f55f925d280c637d54055c9df088ef5f",
|
|
||||||
"f48427a04f67e33f3ba0a17f7c9704a7",
|
|
||||||
"4a9f5bfcc0321aea2eced896cee65894",
|
|
||||||
"8723a67d1a1df90f1cef96e6fe81e702",
|
|
||||||
"c166c343ee25998f80bad4067960d3fd",
|
|
||||||
"dab67288d16702e676a040fd42344d73",
|
|
||||||
"c8e9e0d80841eb2c116dd14c180e006c",
|
|
||||||
"92294f546bacf0dea9042c93ecba8b34",
|
|
||||||
"013705b1502b37369ad22fe8237d444e",
|
|
||||||
"9b97f8837d5f2ebab0768fc9a6446b93",
|
|
||||||
"7e7e5236b05ec35f89edf8bf655498e7",
|
|
||||||
"7be8f2362c174c776fb9432fe93bf259",
|
|
||||||
"2422e80420276d2df5702c6470879b01",
|
|
||||||
"df645795db778bcce23bbe819a76ba48",
|
|
||||||
"3f97a4ac87dfc58761cda1782d749074",
|
|
||||||
"50e3f45df21ebfa1b706b9c0a1c245a8",
|
|
||||||
"7879541c7ff612c7ddf17cb8f7260183",
|
|
||||||
"67f6542b903b7ba1945eba1a85ee6b1c",
|
|
||||||
"b34b73d36ab6234b8d3f5494d251138e",
|
|
||||||
"0aea139641fdba59ab1103479a96e05f",
|
|
||||||
"02776815a87b8ba878453666d42afe3c",
|
|
||||||
"5929ab0a90459ebac5a16e2fb37c847e",
|
|
||||||
"c244def5b20ce0468f2b5012d04ac7fd",
|
|
||||||
"12116add6fefce36ed8a0aeccce9b6d3",
|
|
||||||
"3cd743841e9d8b878f34d91b793b4fad",
|
|
||||||
"45e87510cf5705262185f46905fae35f",
|
|
||||||
"276047016b0bfb501b2d4fc748165793",
|
|
||||||
"ddd245df5a799417d350bd7f4e0b0b7e",
|
|
||||||
"d34d917a54a2983f3fdbc4b14caae382",
|
|
||||||
"7730fbc09d0c1fb1939a8fc436f6b995",
|
|
||||||
"eb4899ef257a1711cc9270a19702e5b5",
|
|
||||||
"8a30932014bce35bba620895d374df7a",
|
|
||||||
"1924aabf9c50aa00bee5e1f95b5d9e12",
|
|
||||||
"1758d6f8b982aec9fbe50f20e3082b46",
|
|
||||||
"cd075928ab7e6883e697fe7fd3ac43ee",
|
|
||||||
}
|
|
21
vendor/golang.org/x/crypto/blake2s/register.go
generated
vendored
21
vendor/golang.org/x/crypto/blake2s/register.go
generated
vendored
|
@ -1,21 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.9
|
|
||||||
|
|
||||||
package blake2s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto"
|
|
||||||
"hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
newHash256 := func() hash.Hash {
|
|
||||||
h, _ := New256(nil)
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
crypto.RegisterHash(crypto.BLAKE2s_256, newHash256)
|
|
||||||
}
|
|
2
vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
2
vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
|
@ -39,7 +39,7 @@ func NewCipher(key []byte) (*Cipher, error) {
|
||||||
|
|
||||||
// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
|
// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
|
||||||
// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
|
// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
|
||||||
// sufficient and desirable. For bcrypt compatibility, the key can be over 56
|
// sufficient and desirable. For bcrypt compatiblity, the key can be over 56
|
||||||
// bytes.
|
// bytes.
|
||||||
func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
|
func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
|
||||||
if len(salt) == 0 {
|
if len(salt) == 0 {
|
||||||
|
|
4
vendor/golang.org/x/crypto/bn256/constants.go
generated
vendored
4
vendor/golang.org/x/crypto/bn256/constants.go
generated
vendored
|
@ -16,10 +16,10 @@ func bigFromBase10(s string) *big.Int {
|
||||||
// u is the BN parameter that determines the prime: 1868033³.
|
// u is the BN parameter that determines the prime: 1868033³.
|
||||||
var u = bigFromBase10("6518589491078791937")
|
var u = bigFromBase10("6518589491078791937")
|
||||||
|
|
||||||
// p is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1.
|
// p is a prime over which we form a basic field: 36u⁴+36u³+24u³+6u+1.
|
||||||
var p = bigFromBase10("65000549695646603732796438742359905742825358107623003571877145026864184071783")
|
var p = bigFromBase10("65000549695646603732796438742359905742825358107623003571877145026864184071783")
|
||||||
|
|
||||||
// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1.
|
// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u³+6u+1.
|
||||||
var Order = bigFromBase10("65000549695646603732796438742359905742570406053903786389881062969044166799969")
|
var Order = bigFromBase10("65000549695646603732796438742359905742570406053903786389881062969044166799969")
|
||||||
|
|
||||||
// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+3.
|
// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+3.
|
||||||
|
|
83
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
generated
vendored
83
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
generated
vendored
|
@ -1,83 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD as specified in RFC 7539.
|
|
||||||
package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/cipher"
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// KeySize is the size of the key used by this AEAD, in bytes.
|
|
||||||
KeySize = 32
|
|
||||||
// NonceSize is the size of the nonce used with this AEAD, in bytes.
|
|
||||||
NonceSize = 12
|
|
||||||
)
|
|
||||||
|
|
||||||
type chacha20poly1305 struct {
|
|
||||||
key [32]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a ChaCha20-Poly1305 AEAD that uses the given, 256-bit key.
|
|
||||||
func New(key []byte) (cipher.AEAD, error) {
|
|
||||||
if len(key) != KeySize {
|
|
||||||
return nil, errors.New("chacha20poly1305: bad key length")
|
|
||||||
}
|
|
||||||
ret := new(chacha20poly1305)
|
|
||||||
copy(ret.key[:], key)
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) NonceSize() int {
|
|
||||||
return NonceSize
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) Overhead() int {
|
|
||||||
return 16
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
|
|
||||||
if len(nonce) != NonceSize {
|
|
||||||
panic("chacha20poly1305: bad nonce length passed to Seal")
|
|
||||||
}
|
|
||||||
|
|
||||||
if uint64(len(plaintext)) > (1<<38)-64 {
|
|
||||||
panic("chacha20poly1305: plaintext too large")
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.seal(dst, nonce, plaintext, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
var errOpen = errors.New("chacha20poly1305: message authentication failed")
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
|
|
||||||
if len(nonce) != NonceSize {
|
|
||||||
panic("chacha20poly1305: bad nonce length passed to Open")
|
|
||||||
}
|
|
||||||
if len(ciphertext) < 16 {
|
|
||||||
return nil, errOpen
|
|
||||||
}
|
|
||||||
if uint64(len(ciphertext)) > (1<<38)-48 {
|
|
||||||
panic("chacha20poly1305: ciphertext too large")
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.open(dst, nonce, ciphertext, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
// sliceForAppend takes a slice and a requested number of bytes. It returns a
|
|
||||||
// slice with the contents of the given slice followed by that many bytes and a
|
|
||||||
// second slice that aliases into it and contains only the extra bytes. If the
|
|
||||||
// original slice has sufficient capacity then no allocation is performed.
|
|
||||||
func sliceForAppend(in []byte, n int) (head, tail []byte) {
|
|
||||||
if total := len(in) + n; cap(in) >= total {
|
|
||||||
head = in[:total]
|
|
||||||
} else {
|
|
||||||
head = make([]byte, total)
|
|
||||||
copy(head, in)
|
|
||||||
}
|
|
||||||
tail = head[len(in):]
|
|
||||||
return
|
|
||||||
}
|
|
127
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
generated
vendored
127
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
generated
vendored
|
@ -1,127 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.7,amd64,!gccgo,!appengine
|
|
||||||
|
|
||||||
package chacha20poly1305
|
|
||||||
|
|
||||||
import "encoding/binary"
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
|
|
||||||
|
|
||||||
// cpuid is implemented in chacha20poly1305_amd64.s.
|
|
||||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
|
||||||
|
|
||||||
// xgetbv with ecx = 0 is implemented in chacha20poly1305_amd64.s.
|
|
||||||
func xgetbv() (eax, edx uint32)
|
|
||||||
|
|
||||||
var (
|
|
||||||
useASM bool
|
|
||||||
useAVX2 bool
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
detectCPUFeatures()
|
|
||||||
}
|
|
||||||
|
|
||||||
// detectCPUFeatures is used to detect if cpu instructions
|
|
||||||
// used by the functions implemented in assembler in
|
|
||||||
// chacha20poly1305_amd64.s are supported.
|
|
||||||
func detectCPUFeatures() {
|
|
||||||
maxID, _, _, _ := cpuid(0, 0)
|
|
||||||
if maxID < 1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, ecx1, _ := cpuid(1, 0)
|
|
||||||
|
|
||||||
haveSSSE3 := isSet(9, ecx1)
|
|
||||||
useASM = haveSSSE3
|
|
||||||
|
|
||||||
haveOSXSAVE := isSet(27, ecx1)
|
|
||||||
|
|
||||||
osSupportsAVX := false
|
|
||||||
// For XGETBV, OSXSAVE bit is required and sufficient.
|
|
||||||
if haveOSXSAVE {
|
|
||||||
eax, _ := xgetbv()
|
|
||||||
// Check if XMM and YMM registers have OS support.
|
|
||||||
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
|
|
||||||
}
|
|
||||||
haveAVX := isSet(28, ecx1) && osSupportsAVX
|
|
||||||
|
|
||||||
if maxID < 7 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, ebx7, _, _ := cpuid(7, 0)
|
|
||||||
haveAVX2 := isSet(5, ebx7) && haveAVX
|
|
||||||
haveBMI2 := isSet(8, ebx7)
|
|
||||||
|
|
||||||
useAVX2 = haveAVX2 && haveBMI2
|
|
||||||
}
|
|
||||||
|
|
||||||
// isSet checks if bit at bitpos is set in value.
|
|
||||||
func isSet(bitpos uint, value uint32) bool {
|
|
||||||
return value&(1<<bitpos) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// setupState writes a ChaCha20 input matrix to state. See
|
|
||||||
// https://tools.ietf.org/html/rfc7539#section-2.3.
|
|
||||||
func setupState(state *[16]uint32, key *[32]byte, nonce []byte) {
|
|
||||||
state[0] = 0x61707865
|
|
||||||
state[1] = 0x3320646e
|
|
||||||
state[2] = 0x79622d32
|
|
||||||
state[3] = 0x6b206574
|
|
||||||
|
|
||||||
state[4] = binary.LittleEndian.Uint32(key[:4])
|
|
||||||
state[5] = binary.LittleEndian.Uint32(key[4:8])
|
|
||||||
state[6] = binary.LittleEndian.Uint32(key[8:12])
|
|
||||||
state[7] = binary.LittleEndian.Uint32(key[12:16])
|
|
||||||
state[8] = binary.LittleEndian.Uint32(key[16:20])
|
|
||||||
state[9] = binary.LittleEndian.Uint32(key[20:24])
|
|
||||||
state[10] = binary.LittleEndian.Uint32(key[24:28])
|
|
||||||
state[11] = binary.LittleEndian.Uint32(key[28:32])
|
|
||||||
|
|
||||||
state[12] = 0
|
|
||||||
state[13] = binary.LittleEndian.Uint32(nonce[:4])
|
|
||||||
state[14] = binary.LittleEndian.Uint32(nonce[4:8])
|
|
||||||
state[15] = binary.LittleEndian.Uint32(nonce[8:12])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
|
|
||||||
if !useASM {
|
|
||||||
return c.sealGeneric(dst, nonce, plaintext, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
var state [16]uint32
|
|
||||||
setupState(&state, &c.key, nonce)
|
|
||||||
|
|
||||||
ret, out := sliceForAppend(dst, len(plaintext)+16)
|
|
||||||
chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
|
|
||||||
if !useASM {
|
|
||||||
return c.openGeneric(dst, nonce, ciphertext, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
var state [16]uint32
|
|
||||||
setupState(&state, &c.key, nonce)
|
|
||||||
|
|
||||||
ciphertext = ciphertext[:len(ciphertext)-16]
|
|
||||||
ret, out := sliceForAppend(dst, len(ciphertext))
|
|
||||||
if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
|
|
||||||
for i := range out {
|
|
||||||
out[i] = 0
|
|
||||||
}
|
|
||||||
return nil, errOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
2714
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
generated
vendored
2714
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
generated
vendored
File diff suppressed because it is too large
Load diff
70
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
generated
vendored
70
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
generated
vendored
|
@ -1,70 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package chacha20poly1305
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/chacha20poly1305/internal/chacha20"
|
|
||||||
"golang.org/x/crypto/poly1305"
|
|
||||||
)
|
|
||||||
|
|
||||||
func roundTo16(n int) int {
|
|
||||||
return 16 * ((n + 15) / 16)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
|
|
||||||
var counter [16]byte
|
|
||||||
copy(counter[4:], nonce)
|
|
||||||
|
|
||||||
var polyKey [32]byte
|
|
||||||
chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key)
|
|
||||||
|
|
||||||
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
|
|
||||||
counter[0] = 1
|
|
||||||
chacha20.XORKeyStream(out, plaintext, &counter, &c.key)
|
|
||||||
|
|
||||||
polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(plaintext))+8+8)
|
|
||||||
copy(polyInput, additionalData)
|
|
||||||
copy(polyInput[roundTo16(len(additionalData)):], out[:len(plaintext)])
|
|
||||||
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-16:], uint64(len(additionalData)))
|
|
||||||
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(plaintext)))
|
|
||||||
|
|
||||||
var tag [poly1305.TagSize]byte
|
|
||||||
poly1305.Sum(&tag, polyInput, &polyKey)
|
|
||||||
copy(out[len(plaintext):], tag[:])
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
|
|
||||||
var tag [poly1305.TagSize]byte
|
|
||||||
copy(tag[:], ciphertext[len(ciphertext)-16:])
|
|
||||||
ciphertext = ciphertext[:len(ciphertext)-16]
|
|
||||||
|
|
||||||
var counter [16]byte
|
|
||||||
copy(counter[4:], nonce)
|
|
||||||
|
|
||||||
var polyKey [32]byte
|
|
||||||
chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key)
|
|
||||||
|
|
||||||
polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(ciphertext))+8+8)
|
|
||||||
copy(polyInput, additionalData)
|
|
||||||
copy(polyInput[roundTo16(len(additionalData)):], ciphertext)
|
|
||||||
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-16:], uint64(len(additionalData)))
|
|
||||||
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(ciphertext)))
|
|
||||||
|
|
||||||
ret, out := sliceForAppend(dst, len(ciphertext))
|
|
||||||
if !poly1305.Verify(&tag, polyInput, &polyKey) {
|
|
||||||
for i := range out {
|
|
||||||
out[i] = 0
|
|
||||||
}
|
|
||||||
return nil, errOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
counter[0] = 1
|
|
||||||
chacha20.XORKeyStream(out, ciphertext, &counter, &c.key)
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
15
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
generated
vendored
15
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
generated
vendored
|
@ -1,15 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !amd64 !go1.7 gccgo appengine
|
|
||||||
|
|
||||||
package chacha20poly1305
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
|
|
||||||
return c.sealGeneric(dst, nonce, plaintext, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
|
|
||||||
return c.openGeneric(dst, nonce, ciphertext, additionalData)
|
|
||||||
}
|
|
182
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_test.go
generated
vendored
182
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_test.go
generated
vendored
|
@ -1,182 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package chacha20poly1305
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
cr "crypto/rand"
|
|
||||||
"encoding/hex"
|
|
||||||
mr "math/rand"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVectors(t *testing.T) {
|
|
||||||
for i, test := range chacha20Poly1305Tests {
|
|
||||||
key, _ := hex.DecodeString(test.key)
|
|
||||||
nonce, _ := hex.DecodeString(test.nonce)
|
|
||||||
ad, _ := hex.DecodeString(test.aad)
|
|
||||||
plaintext, _ := hex.DecodeString(test.plaintext)
|
|
||||||
|
|
||||||
aead, err := New(key)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ct := aead.Seal(nil, nonce, plaintext, ad)
|
|
||||||
if ctHex := hex.EncodeToString(ct); ctHex != test.out {
|
|
||||||
t.Errorf("#%d: got %s, want %s", i, ctHex, test.out)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
plaintext2, err := aead.Open(nil, nonce, ct, ad)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("#%d: Open failed", i)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(plaintext, plaintext2) {
|
|
||||||
t.Errorf("#%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ad) > 0 {
|
|
||||||
alterAdIdx := mr.Intn(len(ad))
|
|
||||||
ad[alterAdIdx] ^= 0x80
|
|
||||||
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
|
||||||
t.Errorf("#%d: Open was successful after altering additional data", i)
|
|
||||||
}
|
|
||||||
ad[alterAdIdx] ^= 0x80
|
|
||||||
}
|
|
||||||
|
|
||||||
alterNonceIdx := mr.Intn(aead.NonceSize())
|
|
||||||
nonce[alterNonceIdx] ^= 0x80
|
|
||||||
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
|
||||||
t.Errorf("#%d: Open was successful after altering nonce", i)
|
|
||||||
}
|
|
||||||
nonce[alterNonceIdx] ^= 0x80
|
|
||||||
|
|
||||||
alterCtIdx := mr.Intn(len(ct))
|
|
||||||
ct[alterCtIdx] ^= 0x80
|
|
||||||
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
|
|
||||||
t.Errorf("#%d: Open was successful after altering ciphertext", i)
|
|
||||||
}
|
|
||||||
ct[alterCtIdx] ^= 0x80
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRandom(t *testing.T) {
|
|
||||||
// Some random tests to verify Open(Seal) == Plaintext
|
|
||||||
for i := 0; i < 256; i++ {
|
|
||||||
var nonce [12]byte
|
|
||||||
var key [32]byte
|
|
||||||
|
|
||||||
al := mr.Intn(128)
|
|
||||||
pl := mr.Intn(16384)
|
|
||||||
ad := make([]byte, al)
|
|
||||||
plaintext := make([]byte, pl)
|
|
||||||
cr.Read(key[:])
|
|
||||||
cr.Read(nonce[:])
|
|
||||||
cr.Read(ad)
|
|
||||||
cr.Read(plaintext)
|
|
||||||
|
|
||||||
aead, err := New(key[:])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ct := aead.Seal(nil, nonce[:], plaintext, ad)
|
|
||||||
|
|
||||||
plaintext2, err := aead.Open(nil, nonce[:], ct, ad)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Random #%d: Open failed", i)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(plaintext, plaintext2) {
|
|
||||||
t.Errorf("Random #%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ad) > 0 {
|
|
||||||
alterAdIdx := mr.Intn(len(ad))
|
|
||||||
ad[alterAdIdx] ^= 0x80
|
|
||||||
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
|
||||||
t.Errorf("Random #%d: Open was successful after altering additional data", i)
|
|
||||||
}
|
|
||||||
ad[alterAdIdx] ^= 0x80
|
|
||||||
}
|
|
||||||
|
|
||||||
alterNonceIdx := mr.Intn(aead.NonceSize())
|
|
||||||
nonce[alterNonceIdx] ^= 0x80
|
|
||||||
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
|
||||||
t.Errorf("Random #%d: Open was successful after altering nonce", i)
|
|
||||||
}
|
|
||||||
nonce[alterNonceIdx] ^= 0x80
|
|
||||||
|
|
||||||
alterCtIdx := mr.Intn(len(ct))
|
|
||||||
ct[alterCtIdx] ^= 0x80
|
|
||||||
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
|
|
||||||
t.Errorf("Random #%d: Open was successful after altering ciphertext", i)
|
|
||||||
}
|
|
||||||
ct[alterCtIdx] ^= 0x80
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchamarkChaCha20Poly1305Seal(b *testing.B, buf []byte) {
|
|
||||||
b.SetBytes(int64(len(buf)))
|
|
||||||
|
|
||||||
var key [32]byte
|
|
||||||
var nonce [12]byte
|
|
||||||
var ad [13]byte
|
|
||||||
var out []byte
|
|
||||||
|
|
||||||
aead, _ := New(key[:])
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
out = aead.Seal(out[:0], nonce[:], buf[:], ad[:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchamarkChaCha20Poly1305Open(b *testing.B, buf []byte) {
|
|
||||||
b.SetBytes(int64(len(buf)))
|
|
||||||
|
|
||||||
var key [32]byte
|
|
||||||
var nonce [12]byte
|
|
||||||
var ad [13]byte
|
|
||||||
var ct []byte
|
|
||||||
var out []byte
|
|
||||||
|
|
||||||
aead, _ := New(key[:])
|
|
||||||
ct = aead.Seal(ct[:0], nonce[:], buf[:], ad[:])
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
out, _ = aead.Open(out[:0], nonce[:], ct[:], ad[:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkChacha20Poly1305Open_64(b *testing.B) {
|
|
||||||
benchamarkChaCha20Poly1305Open(b, make([]byte, 64))
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkChacha20Poly1305Seal_64(b *testing.B) {
|
|
||||||
benchamarkChaCha20Poly1305Seal(b, make([]byte, 64))
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkChacha20Poly1305Open_1350(b *testing.B) {
|
|
||||||
benchamarkChaCha20Poly1305Open(b, make([]byte, 1350))
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkChacha20Poly1305Seal_1350(b *testing.B) {
|
|
||||||
benchamarkChaCha20Poly1305Seal(b, make([]byte, 1350))
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkChacha20Poly1305Open_8K(b *testing.B) {
|
|
||||||
benchamarkChaCha20Poly1305Open(b, make([]byte, 8*1024))
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkChacha20Poly1305Seal_8K(b *testing.B) {
|
|
||||||
benchamarkChaCha20Poly1305Seal(b, make([]byte, 8*1024))
|
|
||||||
}
|
|
332
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_vectors_test.go
generated
vendored
332
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_vectors_test.go
generated
vendored
File diff suppressed because one or more lines are too long
199
vendor/golang.org/x/crypto/chacha20poly1305/internal/chacha20/chacha_generic.go
generated
vendored
199
vendor/golang.org/x/crypto/chacha20poly1305/internal/chacha20/chacha_generic.go
generated
vendored
|
@ -1,199 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package ChaCha20 implements the core ChaCha20 function as specified in https://tools.ietf.org/html/rfc7539#section-2.3.
|
|
||||||
package chacha20
|
|
||||||
|
|
||||||
import "encoding/binary"
|
|
||||||
|
|
||||||
const rounds = 20
|
|
||||||
|
|
||||||
// core applies the ChaCha20 core function to 16-byte input in, 32-byte key k,
|
|
||||||
// and 16-byte constant c, and puts the result into 64-byte array out.
|
|
||||||
func core(out *[64]byte, in *[16]byte, k *[32]byte) {
|
|
||||||
j0 := uint32(0x61707865)
|
|
||||||
j1 := uint32(0x3320646e)
|
|
||||||
j2 := uint32(0x79622d32)
|
|
||||||
j3 := uint32(0x6b206574)
|
|
||||||
j4 := binary.LittleEndian.Uint32(k[0:4])
|
|
||||||
j5 := binary.LittleEndian.Uint32(k[4:8])
|
|
||||||
j6 := binary.LittleEndian.Uint32(k[8:12])
|
|
||||||
j7 := binary.LittleEndian.Uint32(k[12:16])
|
|
||||||
j8 := binary.LittleEndian.Uint32(k[16:20])
|
|
||||||
j9 := binary.LittleEndian.Uint32(k[20:24])
|
|
||||||
j10 := binary.LittleEndian.Uint32(k[24:28])
|
|
||||||
j11 := binary.LittleEndian.Uint32(k[28:32])
|
|
||||||
j12 := binary.LittleEndian.Uint32(in[0:4])
|
|
||||||
j13 := binary.LittleEndian.Uint32(in[4:8])
|
|
||||||
j14 := binary.LittleEndian.Uint32(in[8:12])
|
|
||||||
j15 := binary.LittleEndian.Uint32(in[12:16])
|
|
||||||
|
|
||||||
x0, x1, x2, x3, x4, x5, x6, x7 := j0, j1, j2, j3, j4, j5, j6, j7
|
|
||||||
x8, x9, x10, x11, x12, x13, x14, x15 := j8, j9, j10, j11, j12, j13, j14, j15
|
|
||||||
|
|
||||||
for i := 0; i < rounds; i += 2 {
|
|
||||||
x0 += x4
|
|
||||||
x12 ^= x0
|
|
||||||
x12 = (x12 << 16) | (x12 >> (16))
|
|
||||||
x8 += x12
|
|
||||||
x4 ^= x8
|
|
||||||
x4 = (x4 << 12) | (x4 >> (20))
|
|
||||||
x0 += x4
|
|
||||||
x12 ^= x0
|
|
||||||
x12 = (x12 << 8) | (x12 >> (24))
|
|
||||||
x8 += x12
|
|
||||||
x4 ^= x8
|
|
||||||
x4 = (x4 << 7) | (x4 >> (25))
|
|
||||||
x1 += x5
|
|
||||||
x13 ^= x1
|
|
||||||
x13 = (x13 << 16) | (x13 >> 16)
|
|
||||||
x9 += x13
|
|
||||||
x5 ^= x9
|
|
||||||
x5 = (x5 << 12) | (x5 >> 20)
|
|
||||||
x1 += x5
|
|
||||||
x13 ^= x1
|
|
||||||
x13 = (x13 << 8) | (x13 >> 24)
|
|
||||||
x9 += x13
|
|
||||||
x5 ^= x9
|
|
||||||
x5 = (x5 << 7) | (x5 >> 25)
|
|
||||||
x2 += x6
|
|
||||||
x14 ^= x2
|
|
||||||
x14 = (x14 << 16) | (x14 >> 16)
|
|
||||||
x10 += x14
|
|
||||||
x6 ^= x10
|
|
||||||
x6 = (x6 << 12) | (x6 >> 20)
|
|
||||||
x2 += x6
|
|
||||||
x14 ^= x2
|
|
||||||
x14 = (x14 << 8) | (x14 >> 24)
|
|
||||||
x10 += x14
|
|
||||||
x6 ^= x10
|
|
||||||
x6 = (x6 << 7) | (x6 >> 25)
|
|
||||||
x3 += x7
|
|
||||||
x15 ^= x3
|
|
||||||
x15 = (x15 << 16) | (x15 >> 16)
|
|
||||||
x11 += x15
|
|
||||||
x7 ^= x11
|
|
||||||
x7 = (x7 << 12) | (x7 >> 20)
|
|
||||||
x3 += x7
|
|
||||||
x15 ^= x3
|
|
||||||
x15 = (x15 << 8) | (x15 >> 24)
|
|
||||||
x11 += x15
|
|
||||||
x7 ^= x11
|
|
||||||
x7 = (x7 << 7) | (x7 >> 25)
|
|
||||||
x0 += x5
|
|
||||||
x15 ^= x0
|
|
||||||
x15 = (x15 << 16) | (x15 >> 16)
|
|
||||||
x10 += x15
|
|
||||||
x5 ^= x10
|
|
||||||
x5 = (x5 << 12) | (x5 >> 20)
|
|
||||||
x0 += x5
|
|
||||||
x15 ^= x0
|
|
||||||
x15 = (x15 << 8) | (x15 >> 24)
|
|
||||||
x10 += x15
|
|
||||||
x5 ^= x10
|
|
||||||
x5 = (x5 << 7) | (x5 >> 25)
|
|
||||||
x1 += x6
|
|
||||||
x12 ^= x1
|
|
||||||
x12 = (x12 << 16) | (x12 >> 16)
|
|
||||||
x11 += x12
|
|
||||||
x6 ^= x11
|
|
||||||
x6 = (x6 << 12) | (x6 >> 20)
|
|
||||||
x1 += x6
|
|
||||||
x12 ^= x1
|
|
||||||
x12 = (x12 << 8) | (x12 >> 24)
|
|
||||||
x11 += x12
|
|
||||||
x6 ^= x11
|
|
||||||
x6 = (x6 << 7) | (x6 >> 25)
|
|
||||||
x2 += x7
|
|
||||||
x13 ^= x2
|
|
||||||
x13 = (x13 << 16) | (x13 >> 16)
|
|
||||||
x8 += x13
|
|
||||||
x7 ^= x8
|
|
||||||
x7 = (x7 << 12) | (x7 >> 20)
|
|
||||||
x2 += x7
|
|
||||||
x13 ^= x2
|
|
||||||
x13 = (x13 << 8) | (x13 >> 24)
|
|
||||||
x8 += x13
|
|
||||||
x7 ^= x8
|
|
||||||
x7 = (x7 << 7) | (x7 >> 25)
|
|
||||||
x3 += x4
|
|
||||||
x14 ^= x3
|
|
||||||
x14 = (x14 << 16) | (x14 >> 16)
|
|
||||||
x9 += x14
|
|
||||||
x4 ^= x9
|
|
||||||
x4 = (x4 << 12) | (x4 >> 20)
|
|
||||||
x3 += x4
|
|
||||||
x14 ^= x3
|
|
||||||
x14 = (x14 << 8) | (x14 >> 24)
|
|
||||||
x9 += x14
|
|
||||||
x4 ^= x9
|
|
||||||
x4 = (x4 << 7) | (x4 >> 25)
|
|
||||||
}
|
|
||||||
|
|
||||||
x0 += j0
|
|
||||||
x1 += j1
|
|
||||||
x2 += j2
|
|
||||||
x3 += j3
|
|
||||||
x4 += j4
|
|
||||||
x5 += j5
|
|
||||||
x6 += j6
|
|
||||||
x7 += j7
|
|
||||||
x8 += j8
|
|
||||||
x9 += j9
|
|
||||||
x10 += j10
|
|
||||||
x11 += j11
|
|
||||||
x12 += j12
|
|
||||||
x13 += j13
|
|
||||||
x14 += j14
|
|
||||||
x15 += j15
|
|
||||||
|
|
||||||
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], x4)
|
|
||||||
binary.LittleEndian.PutUint32(out[20:24], x5)
|
|
||||||
binary.LittleEndian.PutUint32(out[24:28], x6)
|
|
||||||
binary.LittleEndian.PutUint32(out[28:32], x7)
|
|
||||||
binary.LittleEndian.PutUint32(out[32:36], x8)
|
|
||||||
binary.LittleEndian.PutUint32(out[36:40], x9)
|
|
||||||
binary.LittleEndian.PutUint32(out[40:44], x10)
|
|
||||||
binary.LittleEndian.PutUint32(out[44:48], x11)
|
|
||||||
binary.LittleEndian.PutUint32(out[48:52], x12)
|
|
||||||
binary.LittleEndian.PutUint32(out[52:56], x13)
|
|
||||||
binary.LittleEndian.PutUint32(out[56:60], x14)
|
|
||||||
binary.LittleEndian.PutUint32(out[60:64], x15)
|
|
||||||
}
|
|
||||||
|
|
||||||
// XORKeyStream crypts bytes from in to out using the given key and counters.
|
|
||||||
// In and out may be the same slice but otherwise should not overlap. Counter
|
|
||||||
// contains the raw ChaCha20 counter bytes (i.e. block counter followed by
|
|
||||||
// nonce).
|
|
||||||
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
|
|
||||||
var block [64]byte
|
|
||||||
var counterCopy [16]byte
|
|
||||||
copy(counterCopy[:], counter[:])
|
|
||||||
|
|
||||||
for len(in) >= 64 {
|
|
||||||
core(&block, &counterCopy, key)
|
|
||||||
for i, x := range block {
|
|
||||||
out[i] = in[i] ^ x
|
|
||||||
}
|
|
||||||
u := uint32(1)
|
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
u += uint32(counterCopy[i])
|
|
||||||
counterCopy[i] = byte(u)
|
|
||||||
u >>= 8
|
|
||||||
}
|
|
||||||
in = in[64:]
|
|
||||||
out = out[64:]
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(in) > 0 {
|
|
||||||
core(&block, &counterCopy, key)
|
|
||||||
for i, v := range in {
|
|
||||||
out[i] = v ^ block[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
33
vendor/golang.org/x/crypto/chacha20poly1305/internal/chacha20/chacha_test.go
generated
vendored
33
vendor/golang.org/x/crypto/chacha20poly1305/internal/chacha20/chacha_test.go
generated
vendored
|
@ -1,33 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package chacha20
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/hex"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCore(t *testing.T) {
|
|
||||||
// This is just a smoke test that checks the example from
|
|
||||||
// https://tools.ietf.org/html/rfc7539#section-2.3.2. The
|
|
||||||
// chacha20poly1305 package contains much more extensive tests of this
|
|
||||||
// code.
|
|
||||||
var key [32]byte
|
|
||||||
for i := range key {
|
|
||||||
key[i] = byte(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
var input [16]byte
|
|
||||||
input[0] = 1
|
|
||||||
input[7] = 9
|
|
||||||
input[11] = 0x4a
|
|
||||||
|
|
||||||
var out [64]byte
|
|
||||||
XORKeyStream(out[:], out[:], &input, &key)
|
|
||||||
const expected = "10f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e"
|
|
||||||
if result := hex.EncodeToString(out[:]); result != expected {
|
|
||||||
t.Errorf("wanted %x but got %x", expected, result)
|
|
||||||
}
|
|
||||||
}
|
|
1
vendor/golang.org/x/crypto/codereview.cfg
generated
vendored
1
vendor/golang.org/x/crypto/codereview.cfg
generated
vendored
|
@ -1 +0,0 @@
|
||||||
issuerepo: golang/go
|
|
604
vendor/golang.org/x/crypto/cryptobyte/asn1.go
generated
vendored
604
vendor/golang.org/x/crypto/cryptobyte/asn1.go
generated
vendored
|
@ -1,604 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package cryptobyte
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/asn1"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
"reflect"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This file contains ASN.1-related methods for String and Builder.
|
|
||||||
|
|
||||||
// Tag represents an ASN.1 tag number and class (together also referred to as
|
|
||||||
// identifier octets). Methods in this package only support the low-tag-number
|
|
||||||
// form, i.e. a single identifier octet with bits 7-8 encoding the class and
|
|
||||||
// bits 1-6 encoding the tag number.
|
|
||||||
type Tag uint8
|
|
||||||
|
|
||||||
// Contructed returns t with the context-specific class bit set.
|
|
||||||
func (t Tag) ContextSpecific() Tag { return t | 0x80 }
|
|
||||||
|
|
||||||
// Contructed returns t with the constructed class bit set.
|
|
||||||
func (t Tag) Constructed() Tag { return t | 0x20 }
|
|
||||||
|
|
||||||
// Builder
|
|
||||||
|
|
||||||
// AddASN1Int64 appends a DER-encoded ASN.1 INTEGER.
|
|
||||||
func (b *Builder) AddASN1Int64(v int64) {
|
|
||||||
b.addASN1Signed(asn1.TagInteger, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION.
|
|
||||||
func (b *Builder) AddASN1Enum(v int64) {
|
|
||||||
b.addASN1Signed(asn1.TagEnum, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Builder) addASN1Signed(tag Tag, v int64) {
|
|
||||||
b.AddASN1(tag, func(c *Builder) {
|
|
||||||
length := 1
|
|
||||||
for i := v; i >= 0x80 || i < -0x80; i >>= 8 {
|
|
||||||
length++
|
|
||||||
}
|
|
||||||
|
|
||||||
for ; length > 0; length-- {
|
|
||||||
i := v >> uint((length-1)*8) & 0xff
|
|
||||||
c.AddUint8(uint8(i))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddASN1Uint64 appends a DER-encoded ASN.1 INTEGER.
|
|
||||||
func (b *Builder) AddASN1Uint64(v uint64) {
|
|
||||||
b.AddASN1(asn1.TagInteger, func(c *Builder) {
|
|
||||||
length := 1
|
|
||||||
for i := v; i >= 0x80; i >>= 8 {
|
|
||||||
length++
|
|
||||||
}
|
|
||||||
|
|
||||||
for ; length > 0; length-- {
|
|
||||||
i := v >> uint((length-1)*8) & 0xff
|
|
||||||
c.AddUint8(uint8(i))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddASN1BigInt appends a DER-encoded ASN.1 INTEGER.
|
|
||||||
func (b *Builder) AddASN1BigInt(n *big.Int) {
|
|
||||||
if b.err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
b.AddASN1(asn1.TagInteger, func(c *Builder) {
|
|
||||||
if n.Sign() < 0 {
|
|
||||||
// A negative number has to be converted to two's-complement form. So we
|
|
||||||
// invert and subtract 1. 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 bytes[0]&0x80 == 0 {
|
|
||||||
c.add(0xff)
|
|
||||||
}
|
|
||||||
c.add(bytes...)
|
|
||||||
} else if n.Sign() == 0 {
|
|
||||||
c.add(0)
|
|
||||||
} else {
|
|
||||||
bytes := n.Bytes()
|
|
||||||
if bytes[0]&0x80 != 0 {
|
|
||||||
c.add(0)
|
|
||||||
}
|
|
||||||
c.add(bytes...)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddASN1OctetString appends a DER-encoded ASN.1 OCTET STRING.
|
|
||||||
func (b *Builder) AddASN1OctetString(bytes []byte) {
|
|
||||||
b.AddASN1(asn1.TagOctetString, func(c *Builder) {
|
|
||||||
c.AddBytes(bytes)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const generalizedTimeFormatStr = "20060102150405Z0700"
|
|
||||||
|
|
||||||
// AddASN1GeneralizedTime appends a DER-encoded ASN.1 GENERALIZEDTIME.
|
|
||||||
func (b *Builder) AddASN1GeneralizedTime(t time.Time) {
|
|
||||||
if t.Year() < 0 || t.Year() > 9999 {
|
|
||||||
b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b.AddASN1(asn1.TagGeneralizedTime, func(c *Builder) {
|
|
||||||
c.AddBytes([]byte(t.Format(generalizedTimeFormatStr)))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING.
|
|
||||||
func (b *Builder) AddASN1BitString(s asn1.BitString) {
|
|
||||||
// TODO(martinkr): Implement.
|
|
||||||
b.MarshalASN1(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalASN1 calls asn1.Marshal on its input and appends the result if
|
|
||||||
// successful or records an error if one occurred.
|
|
||||||
func (b *Builder) MarshalASN1(v interface{}) {
|
|
||||||
// NOTE(martinkr): This is somewhat of a hack to allow propagation of
|
|
||||||
// asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a
|
|
||||||
// value embedded into a struct, its tag information is lost.
|
|
||||||
if b.err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bytes, err := asn1.Marshal(v)
|
|
||||||
if err != nil {
|
|
||||||
b.err = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b.AddBytes(bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddASN1 appends an ASN.1 object. The object is prefixed with the given tag.
|
|
||||||
// Tags greater than 30 are not supported and result in an error (i.e.
|
|
||||||
// low-tag-number form only). The child builder passed to the
|
|
||||||
// BuilderContinuation can be used to build the content of the ASN.1 object.
|
|
||||||
func (b *Builder) AddASN1(tag Tag, f BuilderContinuation) {
|
|
||||||
if b.err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Identifiers with the low five bits set indicate high-tag-number format
|
|
||||||
// (two or more octets), which we don't support.
|
|
||||||
if tag&0x1f == 0x1f {
|
|
||||||
b.err = fmt.Errorf("cryptobyte: high-tag number identifier octects not supported: 0x%x", tag)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b.AddUint8(uint8(tag))
|
|
||||||
b.addLengthPrefixed(1, true, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String
|
|
||||||
|
|
||||||
var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
|
|
||||||
|
|
||||||
// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
|
|
||||||
// not point to an integer or to a big.Int, it panics. It returns true on
|
|
||||||
// success and false on error.
|
|
||||||
func (s *String) ReadASN1Integer(out interface{}) bool {
|
|
||||||
if reflect.TypeOf(out).Kind() != reflect.Ptr {
|
|
||||||
panic("out is not a pointer")
|
|
||||||
}
|
|
||||||
switch reflect.ValueOf(out).Elem().Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
var i int64
|
|
||||||
if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
reflect.ValueOf(out).Elem().SetInt(i)
|
|
||||||
return true
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
var u uint64
|
|
||||||
if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
reflect.ValueOf(out).Elem().SetUint(u)
|
|
||||||
return true
|
|
||||||
case reflect.Struct:
|
|
||||||
if reflect.TypeOf(out).Elem() == bigIntType {
|
|
||||||
return s.readASN1BigInt(out.(*big.Int))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
panic("out does not point to an integer type")
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkASN1Integer(bytes []byte) bool {
|
|
||||||
if len(bytes) == 0 {
|
|
||||||
// An INTEGER is encoded with at least one octet.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if len(bytes) == 1 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if bytes[0] == 0 && bytes[1]&0x80 == 0 || bytes[0] == 0xff && bytes[1]&0x80 == 0x80 {
|
|
||||||
// Value is not minimally encoded.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
var bigOne = big.NewInt(1)
|
|
||||||
|
|
||||||
func (s *String) readASN1BigInt(out *big.Int) bool {
|
|
||||||
var bytes String
|
|
||||||
if !s.ReadASN1(&bytes, asn1.TagInteger) || !checkASN1Integer(bytes) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if bytes[0]&0x80 == 0x80 {
|
|
||||||
// Negative number.
|
|
||||||
neg := make([]byte, len(bytes))
|
|
||||||
for i, b := range bytes {
|
|
||||||
neg[i] = ^b
|
|
||||||
}
|
|
||||||
out.SetBytes(neg)
|
|
||||||
out.Add(out, bigOne)
|
|
||||||
out.Neg(out)
|
|
||||||
} else {
|
|
||||||
out.SetBytes(bytes)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *String) readASN1Int64(out *int64) bool {
|
|
||||||
var bytes String
|
|
||||||
if !s.ReadASN1(&bytes, asn1.TagInteger) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func asn1Signed(out *int64, n []byte) bool {
|
|
||||||
length := len(n)
|
|
||||||
if length > 8 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
*out <<= 8
|
|
||||||
*out |= int64(n[i])
|
|
||||||
}
|
|
||||||
// Shift up and down in order to sign extend the result.
|
|
||||||
*out <<= 64 - uint8(length)*8
|
|
||||||
*out >>= 64 - uint8(length)*8
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *String) readASN1Uint64(out *uint64) bool {
|
|
||||||
var bytes String
|
|
||||||
if !s.ReadASN1(&bytes, asn1.TagInteger) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func asn1Unsigned(out *uint64, n []byte) bool {
|
|
||||||
length := len(n)
|
|
||||||
if length > 9 || length == 9 && n[0] != 0 {
|
|
||||||
// Too large for uint64.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if n[0]&0x80 != 0 {
|
|
||||||
// Negative number.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
*out <<= 8
|
|
||||||
*out |= uint64(n[i])
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It returns
|
|
||||||
// true on success and false on error.
|
|
||||||
func (s *String) ReadASN1Enum(out *int) bool {
|
|
||||||
var bytes String
|
|
||||||
var i int64
|
|
||||||
if !s.ReadASN1(&bytes, asn1.TagEnum) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if int64(int(i)) != i {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*out = int(i)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *String) readBase128Int(out *int) bool {
|
|
||||||
ret := 0
|
|
||||||
for i := 0; len(*s) > 0; i++ {
|
|
||||||
if i == 4 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
ret <<= 7
|
|
||||||
b := s.read(1)[0]
|
|
||||||
ret |= int(b & 0x7f)
|
|
||||||
if b&0x80 == 0 {
|
|
||||||
*out = ret
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false // truncated
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and
|
|
||||||
// advances. It returns true on success and false on error.
|
|
||||||
func (s *String) ReadASN1ObjectIdentifier(out *asn1.ObjectIdentifier) bool {
|
|
||||||
var bytes String
|
|
||||||
if !s.ReadASN1(&bytes, asn1.TagOID) || len(bytes) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the worst case, we get two elements from the first byte (which is
|
|
||||||
// encoded differently) and then every varint is a single byte long.
|
|
||||||
components := make([]int, len(bytes)+1)
|
|
||||||
|
|
||||||
// The first varint is 40*value1 + value2:
|
|
||||||
// According to this packing, value1 can take the values 0, 1 and 2 only.
|
|
||||||
// When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
|
|
||||||
// then there are no restrictions on value2.
|
|
||||||
var v int
|
|
||||||
if !bytes.readBase128Int(&v) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if v < 80 {
|
|
||||||
components[0] = v / 40
|
|
||||||
components[1] = v % 40
|
|
||||||
} else {
|
|
||||||
components[0] = 2
|
|
||||||
components[1] = v - 80
|
|
||||||
}
|
|
||||||
|
|
||||||
i := 2
|
|
||||||
for ; len(bytes) > 0; i++ {
|
|
||||||
if !bytes.readBase128Int(&v) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
components[i] = v
|
|
||||||
}
|
|
||||||
*out = components[:i]
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and
|
|
||||||
// advances. It returns true on success and false on error.
|
|
||||||
func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
|
|
||||||
var bytes String
|
|
||||||
if !s.ReadASN1(&bytes, asn1.TagGeneralizedTime) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
t := string(bytes)
|
|
||||||
res, err := time.Parse(generalizedTimeFormatStr, t)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if serialized := res.Format(generalizedTimeFormatStr); serialized != t {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*out = res
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It
|
|
||||||
// returns true on success and false on error.
|
|
||||||
func (s *String) ReadASN1BitString(out *asn1.BitString) bool {
|
|
||||||
var bytes String
|
|
||||||
if !s.ReadASN1(&bytes, asn1.TagBitString) || len(bytes) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
paddingBits := uint8(bytes[0])
|
|
||||||
bytes = bytes[1:]
|
|
||||||
if paddingBits > 7 ||
|
|
||||||
len(bytes) == 0 && paddingBits != 0 ||
|
|
||||||
len(bytes) > 0 && bytes[len(bytes)-1]&(1<<paddingBits-1) != 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
out.BitLength = len(bytes)*8 - int(paddingBits)
|
|
||||||
out.Bytes = bytes
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadASN1Bytes reads the contents of a DER-encoded ASN.1 element (not including
|
|
||||||
// tag and length bytes) into out, and advances. The element must match the
|
|
||||||
// given tag. It returns true on success and false on error.
|
|
||||||
func (s *String) ReadASN1Bytes(out *[]byte, tag Tag) bool {
|
|
||||||
return s.ReadASN1((*String)(out), tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadASN1 reads the contents of a DER-encoded ASN.1 element (not including
|
|
||||||
// tag and length bytes) into out, and advances. The element must match the
|
|
||||||
// given tag. It returns true on success and false on error.
|
|
||||||
//
|
|
||||||
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
|
|
||||||
func (s *String) ReadASN1(out *String, tag Tag) bool {
|
|
||||||
var t Tag
|
|
||||||
if !s.ReadAnyASN1(out, &t) || t != tag {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadASN1Element reads the contents of a DER-encoded ASN.1 element (including
|
|
||||||
// tag and length bytes) into out, and advances. The element must match the
|
|
||||||
// given tag. It returns true on success and false on error.
|
|
||||||
//
|
|
||||||
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
|
|
||||||
func (s *String) ReadASN1Element(out *String, tag Tag) bool {
|
|
||||||
var t Tag
|
|
||||||
if !s.ReadAnyASN1Element(out, &t) || t != tag {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadAnyASN1 reads the contents of a DER-encoded ASN.1 element (not including
|
|
||||||
// tag and length bytes) into out, sets outTag to its tag, and advances. It
|
|
||||||
// returns true on success and false on error.
|
|
||||||
//
|
|
||||||
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
|
|
||||||
func (s *String) ReadAnyASN1(out *String, outTag *Tag) bool {
|
|
||||||
return s.readASN1(out, outTag, true /* skip header */)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadAnyASN1Element reads the contents of a DER-encoded ASN.1 element
|
|
||||||
// (including tag and length bytes) into out, sets outTag to is tag, and
|
|
||||||
// advances. It returns true on success and false on error.
|
|
||||||
//
|
|
||||||
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
|
|
||||||
func (s *String) ReadAnyASN1Element(out *String, outTag *Tag) bool {
|
|
||||||
return s.readASN1(out, outTag, false /* include header */)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PeekASN1Tag returns true if the next ASN.1 value on the string starts with
|
|
||||||
// the given tag.
|
|
||||||
func (s String) PeekASN1Tag(tag Tag) bool {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return Tag(s[0]) == tag
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadOptionalASN1 attempts to read the contents of a DER-encoded ASN.Element
|
|
||||||
// (not including tag and length bytes) tagged with the given tag into out. It
|
|
||||||
// stores whether an element with the tag was found in outPresent, unless
|
|
||||||
// outPresent is nil. It returns true on success and false on error.
|
|
||||||
func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag Tag) bool {
|
|
||||||
present := s.PeekASN1Tag(tag)
|
|
||||||
if outPresent != nil {
|
|
||||||
*outPresent = present
|
|
||||||
}
|
|
||||||
if present && !s.ReadASN1(out, tag) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER
|
|
||||||
// explicitly tagged with tag into out and advances. If no element with a
|
|
||||||
// matching tag is present, it writes defaultValue into out instead. If out
|
|
||||||
// does not point to an integer or to a big.Int, it panics. It returns true on
|
|
||||||
// success and false on error.
|
|
||||||
func (s *String) ReadOptionalASN1Integer(out interface{}, tag Tag, defaultValue interface{}) bool {
|
|
||||||
if reflect.TypeOf(out).Kind() != reflect.Ptr {
|
|
||||||
panic("out is not a pointer")
|
|
||||||
}
|
|
||||||
var present bool
|
|
||||||
var i String
|
|
||||||
if !s.ReadOptionalASN1(&i, &present, tag) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !present {
|
|
||||||
switch reflect.ValueOf(out).Elem().Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
|
||||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
reflect.ValueOf(out).Elem().Set(reflect.ValueOf(defaultValue))
|
|
||||||
case reflect.Struct:
|
|
||||||
if reflect.TypeOf(out).Elem() != bigIntType {
|
|
||||||
panic("invalid integer type")
|
|
||||||
}
|
|
||||||
if reflect.TypeOf(defaultValue).Kind() != reflect.Ptr ||
|
|
||||||
reflect.TypeOf(defaultValue).Elem() != bigIntType {
|
|
||||||
panic("out points to big.Int, but defaultValue does not")
|
|
||||||
}
|
|
||||||
out.(*big.Int).Set(defaultValue.(*big.Int))
|
|
||||||
default:
|
|
||||||
panic("invalid integer type")
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if !i.ReadASN1Integer(out) || !i.Empty() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadOptionalASN1OctetString attempts to read an optional ASN.1 OCTET STRING
|
|
||||||
// explicitly tagged with tag into out and advances. If no element with a
|
|
||||||
// matching tag is present, it writes defaultValue into out instead. It returns
|
|
||||||
// true on success and false on error.
|
|
||||||
func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag Tag) bool {
|
|
||||||
var present bool
|
|
||||||
var child String
|
|
||||||
if !s.ReadOptionalASN1(&child, &present, tag) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if outPresent != nil {
|
|
||||||
*outPresent = present
|
|
||||||
}
|
|
||||||
if present {
|
|
||||||
var oct String
|
|
||||||
if !child.ReadASN1(&oct, asn1.TagOctetString) || !child.Empty() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*out = oct
|
|
||||||
} else {
|
|
||||||
*out = nil
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *String) readASN1(out *String, outTag *Tag, skipHeader bool) bool {
|
|
||||||
if len(*s) < 2 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
tag, lenByte := (*s)[0], (*s)[1]
|
|
||||||
|
|
||||||
if tag&0x1f == 0x1f {
|
|
||||||
// ITU-T X.690 section 8.1.2
|
|
||||||
//
|
|
||||||
// An identifier octet with a tag part of 0x1f indicates a high-tag-number
|
|
||||||
// form identifier with two or more octets. We only support tags less than
|
|
||||||
// 31 (i.e. low-tag-number form, single octet identifier).
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if outTag != nil {
|
|
||||||
*outTag = Tag(tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ITU-T X.690 section 8.1.3
|
|
||||||
//
|
|
||||||
// Bit 8 of the first length byte indicates whether the length is short- or
|
|
||||||
// long-form.
|
|
||||||
var length, headerLen uint32 // length includes headerLen
|
|
||||||
if lenByte&0x80 == 0 {
|
|
||||||
// Short-form length (section 8.1.3.4), encoded in bits 1-7.
|
|
||||||
length = uint32(lenByte) + 2
|
|
||||||
headerLen = 2
|
|
||||||
} else {
|
|
||||||
// Long-form length (section 8.1.3.5). Bits 1-7 encode the number of octets
|
|
||||||
// used to encode the length.
|
|
||||||
lenLen := lenByte & 0x7f
|
|
||||||
var len32 uint32
|
|
||||||
|
|
||||||
if lenLen == 0 || lenLen > 4 || len(*s) < int(2+lenLen) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
lenBytes := String((*s)[2 : 2+lenLen])
|
|
||||||
if !lenBytes.readUnsigned(&len32, int(lenLen)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
|
|
||||||
// with the minimum number of octets.
|
|
||||||
if len32 < 128 {
|
|
||||||
// Length should have used short-form encoding.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if len32>>((lenLen-1)*8) == 0 {
|
|
||||||
// Leading octet is 0. Length should have been at least one byte shorter.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
headerLen = 2 + uint32(lenLen)
|
|
||||||
if headerLen+len32 < len32 {
|
|
||||||
// Overflow.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
length = headerLen + len32
|
|
||||||
}
|
|
||||||
|
|
||||||
if uint32(int(length)) != length || !s.ReadBytes((*[]byte)(out), int(length)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if skipHeader && !out.Skip(int(headerLen)) {
|
|
||||||
panic("cryptobyte: internal error")
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
285
vendor/golang.org/x/crypto/cryptobyte/asn1_test.go
generated
vendored
285
vendor/golang.org/x/crypto/cryptobyte/asn1_test.go
generated
vendored
|
@ -1,285 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package cryptobyte
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/asn1"
|
|
||||||
"math/big"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type readASN1Test struct {
|
|
||||||
name string
|
|
||||||
in []byte
|
|
||||||
tag Tag
|
|
||||||
ok bool
|
|
||||||
out interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
var readASN1TestData = []readASN1Test{
|
|
||||||
{"valid", []byte{0x30, 2, 1, 2}, 0x30, true, []byte{1, 2}},
|
|
||||||
{"truncated", []byte{0x30, 3, 1, 2}, 0x30, false, nil},
|
|
||||||
{"zero length of length", []byte{0x30, 0x80}, 0x30, false, nil},
|
|
||||||
{"invalid long form length", []byte{0x30, 0x81, 1, 1}, 0x30, false, nil},
|
|
||||||
{"non-minimal length", append([]byte{0x30, 0x82, 0, 0x80}, make([]byte, 0x80)...), 0x30, false, nil},
|
|
||||||
{"invalid tag", []byte{0xa1, 3, 0x4, 1, 1}, 31, false, nil},
|
|
||||||
{"high tag", []byte{0x1f, 0x81, 0x80, 0x01, 2, 1, 2}, 0xff /* actually 0x4001, but tag is uint8 */, false, nil},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1(t *testing.T) {
|
|
||||||
for _, test := range readASN1TestData {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
var in, out String = test.in, nil
|
|
||||||
ok := in.ReadASN1(&out, test.tag)
|
|
||||||
if ok != test.ok || ok && !bytes.Equal(out, test.out.([]byte)) {
|
|
||||||
t.Errorf("in.ReadASN1() = %v, want %v; out = %v, want %v", ok, test.ok, out, test.out)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1Optional(t *testing.T) {
|
|
||||||
var empty String
|
|
||||||
var present bool
|
|
||||||
ok := empty.ReadOptionalASN1(nil, &present, 0xa0)
|
|
||||||
if !ok || present {
|
|
||||||
t.Errorf("empty.ReadOptionalASN1() = %v, want true; present = %v want false", ok, present)
|
|
||||||
}
|
|
||||||
|
|
||||||
var in, out String = []byte{0xa1, 3, 0x4, 1, 1}, nil
|
|
||||||
ok = in.ReadOptionalASN1(&out, &present, 0xa0)
|
|
||||||
if !ok || present {
|
|
||||||
t.Errorf("in.ReadOptionalASN1() = %v, want true, present = %v, want false", ok, present)
|
|
||||||
}
|
|
||||||
ok = in.ReadOptionalASN1(&out, &present, 0xa1)
|
|
||||||
wantBytes := []byte{4, 1, 1}
|
|
||||||
if !ok || !present || !bytes.Equal(out, wantBytes) {
|
|
||||||
t.Errorf("in.ReadOptionalASN1() = %v, want true; present = %v, want true; out = %v, want = %v", ok, present, out, wantBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var optionalOctetStringTestData = []struct {
|
|
||||||
readASN1Test
|
|
||||||
present bool
|
|
||||||
}{
|
|
||||||
{readASN1Test{"empty", []byte{}, 0xa0, true, []byte{}}, false},
|
|
||||||
{readASN1Test{"invalid", []byte{0xa1, 3, 0x4, 2, 1}, 0xa1, false, []byte{}}, true},
|
|
||||||
{readASN1Test{"missing", []byte{0xa1, 3, 0x4, 1, 1}, 0xa0, true, []byte{}}, false},
|
|
||||||
{readASN1Test{"present", []byte{0xa1, 3, 0x4, 1, 1}, 0xa1, true, []byte{1}}, true},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1OptionalOctetString(t *testing.T) {
|
|
||||||
for _, test := range optionalOctetStringTestData {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
in := String(test.in)
|
|
||||||
var out []byte
|
|
||||||
var present bool
|
|
||||||
ok := in.ReadOptionalASN1OctetString(&out, &present, test.tag)
|
|
||||||
if ok != test.ok || present != test.present || !bytes.Equal(out, test.out.([]byte)) {
|
|
||||||
t.Errorf("in.ReadOptionalASN1OctetString() = %v, want %v; present = %v want %v; out = %v, want %v", ok, test.ok, present, test.present, out, test.out)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultInt = -1
|
|
||||||
|
|
||||||
var optionalIntTestData = []readASN1Test{
|
|
||||||
{"empty", []byte{}, 0xa0, true, defaultInt},
|
|
||||||
{"invalid", []byte{0xa1, 3, 0x2, 2, 127}, 0xa1, false, 0},
|
|
||||||
{"missing", []byte{0xa1, 3, 0x2, 1, 127}, 0xa0, true, defaultInt},
|
|
||||||
{"present", []byte{0xa1, 3, 0x2, 1, 42}, 0xa1, true, 42},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1OptionalInteger(t *testing.T) {
|
|
||||||
for _, test := range optionalIntTestData {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
in := String(test.in)
|
|
||||||
var out int
|
|
||||||
ok := in.ReadOptionalASN1Integer(&out, test.tag, defaultInt)
|
|
||||||
if ok != test.ok || ok && out != test.out.(int) {
|
|
||||||
t.Errorf("in.ReadOptionalASN1Integer() = %v, want %v; out = %v, want %v", ok, test.ok, out, test.out)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1IntegerSigned(t *testing.T) {
|
|
||||||
testData64 := []struct {
|
|
||||||
in []byte
|
|
||||||
out int64
|
|
||||||
}{
|
|
||||||
{[]byte{2, 3, 128, 0, 0}, -0x800000},
|
|
||||||
{[]byte{2, 2, 255, 0}, -256},
|
|
||||||
{[]byte{2, 2, 255, 127}, -129},
|
|
||||||
{[]byte{2, 1, 128}, -128},
|
|
||||||
{[]byte{2, 1, 255}, -1},
|
|
||||||
{[]byte{2, 1, 0}, 0},
|
|
||||||
{[]byte{2, 1, 1}, 1},
|
|
||||||
{[]byte{2, 1, 2}, 2},
|
|
||||||
{[]byte{2, 1, 127}, 127},
|
|
||||||
{[]byte{2, 2, 0, 128}, 128},
|
|
||||||
{[]byte{2, 2, 1, 0}, 256},
|
|
||||||
{[]byte{2, 4, 0, 128, 0, 0}, 0x800000},
|
|
||||||
}
|
|
||||||
for i, test := range testData64 {
|
|
||||||
in := String(test.in)
|
|
||||||
var out int64
|
|
||||||
ok := in.ReadASN1Integer(&out)
|
|
||||||
if !ok || out != test.out {
|
|
||||||
t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %d, want %d", i, ok, out, test.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repeat the same cases, reading into a big.Int.
|
|
||||||
t.Run("big.Int", func(t *testing.T) {
|
|
||||||
for i, test := range testData64 {
|
|
||||||
in := String(test.in)
|
|
||||||
var out big.Int
|
|
||||||
ok := in.ReadASN1Integer(&out)
|
|
||||||
if !ok || out.Int64() != test.out {
|
|
||||||
t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %d, want %d", i, ok, out.Int64(), test.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1IntegerUnsigned(t *testing.T) {
|
|
||||||
testData := []struct {
|
|
||||||
in []byte
|
|
||||||
out uint64
|
|
||||||
}{
|
|
||||||
{[]byte{2, 1, 0}, 0},
|
|
||||||
{[]byte{2, 1, 1}, 1},
|
|
||||||
{[]byte{2, 1, 2}, 2},
|
|
||||||
{[]byte{2, 1, 127}, 127},
|
|
||||||
{[]byte{2, 2, 0, 128}, 128},
|
|
||||||
{[]byte{2, 2, 1, 0}, 256},
|
|
||||||
{[]byte{2, 4, 0, 128, 0, 0}, 0x800000},
|
|
||||||
{[]byte{2, 8, 127, 255, 255, 255, 255, 255, 255, 255}, 0x7fffffffffffffff},
|
|
||||||
{[]byte{2, 9, 0, 128, 0, 0, 0, 0, 0, 0, 0}, 0x8000000000000000},
|
|
||||||
{[]byte{2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255}, 0xffffffffffffffff},
|
|
||||||
}
|
|
||||||
for i, test := range testData {
|
|
||||||
in := String(test.in)
|
|
||||||
var out uint64
|
|
||||||
ok := in.ReadASN1Integer(&out)
|
|
||||||
if !ok || out != test.out {
|
|
||||||
t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %d, want %d", i, ok, out, test.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1IntegerInvalid(t *testing.T) {
|
|
||||||
testData := []String{
|
|
||||||
[]byte{3, 1, 0}, // invalid tag
|
|
||||||
// truncated
|
|
||||||
[]byte{2, 1},
|
|
||||||
[]byte{2, 2, 0},
|
|
||||||
// not minimally encoded
|
|
||||||
[]byte{2, 2, 0, 1},
|
|
||||||
[]byte{2, 2, 0xff, 0xff},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, test := range testData {
|
|
||||||
var out int64
|
|
||||||
if test.ReadASN1Integer(&out) {
|
|
||||||
t.Errorf("#%d: in.ReadASN1Integer() = true, want false (out = %d)", i, out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1ObjectIdentifier(t *testing.T) {
|
|
||||||
testData := []struct {
|
|
||||||
in []byte
|
|
||||||
ok bool
|
|
||||||
out []int
|
|
||||||
}{
|
|
||||||
{[]byte{}, false, []int{}},
|
|
||||||
{[]byte{6, 0}, false, []int{}},
|
|
||||||
{[]byte{5, 1, 85}, false, []int{2, 5}},
|
|
||||||
{[]byte{6, 1, 85}, true, []int{2, 5}},
|
|
||||||
{[]byte{6, 2, 85, 0x02}, true, []int{2, 5, 2}},
|
|
||||||
{[]byte{6, 4, 85, 0x02, 0xc0, 0x00}, true, []int{2, 5, 2, 0x2000}},
|
|
||||||
{[]byte{6, 3, 0x81, 0x34, 0x03}, true, []int{2, 100, 3}},
|
|
||||||
{[]byte{6, 7, 85, 0x02, 0xc0, 0x80, 0x80, 0x80, 0x80}, false, []int{}},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, test := range testData {
|
|
||||||
in := String(test.in)
|
|
||||||
var out asn1.ObjectIdentifier
|
|
||||||
ok := in.ReadASN1ObjectIdentifier(&out)
|
|
||||||
if ok != test.ok || ok && !out.Equal(test.out) {
|
|
||||||
t.Errorf("#%d: in.ReadASN1ObjectIdentifier() = %v, want %v; out = %v, want %v", i, ok, test.ok, out, test.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1GeneralizedTime(t *testing.T) {
|
|
||||||
testData := []struct {
|
|
||||||
in string
|
|
||||||
ok bool
|
|
||||||
out time.Time
|
|
||||||
}{
|
|
||||||
{"20100102030405Z", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.UTC)},
|
|
||||||
{"20100102030405", false, time.Time{}},
|
|
||||||
{"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
|
|
||||||
{"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
|
|
||||||
/* These are invalid times. However, the time package normalises times
|
|
||||||
* and they were accepted in some versions. See #11134. */
|
|
||||||
{"00000100000000Z", false, time.Time{}},
|
|
||||||
{"20101302030405Z", false, time.Time{}},
|
|
||||||
{"20100002030405Z", false, time.Time{}},
|
|
||||||
{"20100100030405Z", false, time.Time{}},
|
|
||||||
{"20100132030405Z", false, time.Time{}},
|
|
||||||
{"20100231030405Z", false, time.Time{}},
|
|
||||||
{"20100102240405Z", false, time.Time{}},
|
|
||||||
{"20100102036005Z", false, time.Time{}},
|
|
||||||
{"20100102030460Z", false, time.Time{}},
|
|
||||||
{"-20100102030410Z", false, time.Time{}},
|
|
||||||
{"2010-0102030410Z", false, time.Time{}},
|
|
||||||
{"2010-0002030410Z", false, time.Time{}},
|
|
||||||
{"201001-02030410Z", false, time.Time{}},
|
|
||||||
{"20100102-030410Z", false, time.Time{}},
|
|
||||||
{"2010010203-0410Z", false, time.Time{}},
|
|
||||||
{"201001020304-10Z", false, time.Time{}},
|
|
||||||
}
|
|
||||||
for i, test := range testData {
|
|
||||||
in := String(append([]byte{asn1.TagGeneralizedTime, byte(len(test.in))}, test.in...))
|
|
||||||
var out time.Time
|
|
||||||
ok := in.ReadASN1GeneralizedTime(&out)
|
|
||||||
if ok != test.ok || ok && !reflect.DeepEqual(out, test.out) {
|
|
||||||
t.Errorf("#%d: in.ReadASN1GeneralizedTime() = %v, want %v; out = %q, want %q", i, ok, test.ok, out, test.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadASN1BitString(t *testing.T) {
|
|
||||||
testData := []struct {
|
|
||||||
in []byte
|
|
||||||
ok bool
|
|
||||||
out asn1.BitString
|
|
||||||
}{
|
|
||||||
{[]byte{}, false, asn1.BitString{}},
|
|
||||||
{[]byte{0x00}, true, asn1.BitString{}},
|
|
||||||
{[]byte{0x07, 0x00}, true, asn1.BitString{Bytes: []byte{0}, BitLength: 1}},
|
|
||||||
{[]byte{0x07, 0x01}, false, asn1.BitString{}},
|
|
||||||
{[]byte{0x07, 0x40}, false, asn1.BitString{}},
|
|
||||||
{[]byte{0x08, 0x00}, false, asn1.BitString{}},
|
|
||||||
{[]byte{0xff}, false, asn1.BitString{}},
|
|
||||||
{[]byte{0xfe, 0x00}, false, asn1.BitString{}},
|
|
||||||
}
|
|
||||||
for i, test := range testData {
|
|
||||||
in := String(append([]byte{3, byte(len(test.in))}, test.in...))
|
|
||||||
var out asn1.BitString
|
|
||||||
ok := in.ReadASN1BitString(&out)
|
|
||||||
if ok != test.ok || ok && (!bytes.Equal(out.Bytes, test.out.Bytes) || out.BitLength != test.out.BitLength) {
|
|
||||||
t.Errorf("#%d: in.ReadASN1BitString() = %v, want %v; out = %v, want %v", i, ok, test.ok, out, test.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
255
vendor/golang.org/x/crypto/cryptobyte/builder.go
generated
vendored
255
vendor/golang.org/x/crypto/cryptobyte/builder.go
generated
vendored
|
@ -1,255 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package cryptobyte
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Builder builds byte strings from fixed-length and length-prefixed values.
|
|
||||||
// The zero value is a usable Builder that allocates space as needed.
|
|
||||||
type Builder struct {
|
|
||||||
err error
|
|
||||||
result []byte
|
|
||||||
fixedSize bool
|
|
||||||
child *Builder
|
|
||||||
offset int
|
|
||||||
pendingLenLen int
|
|
||||||
pendingIsASN1 bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBuilder creates a Builder that appends its output to the given buffer.
|
|
||||||
// Like append(), the slice will be reallocated if its capacity is exceeded.
|
|
||||||
// Use Bytes to get the final buffer.
|
|
||||||
func NewBuilder(buffer []byte) *Builder {
|
|
||||||
return &Builder{
|
|
||||||
result: buffer,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFixedBuilder creates a Builder that appends its output into the given
|
|
||||||
// buffer. This builder does not reallocate the output buffer. Writes that
|
|
||||||
// would exceed the buffer's capacity are treated as an error.
|
|
||||||
func NewFixedBuilder(buffer []byte) *Builder {
|
|
||||||
return &Builder{
|
|
||||||
result: buffer,
|
|
||||||
fixedSize: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns the bytes written by the builder or an error if one has
|
|
||||||
// occurred during during building.
|
|
||||||
func (b *Builder) Bytes() ([]byte, error) {
|
|
||||||
if b.err != nil {
|
|
||||||
return nil, b.err
|
|
||||||
}
|
|
||||||
return b.result[b.offset:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BytesOrPanic returns the bytes written by the builder or panics if an error
|
|
||||||
// has occurred during building.
|
|
||||||
func (b *Builder) BytesOrPanic() []byte {
|
|
||||||
if b.err != nil {
|
|
||||||
panic(b.err)
|
|
||||||
}
|
|
||||||
return b.result[b.offset:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddUint8 appends an 8-bit value to the byte string.
|
|
||||||
func (b *Builder) AddUint8(v uint8) {
|
|
||||||
b.add(byte(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddUint16 appends a big-endian, 16-bit value to the byte string.
|
|
||||||
func (b *Builder) AddUint16(v uint16) {
|
|
||||||
b.add(byte(v>>8), byte(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddUint24 appends a big-endian, 24-bit value to the byte string. The highest
|
|
||||||
// byte of the 32-bit input value is silently truncated.
|
|
||||||
func (b *Builder) AddUint24(v uint32) {
|
|
||||||
b.add(byte(v>>16), byte(v>>8), byte(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddUint32 appends a big-endian, 32-bit value to the byte string.
|
|
||||||
func (b *Builder) AddUint32(v uint32) {
|
|
||||||
b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddBytes appends a sequence of bytes to the byte string.
|
|
||||||
func (b *Builder) AddBytes(v []byte) {
|
|
||||||
b.add(v...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuilderContinuation is continuation-passing interface for building
|
|
||||||
// length-prefixed byte sequences. Builder methods for length-prefixed
|
|
||||||
// sequences (AddUint8LengthPrefixed etc.) will invoke the BuilderContinuation
|
|
||||||
// supplied to them. The child builder passed to the continuation can be used
|
|
||||||
// to build the content of the length-prefixed sequence. Example:
|
|
||||||
//
|
|
||||||
// parent := cryptobyte.NewBuilder()
|
|
||||||
// parent.AddUint8LengthPrefixed(func (child *Builder) {
|
|
||||||
// child.AddUint8(42)
|
|
||||||
// child.AddUint8LengthPrefixed(func (grandchild *Builder) {
|
|
||||||
// grandchild.AddUint8(5)
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// It is an error to write more bytes to the child than allowed by the reserved
|
|
||||||
// length prefix. After the continuation returns, the child must be considered
|
|
||||||
// invalid, i.e. users must not store any copies or references of the child
|
|
||||||
// that outlive the continuation.
|
|
||||||
type BuilderContinuation func(child *Builder)
|
|
||||||
|
|
||||||
// AddUint8LengthPrefixed adds a 8-bit length-prefixed byte sequence.
|
|
||||||
func (b *Builder) AddUint8LengthPrefixed(f BuilderContinuation) {
|
|
||||||
b.addLengthPrefixed(1, false, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddUint16LengthPrefixed adds a big-endian, 16-bit length-prefixed byte sequence.
|
|
||||||
func (b *Builder) AddUint16LengthPrefixed(f BuilderContinuation) {
|
|
||||||
b.addLengthPrefixed(2, false, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddUint24LengthPrefixed adds a big-endian, 24-bit length-prefixed byte sequence.
|
|
||||||
func (b *Builder) AddUint24LengthPrefixed(f BuilderContinuation) {
|
|
||||||
b.addLengthPrefixed(3, false, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuation) {
|
|
||||||
// Subsequent writes can be ignored if the builder has encountered an error.
|
|
||||||
if b.err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
offset := len(b.result)
|
|
||||||
b.add(make([]byte, lenLen)...)
|
|
||||||
|
|
||||||
b.child = &Builder{
|
|
||||||
result: b.result,
|
|
||||||
fixedSize: b.fixedSize,
|
|
||||||
offset: offset,
|
|
||||||
pendingLenLen: lenLen,
|
|
||||||
pendingIsASN1: isASN1,
|
|
||||||
}
|
|
||||||
|
|
||||||
f(b.child)
|
|
||||||
b.flushChild()
|
|
||||||
if b.child != nil {
|
|
||||||
panic("cryptobyte: internal error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Builder) flushChild() {
|
|
||||||
if b.child == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b.child.flushChild()
|
|
||||||
child := b.child
|
|
||||||
b.child = nil
|
|
||||||
|
|
||||||
if child.err != nil {
|
|
||||||
b.err = child.err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
length := len(child.result) - child.pendingLenLen - child.offset
|
|
||||||
|
|
||||||
if length < 0 {
|
|
||||||
panic("cryptobyte: internal error") // result unexpectedly shrunk
|
|
||||||
}
|
|
||||||
|
|
||||||
if child.pendingIsASN1 {
|
|
||||||
// For ASN.1, we reserved a single byte for the length. If that turned out
|
|
||||||
// to be incorrect, we have to move the contents along in order to make
|
|
||||||
// space.
|
|
||||||
if child.pendingLenLen != 1 {
|
|
||||||
panic("cryptobyte: internal error")
|
|
||||||
}
|
|
||||||
var lenLen, lenByte uint8
|
|
||||||
if int64(length) > 0xfffffffe {
|
|
||||||
b.err = errors.New("pending ASN.1 child too long")
|
|
||||||
return
|
|
||||||
} else if length > 0xffffff {
|
|
||||||
lenLen = 5
|
|
||||||
lenByte = 0x80 | 4
|
|
||||||
} else if length > 0xffff {
|
|
||||||
lenLen = 4
|
|
||||||
lenByte = 0x80 | 3
|
|
||||||
} else if length > 0xff {
|
|
||||||
lenLen = 3
|
|
||||||
lenByte = 0x80 | 2
|
|
||||||
} else if length > 0x7f {
|
|
||||||
lenLen = 2
|
|
||||||
lenByte = 0x80 | 1
|
|
||||||
} else {
|
|
||||||
lenLen = 1
|
|
||||||
lenByte = uint8(length)
|
|
||||||
length = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert the initial length byte, make space for successive length bytes,
|
|
||||||
// and adjust the offset.
|
|
||||||
child.result[child.offset] = lenByte
|
|
||||||
extraBytes := int(lenLen - 1)
|
|
||||||
if extraBytes != 0 {
|
|
||||||
child.add(make([]byte, extraBytes)...)
|
|
||||||
childStart := child.offset + child.pendingLenLen
|
|
||||||
copy(child.result[childStart+extraBytes:], child.result[childStart:])
|
|
||||||
}
|
|
||||||
child.offset++
|
|
||||||
child.pendingLenLen = extraBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
l := length
|
|
||||||
for i := child.pendingLenLen - 1; i >= 0; i-- {
|
|
||||||
child.result[child.offset+i] = uint8(l)
|
|
||||||
l >>= 8
|
|
||||||
}
|
|
||||||
if l != 0 {
|
|
||||||
b.err = fmt.Errorf("cryptobyte: pending child length %d exceeds %d-byte length prefix", length, child.pendingLenLen)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !b.fixedSize {
|
|
||||||
b.result = child.result // In case child reallocated result.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Builder) add(bytes ...byte) {
|
|
||||||
if b.err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if b.child != nil {
|
|
||||||
panic("attempted write while child is pending")
|
|
||||||
}
|
|
||||||
if len(b.result)+len(bytes) < len(bytes) {
|
|
||||||
b.err = errors.New("cryptobyte: length overflow")
|
|
||||||
}
|
|
||||||
if b.fixedSize && len(b.result)+len(bytes) > cap(b.result) {
|
|
||||||
b.err = errors.New("cryptobyte: Builder is exceeding its fixed-size buffer")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b.result = append(b.result, bytes...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A MarshalingValue marshals itself into a Builder.
|
|
||||||
type MarshalingValue interface {
|
|
||||||
// Marshal is called by Builder.AddValue. It receives a pointer to a builder
|
|
||||||
// to marshal itself into. It may return an error that occurred during
|
|
||||||
// marshaling, such as unset or invalid values.
|
|
||||||
Marshal(b *Builder) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddValue calls Marshal on v, passing a pointer to the builder to append to.
|
|
||||||
// If Marshal returns an error, it is set on the Builder so that subsequent
|
|
||||||
// appends don't have an effect.
|
|
||||||
func (b *Builder) AddValue(v MarshalingValue) {
|
|
||||||
err := v.Marshal(b)
|
|
||||||
if err != nil {
|
|
||||||
b.err = err
|
|
||||||
}
|
|
||||||
}
|
|
379
vendor/golang.org/x/crypto/cryptobyte/cryptobyte_test.go
generated
vendored
379
vendor/golang.org/x/crypto/cryptobyte/cryptobyte_test.go
generated
vendored
|
@ -1,379 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package cryptobyte
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func builderBytesEq(b *Builder, want ...byte) error {
|
|
||||||
got := b.BytesOrPanic()
|
|
||||||
if !bytes.Equal(got, want) {
|
|
||||||
return fmt.Errorf("Bytes() = %v, want %v", got, want)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBytes(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
v := []byte("foobarbaz")
|
|
||||||
b.AddBytes(v[0:3])
|
|
||||||
b.AddBytes(v[3:4])
|
|
||||||
b.AddBytes(v[4:9])
|
|
||||||
if err := builderBytesEq(&b, v...); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
s := String(b.BytesOrPanic())
|
|
||||||
for _, w := range []string{"foo", "bar", "baz"} {
|
|
||||||
var got []byte
|
|
||||||
if !s.ReadBytes(&got, 3) {
|
|
||||||
t.Errorf("ReadBytes() = false, want true (w = %v)", w)
|
|
||||||
}
|
|
||||||
want := []byte(w)
|
|
||||||
if !bytes.Equal(got, want) {
|
|
||||||
t.Errorf("ReadBytes(): got = %v, want %v", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(s) != 0 {
|
|
||||||
t.Errorf("len(s) = %d, want 0", len(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUint8(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint8(42)
|
|
||||||
if err := builderBytesEq(&b, 42); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var s String = b.BytesOrPanic()
|
|
||||||
var v uint8
|
|
||||||
if !s.ReadUint8(&v) {
|
|
||||||
t.Error("ReadUint8() = false, want true")
|
|
||||||
}
|
|
||||||
if v != 42 {
|
|
||||||
t.Errorf("v = %d, want 42", v)
|
|
||||||
}
|
|
||||||
if len(s) != 0 {
|
|
||||||
t.Errorf("len(s) = %d, want 0", len(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUint16(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint16(65534)
|
|
||||||
if err := builderBytesEq(&b, 255, 254); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
var s String = b.BytesOrPanic()
|
|
||||||
var v uint16
|
|
||||||
if !s.ReadUint16(&v) {
|
|
||||||
t.Error("ReadUint16() == false, want true")
|
|
||||||
}
|
|
||||||
if v != 65534 {
|
|
||||||
t.Errorf("v = %d, want 65534", v)
|
|
||||||
}
|
|
||||||
if len(s) != 0 {
|
|
||||||
t.Errorf("len(s) = %d, want 0", len(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUint24(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint24(0xfffefd)
|
|
||||||
if err := builderBytesEq(&b, 255, 254, 253); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var s String = b.BytesOrPanic()
|
|
||||||
var v uint32
|
|
||||||
if !s.ReadUint24(&v) {
|
|
||||||
t.Error("ReadUint8() = false, want true")
|
|
||||||
}
|
|
||||||
if v != 0xfffefd {
|
|
||||||
t.Errorf("v = %d, want fffefd", v)
|
|
||||||
}
|
|
||||||
if len(s) != 0 {
|
|
||||||
t.Errorf("len(s) = %d, want 0", len(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUint24Truncation(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint24(0x10111213)
|
|
||||||
if err := builderBytesEq(&b, 0x11, 0x12, 0x13); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUint32(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint32(0xfffefdfc)
|
|
||||||
if err := builderBytesEq(&b, 255, 254, 253, 252); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var s String = b.BytesOrPanic()
|
|
||||||
var v uint32
|
|
||||||
if !s.ReadUint32(&v) {
|
|
||||||
t.Error("ReadUint8() = false, want true")
|
|
||||||
}
|
|
||||||
if v != 0xfffefdfc {
|
|
||||||
t.Errorf("v = %x, want fffefdfc", v)
|
|
||||||
}
|
|
||||||
if len(s) != 0 {
|
|
||||||
t.Errorf("len(s) = %d, want 0", len(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUMultiple(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint8(23)
|
|
||||||
b.AddUint32(0xfffefdfc)
|
|
||||||
b.AddUint16(42)
|
|
||||||
if err := builderBytesEq(&b, 23, 255, 254, 253, 252, 0, 42); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var s String = b.BytesOrPanic()
|
|
||||||
var (
|
|
||||||
x uint8
|
|
||||||
y uint32
|
|
||||||
z uint16
|
|
||||||
)
|
|
||||||
if !s.ReadUint8(&x) || !s.ReadUint32(&y) || !s.ReadUint16(&z) {
|
|
||||||
t.Error("ReadUint8() = false, want true")
|
|
||||||
}
|
|
||||||
if x != 23 || y != 0xfffefdfc || z != 42 {
|
|
||||||
t.Errorf("x, y, z = %d, %d, %d; want 23, 4294901244, 5", x, y, z)
|
|
||||||
}
|
|
||||||
if len(s) != 0 {
|
|
||||||
t.Errorf("len(s) = %d, want 0", len(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUint8LengthPrefixedSimple(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint8LengthPrefixed(func(c *Builder) {
|
|
||||||
c.AddUint8(23)
|
|
||||||
c.AddUint8(42)
|
|
||||||
})
|
|
||||||
if err := builderBytesEq(&b, 2, 23, 42); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var base, child String = b.BytesOrPanic(), nil
|
|
||||||
var x, y uint8
|
|
||||||
if !base.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) ||
|
|
||||||
!child.ReadUint8(&y) {
|
|
||||||
t.Error("parsing failed")
|
|
||||||
}
|
|
||||||
if x != 23 || y != 42 {
|
|
||||||
t.Errorf("want x, y == 23, 42; got %d, %d", x, y)
|
|
||||||
}
|
|
||||||
if len(base) != 0 {
|
|
||||||
t.Errorf("len(base) = %d, want 0", len(base))
|
|
||||||
}
|
|
||||||
if len(child) != 0 {
|
|
||||||
t.Errorf("len(child) = %d, want 0", len(child))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUint8LengthPrefixedMulti(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint8LengthPrefixed(func(c *Builder) {
|
|
||||||
c.AddUint8(23)
|
|
||||||
c.AddUint8(42)
|
|
||||||
})
|
|
||||||
b.AddUint8(5)
|
|
||||||
b.AddUint8LengthPrefixed(func(c *Builder) {
|
|
||||||
c.AddUint8(123)
|
|
||||||
c.AddUint8(234)
|
|
||||||
})
|
|
||||||
if err := builderBytesEq(&b, 2, 23, 42, 5, 2, 123, 234); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var s, child String = b.BytesOrPanic(), nil
|
|
||||||
var u, v, w, x, y uint8
|
|
||||||
if !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&u) || !child.ReadUint8(&v) ||
|
|
||||||
!s.ReadUint8(&w) || !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) || !child.ReadUint8(&y) {
|
|
||||||
t.Error("parsing failed")
|
|
||||||
}
|
|
||||||
if u != 23 || v != 42 || w != 5 || x != 123 || y != 234 {
|
|
||||||
t.Errorf("u, v, w, x, y = %d, %d, %d, %d, %d; want 23, 42, 5, 123, 234",
|
|
||||||
u, v, w, x, y)
|
|
||||||
}
|
|
||||||
if len(s) != 0 {
|
|
||||||
t.Errorf("len(s) = %d, want 0", len(s))
|
|
||||||
}
|
|
||||||
if len(child) != 0 {
|
|
||||||
t.Errorf("len(child) = %d, want 0", len(child))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUint8LengthPrefixedNested(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint8LengthPrefixed(func(c *Builder) {
|
|
||||||
c.AddUint8(5)
|
|
||||||
c.AddUint8LengthPrefixed(func(d *Builder) {
|
|
||||||
d.AddUint8(23)
|
|
||||||
d.AddUint8(42)
|
|
||||||
})
|
|
||||||
c.AddUint8(123)
|
|
||||||
})
|
|
||||||
if err := builderBytesEq(&b, 5, 5, 2, 23, 42, 123); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var base, child1, child2 String = b.BytesOrPanic(), nil, nil
|
|
||||||
var u, v, w, x uint8
|
|
||||||
if !base.ReadUint8LengthPrefixed(&child1) {
|
|
||||||
t.Error("parsing base failed")
|
|
||||||
}
|
|
||||||
if !child1.ReadUint8(&u) || !child1.ReadUint8LengthPrefixed(&child2) || !child1.ReadUint8(&x) {
|
|
||||||
t.Error("parsing child1 failed")
|
|
||||||
}
|
|
||||||
if !child2.ReadUint8(&v) || !child2.ReadUint8(&w) {
|
|
||||||
t.Error("parsing child2 failed")
|
|
||||||
}
|
|
||||||
if u != 5 || v != 23 || w != 42 || x != 123 {
|
|
||||||
t.Errorf("u, v, w, x = %d, %d, %d, %d, want 5, 23, 42, 123",
|
|
||||||
u, v, w, x)
|
|
||||||
}
|
|
||||||
if len(base) != 0 {
|
|
||||||
t.Errorf("len(base) = %d, want 0", len(base))
|
|
||||||
}
|
|
||||||
if len(child1) != 0 {
|
|
||||||
t.Errorf("len(child1) = %d, want 0", len(child1))
|
|
||||||
}
|
|
||||||
if len(base) != 0 {
|
|
||||||
t.Errorf("len(child2) = %d, want 0", len(child2))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPreallocatedBuffer(t *testing.T) {
|
|
||||||
var buf [5]byte
|
|
||||||
b := NewBuilder(buf[0:0])
|
|
||||||
b.AddUint8(1)
|
|
||||||
b.AddUint8LengthPrefixed(func(c *Builder) {
|
|
||||||
c.AddUint8(3)
|
|
||||||
c.AddUint8(4)
|
|
||||||
})
|
|
||||||
b.AddUint16(1286) // Outgrow buf by one byte.
|
|
||||||
want := []byte{1, 2, 3, 4, 0}
|
|
||||||
if !bytes.Equal(buf[:], want) {
|
|
||||||
t.Errorf("buf = %v want %v", buf, want)
|
|
||||||
}
|
|
||||||
if err := builderBytesEq(b, 1, 2, 3, 4, 5, 6); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWriteWithPendingChild(t *testing.T) {
|
|
||||||
var b Builder
|
|
||||||
b.AddUint8LengthPrefixed(func(c *Builder) {
|
|
||||||
c.AddUint8LengthPrefixed(func(d *Builder) {
|
|
||||||
defer func() {
|
|
||||||
if recover() == nil {
|
|
||||||
t.Errorf("recover() = nil, want error; c.AddUint8() did not panic")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
c.AddUint8(2) // panics
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if recover() == nil {
|
|
||||||
t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
b.AddUint8(2) // panics
|
|
||||||
})
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if recover() == nil {
|
|
||||||
t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
b.AddUint8(2) // panics
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ASN.1
|
|
||||||
|
|
||||||
func TestASN1Int64(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
in int64
|
|
||||||
want []byte
|
|
||||||
}{
|
|
||||||
{-0x800000, []byte{2, 3, 128, 0, 0}},
|
|
||||||
{-256, []byte{2, 2, 255, 0}},
|
|
||||||
{-129, []byte{2, 2, 255, 127}},
|
|
||||||
{-128, []byte{2, 1, 128}},
|
|
||||||
{-1, []byte{2, 1, 255}},
|
|
||||||
{0, []byte{2, 1, 0}},
|
|
||||||
{1, []byte{2, 1, 1}},
|
|
||||||
{2, []byte{2, 1, 2}},
|
|
||||||
{127, []byte{2, 1, 127}},
|
|
||||||
{128, []byte{2, 2, 0, 128}},
|
|
||||||
{256, []byte{2, 2, 1, 0}},
|
|
||||||
{0x800000, []byte{2, 4, 0, 128, 0, 0}},
|
|
||||||
}
|
|
||||||
for i, tt := range tests {
|
|
||||||
var b Builder
|
|
||||||
b.AddASN1Int64(tt.in)
|
|
||||||
if err := builderBytesEq(&b, tt.want...); err != nil {
|
|
||||||
t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
|
|
||||||
}
|
|
||||||
|
|
||||||
var n int64
|
|
||||||
s := String(b.BytesOrPanic())
|
|
||||||
ok := s.ReadASN1Integer(&n)
|
|
||||||
if !ok || n != tt.in {
|
|
||||||
t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
|
|
||||||
ok, n, tt.in, i)
|
|
||||||
}
|
|
||||||
if len(s) != 0 {
|
|
||||||
t.Errorf("len(s) = %d, want 0", len(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestASN1Uint64(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
in uint64
|
|
||||||
want []byte
|
|
||||||
}{
|
|
||||||
{0, []byte{2, 1, 0}},
|
|
||||||
{1, []byte{2, 1, 1}},
|
|
||||||
{2, []byte{2, 1, 2}},
|
|
||||||
{127, []byte{2, 1, 127}},
|
|
||||||
{128, []byte{2, 2, 0, 128}},
|
|
||||||
{256, []byte{2, 2, 1, 0}},
|
|
||||||
{0x800000, []byte{2, 4, 0, 128, 0, 0}},
|
|
||||||
{0x7fffffffffffffff, []byte{2, 8, 127, 255, 255, 255, 255, 255, 255, 255}},
|
|
||||||
{0x8000000000000000, []byte{2, 9, 0, 128, 0, 0, 0, 0, 0, 0, 0}},
|
|
||||||
{0xffffffffffffffff, []byte{2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255}},
|
|
||||||
}
|
|
||||||
for i, tt := range tests {
|
|
||||||
var b Builder
|
|
||||||
b.AddASN1Uint64(tt.in)
|
|
||||||
if err := builderBytesEq(&b, tt.want...); err != nil {
|
|
||||||
t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
|
|
||||||
}
|
|
||||||
|
|
||||||
var n uint64
|
|
||||||
s := String(b.BytesOrPanic())
|
|
||||||
ok := s.ReadASN1Integer(&n)
|
|
||||||
if !ok || n != tt.in {
|
|
||||||
t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
|
|
||||||
ok, n, tt.in, i)
|
|
||||||
}
|
|
||||||
if len(s) != 0 {
|
|
||||||
t.Errorf("len(s) = %d, want 0", len(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
120
vendor/golang.org/x/crypto/cryptobyte/example_test.go
generated
vendored
120
vendor/golang.org/x/crypto/cryptobyte/example_test.go
generated
vendored
|
@ -1,120 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package cryptobyte_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/asn1"
|
|
||||||
"fmt"
|
|
||||||
"golang.org/x/crypto/cryptobyte"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleString_lengthPrefixed() {
|
|
||||||
// This is an example of parsing length-prefixed data (as found in, for
|
|
||||||
// example, TLS). Imagine a 16-bit prefixed series of 8-bit prefixed
|
|
||||||
// strings.
|
|
||||||
|
|
||||||
input := cryptobyte.String([]byte{0, 12, 5, 'h', 'e', 'l', 'l', 'o', 5, 'w', 'o', 'r', 'l', 'd'})
|
|
||||||
var result []string
|
|
||||||
|
|
||||||
var values cryptobyte.String
|
|
||||||
if !input.ReadUint16LengthPrefixed(&values) ||
|
|
||||||
!input.Empty() {
|
|
||||||
panic("bad format")
|
|
||||||
}
|
|
||||||
|
|
||||||
for !values.Empty() {
|
|
||||||
var value cryptobyte.String
|
|
||||||
if !values.ReadUint8LengthPrefixed(&value) {
|
|
||||||
panic("bad format")
|
|
||||||
}
|
|
||||||
|
|
||||||
result = append(result, string(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output: []string{"hello", "world"}
|
|
||||||
fmt.Printf("%#v\n", result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleString_asn1() {
|
|
||||||
// This is an example of parsing ASN.1 data that looks like:
|
|
||||||
// Foo ::= SEQUENCE {
|
|
||||||
// version [6] INTEGER DEFAULT 0
|
|
||||||
// data OCTET STRING
|
|
||||||
// }
|
|
||||||
|
|
||||||
input := cryptobyte.String([]byte{0x30, 12, 0xa6, 3, 2, 1, 2, 4, 5, 'h', 'e', 'l', 'l', 'o'})
|
|
||||||
|
|
||||||
var (
|
|
||||||
version int64
|
|
||||||
data, inner, versionBytes cryptobyte.String
|
|
||||||
haveVersion bool
|
|
||||||
)
|
|
||||||
if !input.ReadASN1(&inner, cryptobyte.Tag(asn1.TagSequence).Constructed()) ||
|
|
||||||
!input.Empty() ||
|
|
||||||
!inner.ReadOptionalASN1(&versionBytes, &haveVersion, cryptobyte.Tag(6).Constructed().ContextSpecific()) ||
|
|
||||||
(haveVersion && !versionBytes.ReadASN1Integer(&version)) ||
|
|
||||||
(haveVersion && !versionBytes.Empty()) ||
|
|
||||||
!inner.ReadASN1(&data, asn1.TagOctetString) ||
|
|
||||||
!inner.Empty() {
|
|
||||||
panic("bad format")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output: haveVersion: true, version: 2, data: hello
|
|
||||||
fmt.Printf("haveVersion: %t, version: %d, data: %s\n", haveVersion, version, string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleBuilder_asn1() {
|
|
||||||
// This is an example of building ASN.1 data that looks like:
|
|
||||||
// Foo ::= SEQUENCE {
|
|
||||||
// version [6] INTEGER DEFAULT 0
|
|
||||||
// data OCTET STRING
|
|
||||||
// }
|
|
||||||
|
|
||||||
version := int64(2)
|
|
||||||
data := []byte("hello")
|
|
||||||
const defaultVersion = 0
|
|
||||||
|
|
||||||
var b cryptobyte.Builder
|
|
||||||
b.AddASN1(cryptobyte.Tag(asn1.TagSequence).Constructed(), func(b *cryptobyte.Builder) {
|
|
||||||
if version != defaultVersion {
|
|
||||||
b.AddASN1(cryptobyte.Tag(6).Constructed().ContextSpecific(), func(b *cryptobyte.Builder) {
|
|
||||||
b.AddASN1Int64(version)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
b.AddASN1OctetString(data)
|
|
||||||
})
|
|
||||||
|
|
||||||
result, err := b.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output: 300ca603020102040568656c6c6f
|
|
||||||
fmt.Printf("%x\n", result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleBuilder_lengthPrefixed() {
|
|
||||||
// This is an example of building length-prefixed data (as found in,
|
|
||||||
// for example, TLS). Imagine a 16-bit prefixed series of 8-bit
|
|
||||||
// prefixed strings.
|
|
||||||
input := []string{"hello", "world"}
|
|
||||||
|
|
||||||
var b cryptobyte.Builder
|
|
||||||
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
|
|
||||||
for _, value := range input {
|
|
||||||
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
|
|
||||||
b.AddBytes([]byte(value))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
result, err := b.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output: 000c0568656c6c6f05776f726c64
|
|
||||||
fmt.Printf("%x\n", result)
|
|
||||||
}
|
|
157
vendor/golang.org/x/crypto/cryptobyte/string.go
generated
vendored
157
vendor/golang.org/x/crypto/cryptobyte/string.go
generated
vendored
|
@ -1,157 +0,0 @@
|
||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package cryptobyte implements building and parsing of byte strings for
|
|
||||||
// DER-encoded ASN.1 and TLS messages. See the examples for the Builder and
|
|
||||||
// String types to get started.
|
|
||||||
package cryptobyte // import "golang.org/x/crypto/cryptobyte"
|
|
||||||
|
|
||||||
// String represents a string of bytes. It provides methods for parsing
|
|
||||||
// fixed-length and length-prefixed values from it.
|
|
||||||
type String []byte
|
|
||||||
|
|
||||||
// read advances a String by n bytes and returns them. If less than n bytes
|
|
||||||
// remain, it returns nil.
|
|
||||||
func (s *String) read(n int) []byte {
|
|
||||||
if len(*s) < n {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
v := (*s)[:n]
|
|
||||||
*s = (*s)[n:]
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip advances the String by n byte and reports whether it was successful.
|
|
||||||
func (s *String) Skip(n int) bool {
|
|
||||||
return s.read(n) != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadUint8 decodes an 8-bit value into out and advances over it. It
|
|
||||||
// returns true on success and false on error.
|
|
||||||
func (s *String) ReadUint8(out *uint8) bool {
|
|
||||||
v := s.read(1)
|
|
||||||
if v == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*out = uint8(v[0])
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadUint16 decodes a big-endian, 16-bit value into out and advances over it.
|
|
||||||
// It returns true on success and false on error.
|
|
||||||
func (s *String) ReadUint16(out *uint16) bool {
|
|
||||||
v := s.read(2)
|
|
||||||
if v == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*out = uint16(v[0])<<8 | uint16(v[1])
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadUint24 decodes a big-endian, 24-bit value into out and advances over it.
|
|
||||||
// It returns true on success and false on error.
|
|
||||||
func (s *String) ReadUint24(out *uint32) bool {
|
|
||||||
v := s.read(3)
|
|
||||||
if v == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*out = uint32(v[0])<<16 | uint32(v[1])<<8 | uint32(v[2])
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadUint32 decodes a big-endian, 32-bit value into out and advances over it.
|
|
||||||
// It returns true on success and false on error.
|
|
||||||
func (s *String) ReadUint32(out *uint32) bool {
|
|
||||||
v := s.read(4)
|
|
||||||
if v == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*out = uint32(v[0])<<24 | uint32(v[1])<<16 | uint32(v[2])<<8 | uint32(v[3])
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *String) readUnsigned(out *uint32, length int) bool {
|
|
||||||
v := s.read(length)
|
|
||||||
if v == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
var result uint32
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
result <<= 8
|
|
||||||
result |= uint32(v[i])
|
|
||||||
}
|
|
||||||
*out = result
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool {
|
|
||||||
lenBytes := s.read(lenLen)
|
|
||||||
if lenBytes == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
var length uint32
|
|
||||||
for _, b := range lenBytes {
|
|
||||||
length = length << 8
|
|
||||||
length = length | uint32(b)
|
|
||||||
}
|
|
||||||
if int(length) < 0 {
|
|
||||||
// This currently cannot overflow because we read uint24 at most, but check
|
|
||||||
// anyway in case that changes in the future.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
v := s.read(int(length))
|
|
||||||
if v == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*outChild = v
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadUint8LengthPrefixed reads the content of an 8-bit length-prefixed value
|
|
||||||
// into out and advances over it. It returns true on success and false on
|
|
||||||
// error.
|
|
||||||
func (s *String) ReadUint8LengthPrefixed(out *String) bool {
|
|
||||||
return s.readLengthPrefixed(1, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadUint16LengthPrefixed reads the content of a big-endian, 16-bit
|
|
||||||
// length-prefixed value into out and advances over it. It returns true on
|
|
||||||
// success and false on error.
|
|
||||||
func (s *String) ReadUint16LengthPrefixed(out *String) bool {
|
|
||||||
return s.readLengthPrefixed(2, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadUint24LengthPrefixed reads the content of a big-endian, 24-bit
|
|
||||||
// length-prefixed value into out and advances over it. It returns true on
|
|
||||||
// success and false on error.
|
|
||||||
func (s *String) ReadUint24LengthPrefixed(out *String) bool {
|
|
||||||
return s.readLengthPrefixed(3, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadBytes reads n bytes into out and advances over them. It returns true on
|
|
||||||
// success and false and error.
|
|
||||||
func (s *String) ReadBytes(out *[]byte, n int) bool {
|
|
||||||
v := s.read(n)
|
|
||||||
if v == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*out = v
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyBytes copies len(out) bytes into out and advances over them. It returns
|
|
||||||
// true on success and false on error.
|
|
||||||
func (s *String) CopyBytes(out []byte) bool {
|
|
||||||
n := len(out)
|
|
||||||
v := s.read(n)
|
|
||||||
if v == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return copy(out, v) == n
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty reports whether the string does not contain any bytes.
|
|
||||||
func (s String) Empty() bool {
|
|
||||||
return len(s) == 0
|
|
||||||
}
|
|
8
vendor/golang.org/x/crypto/curve25519/const_amd64.h
generated
vendored
8
vendor/golang.org/x/crypto/curve25519/const_amd64.h
generated
vendored
|
@ -1,8 +0,0 @@
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// This code was translated into a form compatible with 6a from the public
|
|
||||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
|
||||||
|
|
||||||
#define REDMASK51 0x0007FFFFFFFFFFFF
|
|
6
vendor/golang.org/x/crypto/curve25519/const_amd64.s
generated
vendored
6
vendor/golang.org/x/crypto/curve25519/const_amd64.s
generated
vendored
|
@ -5,10 +5,10 @@
|
||||||
// This code was translated into a form compatible with 6a from the public
|
// This code was translated into a form compatible with 6a from the public
|
||||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
// +build amd64,!gccgo
|
||||||
|
|
||||||
// These constants cannot be encoded in non-MOVQ immediates.
|
DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF
|
||||||
// We access them directly from memory instead.
|
GLOBL ·REDMASK51(SB), 8, $8
|
||||||
|
|
||||||
DATA ·_121666_213(SB)/8, $996687872
|
DATA ·_121666_213(SB)/8, $996687872
|
||||||
GLOBL ·_121666_213(SB), 8, $8
|
GLOBL ·_121666_213(SB), 8, $8
|
||||||
|
|
133
vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
generated
vendored
133
vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
generated
vendored
|
@ -2,64 +2,87 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
// This code was translated into a form compatible with 6a from the public
|
||||||
|
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
// func cswap(inout *[4][5]uint64, v uint64)
|
// +build amd64,!gccgo
|
||||||
|
|
||||||
|
// func cswap(inout *[5]uint64, v uint64)
|
||||||
TEXT ·cswap(SB),7,$0
|
TEXT ·cswap(SB),7,$0
|
||||||
MOVQ inout+0(FP),DI
|
MOVQ inout+0(FP),DI
|
||||||
MOVQ v+8(FP),SI
|
MOVQ v+8(FP),SI
|
||||||
|
|
||||||
SUBQ $1, SI
|
CMPQ SI,$1
|
||||||
NOTQ SI
|
MOVQ 0(DI),SI
|
||||||
MOVQ SI, X15
|
MOVQ 80(DI),DX
|
||||||
PSHUFD $0x44, X15, X15
|
MOVQ 8(DI),CX
|
||||||
|
MOVQ 88(DI),R8
|
||||||
MOVOU 0(DI), X0
|
MOVQ SI,R9
|
||||||
MOVOU 16(DI), X2
|
CMOVQEQ DX,SI
|
||||||
MOVOU 32(DI), X4
|
CMOVQEQ R9,DX
|
||||||
MOVOU 48(DI), X6
|
MOVQ CX,R9
|
||||||
MOVOU 64(DI), X8
|
CMOVQEQ R8,CX
|
||||||
MOVOU 80(DI), X1
|
CMOVQEQ R9,R8
|
||||||
MOVOU 96(DI), X3
|
MOVQ SI,0(DI)
|
||||||
MOVOU 112(DI), X5
|
MOVQ DX,80(DI)
|
||||||
MOVOU 128(DI), X7
|
MOVQ CX,8(DI)
|
||||||
MOVOU 144(DI), X9
|
MOVQ R8,88(DI)
|
||||||
|
MOVQ 16(DI),SI
|
||||||
MOVO X1, X10
|
MOVQ 96(DI),DX
|
||||||
MOVO X3, X11
|
MOVQ 24(DI),CX
|
||||||
MOVO X5, X12
|
MOVQ 104(DI),R8
|
||||||
MOVO X7, X13
|
MOVQ SI,R9
|
||||||
MOVO X9, X14
|
CMOVQEQ DX,SI
|
||||||
|
CMOVQEQ R9,DX
|
||||||
PXOR X0, X10
|
MOVQ CX,R9
|
||||||
PXOR X2, X11
|
CMOVQEQ R8,CX
|
||||||
PXOR X4, X12
|
CMOVQEQ R9,R8
|
||||||
PXOR X6, X13
|
MOVQ SI,16(DI)
|
||||||
PXOR X8, X14
|
MOVQ DX,96(DI)
|
||||||
PAND X15, X10
|
MOVQ CX,24(DI)
|
||||||
PAND X15, X11
|
MOVQ R8,104(DI)
|
||||||
PAND X15, X12
|
MOVQ 32(DI),SI
|
||||||
PAND X15, X13
|
MOVQ 112(DI),DX
|
||||||
PAND X15, X14
|
MOVQ 40(DI),CX
|
||||||
PXOR X10, X0
|
MOVQ 120(DI),R8
|
||||||
PXOR X10, X1
|
MOVQ SI,R9
|
||||||
PXOR X11, X2
|
CMOVQEQ DX,SI
|
||||||
PXOR X11, X3
|
CMOVQEQ R9,DX
|
||||||
PXOR X12, X4
|
MOVQ CX,R9
|
||||||
PXOR X12, X5
|
CMOVQEQ R8,CX
|
||||||
PXOR X13, X6
|
CMOVQEQ R9,R8
|
||||||
PXOR X13, X7
|
MOVQ SI,32(DI)
|
||||||
PXOR X14, X8
|
MOVQ DX,112(DI)
|
||||||
PXOR X14, X9
|
MOVQ CX,40(DI)
|
||||||
|
MOVQ R8,120(DI)
|
||||||
MOVOU X0, 0(DI)
|
MOVQ 48(DI),SI
|
||||||
MOVOU X2, 16(DI)
|
MOVQ 128(DI),DX
|
||||||
MOVOU X4, 32(DI)
|
MOVQ 56(DI),CX
|
||||||
MOVOU X6, 48(DI)
|
MOVQ 136(DI),R8
|
||||||
MOVOU X8, 64(DI)
|
MOVQ SI,R9
|
||||||
MOVOU X1, 80(DI)
|
CMOVQEQ DX,SI
|
||||||
MOVOU X3, 96(DI)
|
CMOVQEQ R9,DX
|
||||||
MOVOU X5, 112(DI)
|
MOVQ CX,R9
|
||||||
MOVOU X7, 128(DI)
|
CMOVQEQ R8,CX
|
||||||
MOVOU X9, 144(DI)
|
CMOVQEQ R9,R8
|
||||||
|
MOVQ SI,48(DI)
|
||||||
|
MOVQ DX,128(DI)
|
||||||
|
MOVQ CX,56(DI)
|
||||||
|
MOVQ R8,136(DI)
|
||||||
|
MOVQ 64(DI),SI
|
||||||
|
MOVQ 144(DI),DX
|
||||||
|
MOVQ 72(DI),CX
|
||||||
|
MOVQ 152(DI),R8
|
||||||
|
MOVQ SI,R9
|
||||||
|
CMOVQEQ DX,SI
|
||||||
|
CMOVQEQ R9,DX
|
||||||
|
MOVQ CX,R9
|
||||||
|
CMOVQEQ R8,CX
|
||||||
|
CMOVQEQ R9,R8
|
||||||
|
MOVQ SI,64(DI)
|
||||||
|
MOVQ DX,144(DI)
|
||||||
|
MOVQ CX,72(DI)
|
||||||
|
MOVQ R8,152(DI)
|
||||||
|
MOVQ DI,AX
|
||||||
|
MOVQ SI,DX
|
||||||
RET
|
RET
|
||||||
|
|
25
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
25
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
|
@ -4,14 +4,10 @@
|
||||||
|
|
||||||
// We have a implementation in amd64 assembly so this code is only run on
|
// We have a implementation in amd64 assembly so this code is only run on
|
||||||
// non-amd64 platforms. The amd64 assembly does not support gccgo.
|
// non-amd64 platforms. The amd64 assembly does not support gccgo.
|
||||||
// +build !amd64 gccgo appengine
|
// +build !amd64 gccgo
|
||||||
|
|
||||||
package curve25519
|
package curve25519
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This code is a port of the public domain, "ref10" implementation of
|
// This code is a port of the public domain, "ref10" implementation of
|
||||||
// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
|
// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
|
||||||
|
|
||||||
|
@ -54,11 +50,17 @@ func feCopy(dst, src *fieldElement) {
|
||||||
//
|
//
|
||||||
// Preconditions: b in {0,1}.
|
// Preconditions: b in {0,1}.
|
||||||
func feCSwap(f, g *fieldElement, b int32) {
|
func feCSwap(f, g *fieldElement, b int32) {
|
||||||
|
var x fieldElement
|
||||||
b = -b
|
b = -b
|
||||||
|
for i := range x {
|
||||||
|
x[i] = b & (f[i] ^ g[i])
|
||||||
|
}
|
||||||
|
|
||||||
for i := range f {
|
for i := range f {
|
||||||
t := b & (f[i] ^ g[i])
|
f[i] ^= x[i]
|
||||||
f[i] ^= t
|
}
|
||||||
g[i] ^= t
|
for i := range g {
|
||||||
|
g[i] ^= x[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +75,12 @@ func load3(in []byte) int64 {
|
||||||
|
|
||||||
// load4 reads a 32-bit, little-endian value from in.
|
// load4 reads a 32-bit, little-endian value from in.
|
||||||
func load4(in []byte) int64 {
|
func load4(in []byte) int64 {
|
||||||
return int64(binary.LittleEndian.Uint32(in))
|
var r int64
|
||||||
|
r = int64(in[0])
|
||||||
|
r |= int64(in[1]) << 8
|
||||||
|
r |= int64(in[2]) << 16
|
||||||
|
r |= int64(in[3]) << 24
|
||||||
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func feFromBytes(dst *fieldElement, src *[32]byte) {
|
func feFromBytes(dst *fieldElement, src *[32]byte) {
|
||||||
|
|
10
vendor/golang.org/x/crypto/curve25519/curve25519_test.go
generated
vendored
10
vendor/golang.org/x/crypto/curve25519/curve25519_test.go
generated
vendored
|
@ -27,13 +27,3 @@ func TestBaseScalarMult(t *testing.T) {
|
||||||
t.Errorf("incorrect result: got %s, want %s", result, expectedHex)
|
t.Errorf("incorrect result: got %s, want %s", result, expectedHex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkScalarBaseMult(b *testing.B) {
|
|
||||||
var in, out [32]byte
|
|
||||||
in[0] = 1
|
|
||||||
|
|
||||||
b.SetBytes(32)
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
ScalarBaseMult(&out, &in)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
31
vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
generated
vendored
31
vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
generated
vendored
|
@ -5,20 +5,31 @@
|
||||||
// This code was translated into a form compatible with 6a from the public
|
// This code was translated into a form compatible with 6a from the public
|
||||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
// +build amd64,!gccgo
|
||||||
|
|
||||||
#include "const_amd64.h"
|
|
||||||
|
|
||||||
// func freeze(inout *[5]uint64)
|
// func freeze(inout *[5]uint64)
|
||||||
TEXT ·freeze(SB),7,$0-8
|
TEXT ·freeze(SB),7,$96-8
|
||||||
MOVQ inout+0(FP), DI
|
MOVQ inout+0(FP), DI
|
||||||
|
|
||||||
|
MOVQ SP,R11
|
||||||
|
MOVQ $31,CX
|
||||||
|
NOTQ CX
|
||||||
|
ANDQ CX,SP
|
||||||
|
ADDQ $32,SP
|
||||||
|
|
||||||
|
MOVQ R11,0(SP)
|
||||||
|
MOVQ R12,8(SP)
|
||||||
|
MOVQ R13,16(SP)
|
||||||
|
MOVQ R14,24(SP)
|
||||||
|
MOVQ R15,32(SP)
|
||||||
|
MOVQ BX,40(SP)
|
||||||
|
MOVQ BP,48(SP)
|
||||||
MOVQ 0(DI),SI
|
MOVQ 0(DI),SI
|
||||||
MOVQ 8(DI),DX
|
MOVQ 8(DI),DX
|
||||||
MOVQ 16(DI),CX
|
MOVQ 16(DI),CX
|
||||||
MOVQ 24(DI),R8
|
MOVQ 24(DI),R8
|
||||||
MOVQ 32(DI),R9
|
MOVQ 32(DI),R9
|
||||||
MOVQ $REDMASK51,AX
|
MOVQ ·REDMASK51(SB),AX
|
||||||
MOVQ AX,R10
|
MOVQ AX,R10
|
||||||
SUBQ $18,R10
|
SUBQ $18,R10
|
||||||
MOVQ $3,R11
|
MOVQ $3,R11
|
||||||
|
@ -70,4 +81,14 @@ REDUCELOOP:
|
||||||
MOVQ CX,16(DI)
|
MOVQ CX,16(DI)
|
||||||
MOVQ R8,24(DI)
|
MOVQ R8,24(DI)
|
||||||
MOVQ R9,32(DI)
|
MOVQ R9,32(DI)
|
||||||
|
MOVQ 0(SP),R11
|
||||||
|
MOVQ 8(SP),R12
|
||||||
|
MOVQ 16(SP),R13
|
||||||
|
MOVQ 24(SP),R14
|
||||||
|
MOVQ 32(SP),R15
|
||||||
|
MOVQ 40(SP),BX
|
||||||
|
MOVQ 48(SP),BP
|
||||||
|
MOVQ R11,SP
|
||||||
|
MOVQ DI,AX
|
||||||
|
MOVQ SI,DX
|
||||||
RET
|
RET
|
||||||
|
|
841
vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s
generated
vendored
841
vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s
generated
vendored
File diff suppressed because it is too large
Load diff
2
vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go
generated
vendored
2
vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go
generated
vendored
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
// +build amd64,!gccgo
|
||||||
|
|
||||||
package curve25519
|
package curve25519
|
||||||
|
|
||||||
|
|
46
vendor/golang.org/x/crypto/curve25519/mul_amd64.s
generated
vendored
46
vendor/golang.org/x/crypto/curve25519/mul_amd64.s
generated
vendored
|
@ -5,26 +5,38 @@
|
||||||
// This code was translated into a form compatible with 6a from the public
|
// This code was translated into a form compatible with 6a from the public
|
||||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
// +build amd64,!gccgo
|
||||||
|
|
||||||
#include "const_amd64.h"
|
|
||||||
|
|
||||||
// func mul(dest, a, b *[5]uint64)
|
// func mul(dest, a, b *[5]uint64)
|
||||||
TEXT ·mul(SB),0,$16-24
|
TEXT ·mul(SB),0,$128-24
|
||||||
MOVQ dest+0(FP), DI
|
MOVQ dest+0(FP), DI
|
||||||
MOVQ a+8(FP), SI
|
MOVQ a+8(FP), SI
|
||||||
MOVQ b+16(FP), DX
|
MOVQ b+16(FP), DX
|
||||||
|
|
||||||
|
MOVQ SP,R11
|
||||||
|
MOVQ $31,CX
|
||||||
|
NOTQ CX
|
||||||
|
ANDQ CX,SP
|
||||||
|
ADDQ $32,SP
|
||||||
|
|
||||||
|
MOVQ R11,0(SP)
|
||||||
|
MOVQ R12,8(SP)
|
||||||
|
MOVQ R13,16(SP)
|
||||||
|
MOVQ R14,24(SP)
|
||||||
|
MOVQ R15,32(SP)
|
||||||
|
MOVQ BX,40(SP)
|
||||||
|
MOVQ BP,48(SP)
|
||||||
|
MOVQ DI,56(SP)
|
||||||
MOVQ DX,CX
|
MOVQ DX,CX
|
||||||
MOVQ 24(SI),DX
|
MOVQ 24(SI),DX
|
||||||
IMUL3Q $19,DX,AX
|
IMUL3Q $19,DX,AX
|
||||||
MOVQ AX,0(SP)
|
MOVQ AX,64(SP)
|
||||||
MULQ 16(CX)
|
MULQ 16(CX)
|
||||||
MOVQ AX,R8
|
MOVQ AX,R8
|
||||||
MOVQ DX,R9
|
MOVQ DX,R9
|
||||||
MOVQ 32(SI),DX
|
MOVQ 32(SI),DX
|
||||||
IMUL3Q $19,DX,AX
|
IMUL3Q $19,DX,AX
|
||||||
MOVQ AX,8(SP)
|
MOVQ AX,72(SP)
|
||||||
MULQ 8(CX)
|
MULQ 8(CX)
|
||||||
ADDQ AX,R8
|
ADDQ AX,R8
|
||||||
ADCQ DX,R9
|
ADCQ DX,R9
|
||||||
|
@ -99,11 +111,11 @@ TEXT ·mul(SB),0,$16-24
|
||||||
MULQ 8(CX)
|
MULQ 8(CX)
|
||||||
ADDQ AX,BX
|
ADDQ AX,BX
|
||||||
ADCQ DX,BP
|
ADCQ DX,BP
|
||||||
MOVQ 0(SP),AX
|
MOVQ 64(SP),AX
|
||||||
MULQ 24(CX)
|
MULQ 24(CX)
|
||||||
ADDQ AX,R10
|
ADDQ AX,R10
|
||||||
ADCQ DX,R11
|
ADCQ DX,R11
|
||||||
MOVQ 0(SP),AX
|
MOVQ 64(SP),AX
|
||||||
MULQ 32(CX)
|
MULQ 32(CX)
|
||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
|
@ -111,19 +123,19 @@ TEXT ·mul(SB),0,$16-24
|
||||||
MULQ 0(CX)
|
MULQ 0(CX)
|
||||||
ADDQ AX,BX
|
ADDQ AX,BX
|
||||||
ADCQ DX,BP
|
ADCQ DX,BP
|
||||||
MOVQ 8(SP),AX
|
MOVQ 72(SP),AX
|
||||||
MULQ 16(CX)
|
MULQ 16(CX)
|
||||||
ADDQ AX,R10
|
ADDQ AX,R10
|
||||||
ADCQ DX,R11
|
ADCQ DX,R11
|
||||||
MOVQ 8(SP),AX
|
MOVQ 72(SP),AX
|
||||||
MULQ 24(CX)
|
MULQ 24(CX)
|
||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ 8(SP),AX
|
MOVQ 72(SP),AX
|
||||||
MULQ 32(CX)
|
MULQ 32(CX)
|
||||||
ADDQ AX,R14
|
ADDQ AX,R14
|
||||||
ADCQ DX,R15
|
ADCQ DX,R15
|
||||||
MOVQ $REDMASK51,SI
|
MOVQ ·REDMASK51(SB),SI
|
||||||
SHLQ $13,R9:R8
|
SHLQ $13,R9:R8
|
||||||
ANDQ SI,R8
|
ANDQ SI,R8
|
||||||
SHLQ $13,R11:R10
|
SHLQ $13,R11:R10
|
||||||
|
@ -166,4 +178,14 @@ TEXT ·mul(SB),0,$16-24
|
||||||
MOVQ R9,16(DI)
|
MOVQ R9,16(DI)
|
||||||
MOVQ AX,24(DI)
|
MOVQ AX,24(DI)
|
||||||
MOVQ R10,32(DI)
|
MOVQ R10,32(DI)
|
||||||
|
MOVQ 0(SP),R11
|
||||||
|
MOVQ 8(SP),R12
|
||||||
|
MOVQ 16(SP),R13
|
||||||
|
MOVQ 24(SP),R14
|
||||||
|
MOVQ 32(SP),R15
|
||||||
|
MOVQ 40(SP),BX
|
||||||
|
MOVQ 48(SP),BP
|
||||||
|
MOVQ R11,SP
|
||||||
|
MOVQ DI,AX
|
||||||
|
MOVQ SI,DX
|
||||||
RET
|
RET
|
||||||
|
|
31
vendor/golang.org/x/crypto/curve25519/square_amd64.s
generated
vendored
31
vendor/golang.org/x/crypto/curve25519/square_amd64.s
generated
vendored
|
@ -5,15 +5,26 @@
|
||||||
// This code was translated into a form compatible with 6a from the public
|
// This code was translated into a form compatible with 6a from the public
|
||||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
// +build amd64,!gccgo
|
||||||
|
|
||||||
#include "const_amd64.h"
|
|
||||||
|
|
||||||
// func square(out, in *[5]uint64)
|
// func square(out, in *[5]uint64)
|
||||||
TEXT ·square(SB),7,$0-16
|
TEXT ·square(SB),7,$96-16
|
||||||
MOVQ out+0(FP), DI
|
MOVQ out+0(FP), DI
|
||||||
MOVQ in+8(FP), SI
|
MOVQ in+8(FP), SI
|
||||||
|
|
||||||
|
MOVQ SP,R11
|
||||||
|
MOVQ $31,CX
|
||||||
|
NOTQ CX
|
||||||
|
ANDQ CX,SP
|
||||||
|
ADDQ $32, SP
|
||||||
|
|
||||||
|
MOVQ R11,0(SP)
|
||||||
|
MOVQ R12,8(SP)
|
||||||
|
MOVQ R13,16(SP)
|
||||||
|
MOVQ R14,24(SP)
|
||||||
|
MOVQ R15,32(SP)
|
||||||
|
MOVQ BX,40(SP)
|
||||||
|
MOVQ BP,48(SP)
|
||||||
MOVQ 0(SI),AX
|
MOVQ 0(SI),AX
|
||||||
MULQ 0(SI)
|
MULQ 0(SI)
|
||||||
MOVQ AX,CX
|
MOVQ AX,CX
|
||||||
|
@ -86,7 +97,7 @@ TEXT ·square(SB),7,$0-16
|
||||||
MULQ 32(SI)
|
MULQ 32(SI)
|
||||||
ADDQ AX,R13
|
ADDQ AX,R13
|
||||||
ADCQ DX,R14
|
ADCQ DX,R14
|
||||||
MOVQ $REDMASK51,SI
|
MOVQ ·REDMASK51(SB),SI
|
||||||
SHLQ $13,R8:CX
|
SHLQ $13,R8:CX
|
||||||
ANDQ SI,CX
|
ANDQ SI,CX
|
||||||
SHLQ $13,R10:R9
|
SHLQ $13,R10:R9
|
||||||
|
@ -129,4 +140,14 @@ TEXT ·square(SB),7,$0-16
|
||||||
MOVQ R9,16(DI)
|
MOVQ R9,16(DI)
|
||||||
MOVQ AX,24(DI)
|
MOVQ AX,24(DI)
|
||||||
MOVQ R10,32(DI)
|
MOVQ R10,32(DI)
|
||||||
|
MOVQ 0(SP),R11
|
||||||
|
MOVQ 8(SP),R12
|
||||||
|
MOVQ 16(SP),R13
|
||||||
|
MOVQ 24(SP),R14
|
||||||
|
MOVQ 32(SP),R15
|
||||||
|
MOVQ 40(SP),BX
|
||||||
|
MOVQ 48(SP),BP
|
||||||
|
MOVQ R11,SP
|
||||||
|
MOVQ DI,AX
|
||||||
|
MOVQ SI,DX
|
||||||
RET
|
RET
|
||||||
|
|
181
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
181
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
|
@ -1,181 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package ed25519 implements the Ed25519 signature algorithm. See
|
|
||||||
// http://ed25519.cr.yp.to/.
|
|
||||||
//
|
|
||||||
// These functions are also compatible with the “Ed25519” function defined in
|
|
||||||
// https://tools.ietf.org/html/draft-irtf-cfrg-eddsa-05.
|
|
||||||
package ed25519
|
|
||||||
|
|
||||||
// This code is a port of the public domain, “ref10” implementation of ed25519
|
|
||||||
// from SUPERCOP.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto"
|
|
||||||
cryptorand "crypto/rand"
|
|
||||||
"crypto/sha512"
|
|
||||||
"crypto/subtle"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/ed25519/internal/edwards25519"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// PublicKeySize is the size, in bytes, of public keys as used in this package.
|
|
||||||
PublicKeySize = 32
|
|
||||||
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
|
|
||||||
PrivateKeySize = 64
|
|
||||||
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
|
||||||
SignatureSize = 64
|
|
||||||
)
|
|
||||||
|
|
||||||
// PublicKey is the type of Ed25519 public keys.
|
|
||||||
type PublicKey []byte
|
|
||||||
|
|
||||||
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
|
|
||||||
type PrivateKey []byte
|
|
||||||
|
|
||||||
// Public returns the PublicKey corresponding to priv.
|
|
||||||
func (priv PrivateKey) Public() crypto.PublicKey {
|
|
||||||
publicKey := make([]byte, PublicKeySize)
|
|
||||||
copy(publicKey, priv[32:])
|
|
||||||
return PublicKey(publicKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign signs the given message with priv.
|
|
||||||
// Ed25519 performs two passes over messages to be signed and therefore cannot
|
|
||||||
// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
|
|
||||||
// indicate the message hasn't been hashed. This can be achieved by passing
|
|
||||||
// crypto.Hash(0) as the value for opts.
|
|
||||||
func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
|
|
||||||
if opts.HashFunc() != crypto.Hash(0) {
|
|
||||||
return nil, errors.New("ed25519: cannot sign hashed message")
|
|
||||||
}
|
|
||||||
|
|
||||||
return Sign(priv, message), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateKey generates a public/private key pair using entropy from rand.
|
|
||||||
// If rand is nil, crypto/rand.Reader will be used.
|
|
||||||
func GenerateKey(rand io.Reader) (publicKey PublicKey, privateKey PrivateKey, err error) {
|
|
||||||
if rand == nil {
|
|
||||||
rand = cryptorand.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
privateKey = make([]byte, PrivateKeySize)
|
|
||||||
publicKey = make([]byte, PublicKeySize)
|
|
||||||
_, err = io.ReadFull(rand, privateKey[:32])
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
digest := sha512.Sum512(privateKey[:32])
|
|
||||||
digest[0] &= 248
|
|
||||||
digest[31] &= 127
|
|
||||||
digest[31] |= 64
|
|
||||||
|
|
||||||
var A edwards25519.ExtendedGroupElement
|
|
||||||
var hBytes [32]byte
|
|
||||||
copy(hBytes[:], digest[:])
|
|
||||||
edwards25519.GeScalarMultBase(&A, &hBytes)
|
|
||||||
var publicKeyBytes [32]byte
|
|
||||||
A.ToBytes(&publicKeyBytes)
|
|
||||||
|
|
||||||
copy(privateKey[32:], publicKeyBytes[:])
|
|
||||||
copy(publicKey, publicKeyBytes[:])
|
|
||||||
|
|
||||||
return publicKey, privateKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign signs the message with privateKey and returns a signature. It will
|
|
||||||
// panic if len(privateKey) is not PrivateKeySize.
|
|
||||||
func Sign(privateKey PrivateKey, message []byte) []byte {
|
|
||||||
if l := len(privateKey); l != PrivateKeySize {
|
|
||||||
panic("ed25519: bad private key length: " + strconv.Itoa(l))
|
|
||||||
}
|
|
||||||
|
|
||||||
h := sha512.New()
|
|
||||||
h.Write(privateKey[:32])
|
|
||||||
|
|
||||||
var digest1, messageDigest, hramDigest [64]byte
|
|
||||||
var expandedSecretKey [32]byte
|
|
||||||
h.Sum(digest1[:0])
|
|
||||||
copy(expandedSecretKey[:], digest1[:])
|
|
||||||
expandedSecretKey[0] &= 248
|
|
||||||
expandedSecretKey[31] &= 63
|
|
||||||
expandedSecretKey[31] |= 64
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
h.Write(digest1[32:])
|
|
||||||
h.Write(message)
|
|
||||||
h.Sum(messageDigest[:0])
|
|
||||||
|
|
||||||
var messageDigestReduced [32]byte
|
|
||||||
edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
|
|
||||||
var R edwards25519.ExtendedGroupElement
|
|
||||||
edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
|
|
||||||
|
|
||||||
var encodedR [32]byte
|
|
||||||
R.ToBytes(&encodedR)
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
h.Write(encodedR[:])
|
|
||||||
h.Write(privateKey[32:])
|
|
||||||
h.Write(message)
|
|
||||||
h.Sum(hramDigest[:0])
|
|
||||||
var hramDigestReduced [32]byte
|
|
||||||
edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
|
|
||||||
|
|
||||||
var s [32]byte
|
|
||||||
edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
|
|
||||||
|
|
||||||
signature := make([]byte, SignatureSize)
|
|
||||||
copy(signature[:], encodedR[:])
|
|
||||||
copy(signature[32:], s[:])
|
|
||||||
|
|
||||||
return signature
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify reports whether sig is a valid signature of message by publicKey. It
|
|
||||||
// will panic if len(publicKey) is not PublicKeySize.
|
|
||||||
func Verify(publicKey PublicKey, message, sig []byte) bool {
|
|
||||||
if l := len(publicKey); l != PublicKeySize {
|
|
||||||
panic("ed25519: bad public key length: " + strconv.Itoa(l))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(sig) != SignatureSize || sig[63]&224 != 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var A edwards25519.ExtendedGroupElement
|
|
||||||
var publicKeyBytes [32]byte
|
|
||||||
copy(publicKeyBytes[:], publicKey)
|
|
||||||
if !A.FromBytes(&publicKeyBytes) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
edwards25519.FeNeg(&A.X, &A.X)
|
|
||||||
edwards25519.FeNeg(&A.T, &A.T)
|
|
||||||
|
|
||||||
h := sha512.New()
|
|
||||||
h.Write(sig[:32])
|
|
||||||
h.Write(publicKey[:])
|
|
||||||
h.Write(message)
|
|
||||||
var digest [64]byte
|
|
||||||
h.Sum(digest[:0])
|
|
||||||
|
|
||||||
var hReduced [32]byte
|
|
||||||
edwards25519.ScReduce(&hReduced, &digest)
|
|
||||||
|
|
||||||
var R edwards25519.ProjectiveGroupElement
|
|
||||||
var b [32]byte
|
|
||||||
copy(b[:], sig[32:])
|
|
||||||
edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &b)
|
|
||||||
|
|
||||||
var checkR [32]byte
|
|
||||||
R.ToBytes(&checkR)
|
|
||||||
return subtle.ConstantTimeCompare(sig[:32], checkR[:]) == 1
|
|
||||||
}
|
|
183
vendor/golang.org/x/crypto/ed25519/ed25519_test.go
generated
vendored
183
vendor/golang.org/x/crypto/ed25519/ed25519_test.go
generated
vendored
|
@ -1,183 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ed25519
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"crypto"
|
|
||||||
"crypto/rand"
|
|
||||||
"encoding/hex"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/ed25519/internal/edwards25519"
|
|
||||||
)
|
|
||||||
|
|
||||||
type zeroReader struct{}
|
|
||||||
|
|
||||||
func (zeroReader) Read(buf []byte) (int, error) {
|
|
||||||
for i := range buf {
|
|
||||||
buf[i] = 0
|
|
||||||
}
|
|
||||||
return len(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnmarshalMarshal(t *testing.T) {
|
|
||||||
pub, _, _ := GenerateKey(rand.Reader)
|
|
||||||
|
|
||||||
var A edwards25519.ExtendedGroupElement
|
|
||||||
var pubBytes [32]byte
|
|
||||||
copy(pubBytes[:], pub)
|
|
||||||
if !A.FromBytes(&pubBytes) {
|
|
||||||
t.Fatalf("ExtendedGroupElement.FromBytes failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
var pub2 [32]byte
|
|
||||||
A.ToBytes(&pub2)
|
|
||||||
|
|
||||||
if pubBytes != pub2 {
|
|
||||||
t.Errorf("FromBytes(%v)->ToBytes does not round-trip, got %x\n", pubBytes, pub2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSignVerify(t *testing.T) {
|
|
||||||
var zero zeroReader
|
|
||||||
public, private, _ := GenerateKey(zero)
|
|
||||||
|
|
||||||
message := []byte("test message")
|
|
||||||
sig := Sign(private, message)
|
|
||||||
if !Verify(public, message, sig) {
|
|
||||||
t.Errorf("valid signature rejected")
|
|
||||||
}
|
|
||||||
|
|
||||||
wrongMessage := []byte("wrong message")
|
|
||||||
if Verify(public, wrongMessage, sig) {
|
|
||||||
t.Errorf("signature of different message accepted")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCryptoSigner(t *testing.T) {
|
|
||||||
var zero zeroReader
|
|
||||||
public, private, _ := GenerateKey(zero)
|
|
||||||
|
|
||||||
signer := crypto.Signer(private)
|
|
||||||
|
|
||||||
publicInterface := signer.Public()
|
|
||||||
public2, ok := publicInterface.(PublicKey)
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("expected PublicKey from Public() but got %T", publicInterface)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(public, public2) {
|
|
||||||
t.Errorf("public keys do not match: original:%x vs Public():%x", public, public2)
|
|
||||||
}
|
|
||||||
|
|
||||||
message := []byte("message")
|
|
||||||
var noHash crypto.Hash
|
|
||||||
signature, err := signer.Sign(zero, message, noHash)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("error from Sign(): %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !Verify(public, message, signature) {
|
|
||||||
t.Errorf("Verify failed on signature from Sign()")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGolden(t *testing.T) {
|
|
||||||
// sign.input.gz is a selection of test cases from
|
|
||||||
// http://ed25519.cr.yp.to/python/sign.input
|
|
||||||
testDataZ, err := os.Open("testdata/sign.input.gz")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer testDataZ.Close()
|
|
||||||
testData, err := gzip.NewReader(testDataZ)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer testData.Close()
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(testData)
|
|
||||||
lineNo := 0
|
|
||||||
|
|
||||||
for scanner.Scan() {
|
|
||||||
lineNo++
|
|
||||||
|
|
||||||
line := scanner.Text()
|
|
||||||
parts := strings.Split(line, ":")
|
|
||||||
if len(parts) != 5 {
|
|
||||||
t.Fatalf("bad number of parts on line %d", lineNo)
|
|
||||||
}
|
|
||||||
|
|
||||||
privBytes, _ := hex.DecodeString(parts[0])
|
|
||||||
pubKey, _ := hex.DecodeString(parts[1])
|
|
||||||
msg, _ := hex.DecodeString(parts[2])
|
|
||||||
sig, _ := hex.DecodeString(parts[3])
|
|
||||||
// The signatures in the test vectors also include the message
|
|
||||||
// at the end, but we just want R and S.
|
|
||||||
sig = sig[:SignatureSize]
|
|
||||||
|
|
||||||
if l := len(pubKey); l != PublicKeySize {
|
|
||||||
t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l)
|
|
||||||
}
|
|
||||||
|
|
||||||
var priv [PrivateKeySize]byte
|
|
||||||
copy(priv[:], privBytes)
|
|
||||||
copy(priv[32:], pubKey)
|
|
||||||
|
|
||||||
sig2 := Sign(priv[:], msg)
|
|
||||||
if !bytes.Equal(sig, sig2[:]) {
|
|
||||||
t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !Verify(pubKey, msg, sig2) {
|
|
||||||
t.Errorf("signature failed to verify on line %d", lineNo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
|
||||||
t.Fatalf("error reading test data: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkKeyGeneration(b *testing.B) {
|
|
||||||
var zero zeroReader
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
if _, _, err := GenerateKey(zero); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkSigning(b *testing.B) {
|
|
||||||
var zero zeroReader
|
|
||||||
_, priv, err := GenerateKey(zero)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
message := []byte("Hello, world!")
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
Sign(priv, message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkVerification(b *testing.B) {
|
|
||||||
var zero zeroReader
|
|
||||||
pub, priv, err := GenerateKey(zero)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
message := []byte("Hello, world!")
|
|
||||||
signature := Sign(priv, message)
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
Verify(pub, message, signature)
|
|
||||||
}
|
|
||||||
}
|
|
1422
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
generated
vendored
1422
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
generated
vendored
File diff suppressed because it is too large
Load diff
1771
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
1771
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
File diff suppressed because it is too large
Load diff
BIN
vendor/golang.org/x/crypto/ed25519/testdata/sign.input.gz
generated
vendored
BIN
vendor/golang.org/x/crypto/ed25519/testdata/sign.input.gz
generated
vendored
Binary file not shown.
5
vendor/golang.org/x/crypto/nacl/box/box.go
generated
vendored
5
vendor/golang.org/x/crypto/nacl/box/box.go
generated
vendored
|
@ -13,16 +13,15 @@ example, by using nonce 1 for the first message, nonce 2 for the second
|
||||||
message, etc. Nonces are long enough that randomly generated nonces have
|
message, etc. Nonces are long enough that randomly generated nonces have
|
||||||
negligible risk of collision.
|
negligible risk of collision.
|
||||||
|
|
||||||
This package is interoperable with NaCl: https://nacl.cr.yp.to/box.html.
|
This package is interoperable with NaCl: http://nacl.cr.yp.to/box.html.
|
||||||
*/
|
*/
|
||||||
package box // import "golang.org/x/crypto/nacl/box"
|
package box // import "golang.org/x/crypto/nacl/box"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/curve25519"
|
"golang.org/x/crypto/curve25519"
|
||||||
"golang.org/x/crypto/nacl/secretbox"
|
"golang.org/x/crypto/nacl/secretbox"
|
||||||
"golang.org/x/crypto/salsa20/salsa"
|
"golang.org/x/crypto/salsa20/salsa"
|
||||||
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Overhead is the number of bytes of overhead when boxing a message.
|
// Overhead is the number of bytes of overhead when boxing a message.
|
||||||
|
|
95
vendor/golang.org/x/crypto/nacl/box/example_test.go
generated
vendored
95
vendor/golang.org/x/crypto/nacl/box/example_test.go
generated
vendored
|
@ -1,95 +0,0 @@
|
||||||
package box_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
crypto_rand "crypto/rand" // Custom so it's clear which rand we're using.
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/nacl/box"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Example() {
|
|
||||||
senderPublicKey, senderPrivateKey, err := box.GenerateKey(crypto_rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
recipientPublicKey, recipientPrivateKey, err := box.GenerateKey(crypto_rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// You must use a different nonce for each message you encrypt with the
|
|
||||||
// same key. Since the nonce here is 192 bits long, a random value
|
|
||||||
// provides a sufficiently small probability of repeats.
|
|
||||||
var nonce [24]byte
|
|
||||||
if _, err := io.ReadFull(crypto_rand.Reader, nonce[:]); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := []byte("Alas, poor Yorick! I knew him, Horatio")
|
|
||||||
// This encrypts msg and appends the result to the nonce.
|
|
||||||
encrypted := box.Seal(nonce[:], msg, &nonce, recipientPublicKey, senderPrivateKey)
|
|
||||||
|
|
||||||
// The recipient can decrypt the message using their private key and the
|
|
||||||
// sender's public key. When you decrypt, you must use the same nonce you
|
|
||||||
// used to encrypt the message. One way to achieve this is to store the
|
|
||||||
// nonce alongside the encrypted message. Above, we stored the nonce in the
|
|
||||||
// first 24 bytes of the encrypted text.
|
|
||||||
var decryptNonce [24]byte
|
|
||||||
copy(decryptNonce[:], encrypted[:24])
|
|
||||||
decrypted, ok := box.Open(nil, encrypted[24:], &decryptNonce, senderPublicKey, recipientPrivateKey)
|
|
||||||
if !ok {
|
|
||||||
panic("decryption error")
|
|
||||||
}
|
|
||||||
fmt.Println(string(decrypted))
|
|
||||||
// Output: Alas, poor Yorick! I knew him, Horatio
|
|
||||||
}
|
|
||||||
|
|
||||||
func Example_precompute() {
|
|
||||||
senderPublicKey, senderPrivateKey, err := box.GenerateKey(crypto_rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
recipientPublicKey, recipientPrivateKey, err := box.GenerateKey(crypto_rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The shared key can be used to speed up processing when using the same
|
|
||||||
// pair of keys repeatedly.
|
|
||||||
sharedEncryptKey := new([32]byte)
|
|
||||||
box.Precompute(sharedEncryptKey, recipientPublicKey, senderPrivateKey)
|
|
||||||
|
|
||||||
// You must use a different nonce for each message you encrypt with the
|
|
||||||
// same key. Since the nonce here is 192 bits long, a random value
|
|
||||||
// provides a sufficiently small probability of repeats.
|
|
||||||
var nonce [24]byte
|
|
||||||
if _, err := io.ReadFull(crypto_rand.Reader, nonce[:]); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := []byte("A fellow of infinite jest, of most excellent fancy")
|
|
||||||
// This encrypts msg and appends the result to the nonce.
|
|
||||||
encrypted := box.SealAfterPrecomputation(nonce[:], msg, &nonce, sharedEncryptKey)
|
|
||||||
|
|
||||||
// The shared key can be used to speed up processing when using the same
|
|
||||||
// pair of keys repeatedly.
|
|
||||||
var sharedDecryptKey [32]byte
|
|
||||||
box.Precompute(&sharedDecryptKey, senderPublicKey, recipientPrivateKey)
|
|
||||||
|
|
||||||
// The recipient can decrypt the message using the shared key. When you
|
|
||||||
// decrypt, you must use the same nonce you used to encrypt the message.
|
|
||||||
// One way to achieve this is to store the nonce alongside the encrypted
|
|
||||||
// message. Above, we stored the nonce in the first 24 bytes of the
|
|
||||||
// encrypted text.
|
|
||||||
var decryptNonce [24]byte
|
|
||||||
copy(decryptNonce[:], encrypted[:24])
|
|
||||||
decrypted, ok := box.OpenAfterPrecomputation(nil, encrypted[24:], &decryptNonce, &sharedDecryptKey)
|
|
||||||
if !ok {
|
|
||||||
panic("decryption error")
|
|
||||||
}
|
|
||||||
fmt.Println(string(decrypted))
|
|
||||||
// Output: A fellow of infinite jest, of most excellent fancy
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue