1
0
mirror of https://github.com/kubernetes-sigs/descheduler.git synced 2026-01-28 14:41:10 +01:00

bump(*): k8s to 1.17

This commit is contained in:
Mike Dame
2019-12-12 11:02:29 -05:00
parent 3be0a9f80d
commit b3cc62dac6
7242 changed files with 473872 additions and 329488 deletions

53
glide.lock generated
View File

@@ -1,5 +1,5 @@
hash: f82bf395df6f00004b1794606a9256d5c69b62deb5498b574a08b2b5d15f7a6a hash: 20c321631a99e15eafc7907de7b335f1874c451cef023c2159badbcf138c05d7
updated: 2019-12-11T21:28:26.970892-06:00 updated: 2019-12-12T11:02:04.692422-05:00
imports: imports:
- name: cloud.google.com/go - name: cloud.google.com/go
version: 8c41231e01b2085512d98153bcffb847ff9b4b9f version: 8c41231e01b2085512d98153bcffb847ff9b4b9f
@@ -37,7 +37,7 @@ imports:
subpackages: subpackages:
- lru - lru
- name: github.com/golang/protobuf - name: github.com/golang/protobuf
version: b5d812f8a3706043e23a9cd5babf2e5423744d30 version: 6c65a5562fc06764971b7c5d05c76c75e84bdbf7
subpackages: subpackages:
- proto - proto
- ptypes - ptypes
@@ -78,7 +78,7 @@ imports:
- name: github.com/inconshreveable/mousetrap - name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/json-iterator/go - name: github.com/json-iterator/go
version: 27518f6661eba504be5a7a9a9f6d9460d892ade3 version: 03217c3e97663914aec3faafde50d081f197a0a2
- name: github.com/modern-go/concurrent - name: github.com/modern-go/concurrent
version: bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94 version: bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94
- name: github.com/modern-go/reflect2 - name: github.com/modern-go/reflect2
@@ -90,11 +90,11 @@ imports:
- name: github.com/spf13/pflag - name: github.com/spf13/pflag
version: 298182f68c66c05229eb03ac171abe6e309ee79a version: 298182f68c66c05229eb03ac171abe6e309ee79a
- name: golang.org/x/crypto - name: golang.org/x/crypto
version: e84da0312774c21d64ee2317962ef669b27ffb41 version: 60c769a6c58655dab1b9adac0d58967dd517cfba
subpackages: subpackages:
- ssh/terminal - ssh/terminal
- name: golang.org/x/net - name: golang.org/x/net
version: cdfb69ac37fc6fa907650654115ebebb3aae2087 version: 13f9640d40b9cc418fb53703dfbd177679788ceb
subpackages: subpackages:
- context - context
- context/ctxhttp - context/ctxhttp
@@ -103,26 +103,26 @@ imports:
- http2/hpack - http2/hpack
- idna - idna
- name: golang.org/x/oauth2 - name: golang.org/x/oauth2
version: 9f3314589c9a9136388751d9adae6b0ed400978a version: 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33
subpackages: subpackages:
- google - google
- internal - internal
- jws - jws
- jwt - jwt
- name: golang.org/x/sys - name: golang.org/x/sys
version: 3b5209105503162ded1863c307ac66fec31120dd version: fde4db37ae7ad8191b03d30d27f258b5291ae4e3
subpackages: subpackages:
- unix - unix
- windows - windows
- name: golang.org/x/text - name: golang.org/x/text
version: e6919f6577db79269a6443b9dc46d18f2238fb5d version: 342b2e1fbaa52c93f31447ad2c6abc048c63e475
subpackages: subpackages:
- secure/bidirule - secure/bidirule
- transform - transform
- unicode/bidi - unicode/bidi
- unicode/norm - unicode/norm
- name: golang.org/x/time - name: golang.org/x/time
version: f51c12702a4d776e4c1fa9b0fabab841babae631 version: 9d24e82272b4f38b78bc8cff74fa936d31ccd8ef
subpackages: subpackages:
- rate - rate
- name: google.golang.org/appengine - name: google.golang.org/appengine
@@ -138,11 +138,11 @@ imports:
- internal/urlfetch - internal/urlfetch
- urlfetch - urlfetch
- name: gopkg.in/inf.v0 - name: gopkg.in/inf.v0
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 version: d2d2541c53f18d2a059457998ce2876cc8e67cbf
- name: gopkg.in/yaml.v2 - name: gopkg.in/yaml.v2
version: 51d6538a90f86fe93ac480b35f37b2be17fef232 version: f221b8435cfb71e54062f6c6e99e9ade30b124d5
- name: k8s.io/api - name: k8s.io/api
version: 95b840bb6a1f5f0462af804c8589396d294d4914 version: 4c9a86741a7ab3890dd9e0777e85d8eee48bf59c
subpackages: subpackages:
- admission/v1 - admission/v1
- admission/v1beta1 - admission/v1beta1
@@ -167,8 +167,10 @@ imports:
- coordination/v1beta1 - coordination/v1beta1
- core/v1 - core/v1
- discovery/v1alpha1 - discovery/v1alpha1
- discovery/v1beta1
- events/v1beta1 - events/v1beta1
- extensions/v1beta1 - extensions/v1beta1
- flowcontrol/v1alpha1
- imagepolicy/v1alpha1 - imagepolicy/v1alpha1
- networking/v1 - networking/v1
- networking/v1beta1 - networking/v1beta1
@@ -186,11 +188,11 @@ imports:
- storage/v1alpha1 - storage/v1alpha1
- storage/v1beta1 - storage/v1beta1
- name: k8s.io/apiextensions-apiserver - name: k8s.io/apiextensions-apiserver
version: 8f644eb6e783291c4b8cb8cb25a9983be1a74f5c version: ea07e0496fdfc3befebe481bd6f850febc41cdae
subpackages: subpackages:
- pkg/features - pkg/features
- name: k8s.io/apimachinery - name: k8s.io/apimachinery
version: 27d36303b6556f377b4f34e64705fa9024a12b0c version: 79c2a76c473a20cdc4ce59cae4b72529b5d9d16b
subpackages: subpackages:
- pkg/api/errors - pkg/api/errors
- pkg/api/meta - pkg/api/meta
@@ -235,12 +237,12 @@ imports:
- third_party/forked/golang/json - third_party/forked/golang/json
- third_party/forked/golang/reflect - third_party/forked/golang/reflect
- name: k8s.io/apiserver - name: k8s.io/apiserver
version: bfa5e2e684ad413c22fd0dab55b2592af1ead049 version: b79eb8a53681ea45917adf091f05f4c862cadd67
subpackages: subpackages:
- pkg/features - pkg/features
- pkg/util/feature - pkg/util/feature
- name: k8s.io/client-go - name: k8s.io/client-go
version: 1fbdaa4c8d908275eee958429b1cafc2591a2c5d version: c68b62b1efa14564a47d67c07f013dc3553937b9
subpackages: subpackages:
- discovery - discovery
- discovery/fake - discovery/fake
@@ -289,10 +291,14 @@ imports:
- kubernetes/typed/core/v1/fake - kubernetes/typed/core/v1/fake
- kubernetes/typed/discovery/v1alpha1 - kubernetes/typed/discovery/v1alpha1
- kubernetes/typed/discovery/v1alpha1/fake - kubernetes/typed/discovery/v1alpha1/fake
- kubernetes/typed/discovery/v1beta1
- kubernetes/typed/discovery/v1beta1/fake
- kubernetes/typed/events/v1beta1 - kubernetes/typed/events/v1beta1
- kubernetes/typed/events/v1beta1/fake - kubernetes/typed/events/v1beta1/fake
- kubernetes/typed/extensions/v1beta1 - kubernetes/typed/extensions/v1beta1
- kubernetes/typed/extensions/v1beta1/fake - kubernetes/typed/extensions/v1beta1/fake
- kubernetes/typed/flowcontrol/v1alpha1
- kubernetes/typed/flowcontrol/v1alpha1/fake
- kubernetes/typed/networking/v1 - kubernetes/typed/networking/v1
- kubernetes/typed/networking/v1/fake - kubernetes/typed/networking/v1/fake
- kubernetes/typed/networking/v1beta1 - kubernetes/typed/networking/v1beta1
@@ -358,9 +364,9 @@ imports:
- util/keyutil - util/keyutil
- util/retry - util/retry
- name: k8s.io/code-generator - name: k8s.io/code-generator
version: cd179ad6a2693011d6f2fa5cd64c6680ee99379f version: e95606b614f049ef6087115cb340d8d5805b8da7
- name: k8s.io/component-base - name: k8s.io/component-base
version: 547f6c5d70902c6683e93ad96f84adc6b943aedf version: d28e171e54a29670f44b1cc6eed68fd609028f62
subpackages: subpackages:
- cli/flag - cli/flag
- featuregate - featuregate
@@ -368,13 +374,13 @@ imports:
- name: k8s.io/gengo - name: k8s.io/gengo
version: 26a664648505d962332bda642b27306bc10d1082 version: 26a664648505d962332bda642b27306bc10d1082
- name: k8s.io/klog - name: k8s.io/klog
version: 3ca30a56d8a775276f9cdae009ba326fdc05af7f version: 2ca9ad30301bf30a8a6e0fa2110db6b8df699a91
- name: k8s.io/kube-openapi - name: k8s.io/kube-openapi
version: 743ec37842bffe49dd4221d9026f30fb1d5adbc4 version: 30be4d16710ac61bce31eb28a01054596fe6a9f1
subpackages: subpackages:
- pkg/util/proto - pkg/util/proto
- name: k8s.io/kubernetes - name: k8s.io/kubernetes
version: d70a3ca08fe72ad8dd0b2d72cf032474ab2ce2a9 version: 512f09638c517ad6375070af15af905ac00051a7
subpackages: subpackages:
- pkg/api/legacyscheme - pkg/api/legacyscheme
- pkg/api/testapi - pkg/api/testapi
@@ -429,6 +435,7 @@ imports:
- pkg/apis/discovery - pkg/apis/discovery
- pkg/apis/discovery/install - pkg/apis/discovery/install
- pkg/apis/discovery/v1alpha1 - pkg/apis/discovery/v1alpha1
- pkg/apis/discovery/v1beta1
- pkg/apis/events - pkg/apis/events
- pkg/apis/events/install - pkg/apis/events/install
- pkg/apis/events/v1beta1 - pkg/apis/events/v1beta1
@@ -472,7 +479,7 @@ imports:
- pkg/scheduler/algorithm/priorities/util - pkg/scheduler/algorithm/priorities/util
- pkg/util/parsers - pkg/util/parsers
- name: k8s.io/utils - name: k8s.io/utils
version: 581e00157fb1a0435d4fac54a52d1ca1e481d60e version: e782cd3c129fc98ee807f3c889c0f26eb7c9daf5
subpackages: subpackages:
- buffer - buffer
- integer - integer

View File

@@ -57,6 +57,7 @@ import (
) )
const secondInNanos = int64(time.Second / time.Nanosecond) const secondInNanos = int64(time.Second / time.Nanosecond)
const maxSecondsInDuration = 315576000000
// Marshaler is a configurable object for converting between // Marshaler is a configurable object for converting between
// protocol buffer objects and a JSON representation for them. // protocol buffer objects and a JSON representation for them.
@@ -182,7 +183,12 @@ func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeU
return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err)
} }
js["@type"] = (*json.RawMessage)(&turl) js["@type"] = (*json.RawMessage)(&turl)
if b, err = json.Marshal(js); err != nil { if m.Indent != "" {
b, err = json.MarshalIndent(js, indent, m.Indent)
} else {
b, err = json.Marshal(js)
}
if err != nil {
return err return err
} }
} }
@@ -206,19 +212,26 @@ func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeU
// Any is a bit more involved. // Any is a bit more involved.
return m.marshalAny(out, v, indent) return m.marshalAny(out, v, indent)
case "Duration": case "Duration":
// "Generated output always contains 0, 3, 6, or 9 fractional digits,
// depending on required precision."
s, ns := s.Field(0).Int(), s.Field(1).Int() s, ns := s.Field(0).Int(), s.Field(1).Int()
if s < -maxSecondsInDuration || s > maxSecondsInDuration {
return fmt.Errorf("seconds out of range %v", s)
}
if ns <= -secondInNanos || ns >= secondInNanos { if ns <= -secondInNanos || ns >= secondInNanos {
return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos)
} }
if (s > 0 && ns < 0) || (s < 0 && ns > 0) { if (s > 0 && ns < 0) || (s < 0 && ns > 0) {
return errors.New("signs of seconds and nanos do not match") return errors.New("signs of seconds and nanos do not match")
} }
if s < 0 { // Generated output always contains 0, 3, 6, or 9 fractional digits,
// depending on required precision, followed by the suffix "s".
f := "%d.%09d"
if ns < 0 {
ns = -ns ns = -ns
if s == 0 {
f = "-%d.%09d"
}
} }
x := fmt.Sprintf("%d.%09d", s, ns) x := fmt.Sprintf(f, s, ns)
x = strings.TrimSuffix(x, "000") x = strings.TrimSuffix(x, "000")
x = strings.TrimSuffix(x, "000") x = strings.TrimSuffix(x, "000")
x = strings.TrimSuffix(x, ".000") x = strings.TrimSuffix(x, ".000")

View File

@@ -473,10 +473,17 @@ var marshalingTests = []struct {
{"Any with message and indent", marshalerAllOptions, anySimple, anySimplePrettyJSON}, {"Any with message and indent", marshalerAllOptions, anySimple, anySimplePrettyJSON},
{"Any with WKT", marshaler, anyWellKnown, anyWellKnownJSON}, {"Any with WKT", marshaler, anyWellKnown, anyWellKnownJSON},
{"Any with WKT and indent", marshalerAllOptions, anyWellKnown, anyWellKnownPrettyJSON}, {"Any with WKT and indent", marshalerAllOptions, anyWellKnown, anyWellKnownPrettyJSON},
{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}, `{"dur":"3s"}`}, {"Duration empty", marshaler, &durpb.Duration{}, `"0s"`},
{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3, Nanos: 1e6}}, `{"dur":"3.001s"}`}, {"Duration with secs", marshaler, &durpb.Duration{Seconds: 3}, `"3s"`},
{"Duration beyond float64 precision", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 100000000, Nanos: 1}}, `{"dur":"100000000.000000001s"}`}, {"Duration with -secs", marshaler, &durpb.Duration{Seconds: -3}, `"-3s"`},
{"negative Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: -123, Nanos: -456}}, `{"dur":"-123.000000456s"}`}, {"Duration with nanos", marshaler, &durpb.Duration{Nanos: 1e6}, `"0.001s"`},
{"Duration with -nanos", marshaler, &durpb.Duration{Nanos: -1e6}, `"-0.001s"`},
{"Duration with large secs", marshaler, &durpb.Duration{Seconds: 1e10, Nanos: 1}, `"10000000000.000000001s"`},
{"Duration with 6-digit nanos", marshaler, &durpb.Duration{Nanos: 1e4}, `"0.000010s"`},
{"Duration with 3-digit nanos", marshaler, &durpb.Duration{Nanos: 1e6}, `"0.001s"`},
{"Duration with -secs -nanos", marshaler, &durpb.Duration{Seconds: -123, Nanos: -450}, `"-123.000000450s"`},
{"Duration max value", marshaler, &durpb.Duration{Seconds: 315576000000, Nanos: 999999999}, `"315576000000.999999999s"`},
{"Duration min value", marshaler, &durpb.Duration{Seconds: -315576000000, Nanos: -999999999}, `"-315576000000.999999999s"`},
{"Struct", marshaler, &pb.KnownTypes{St: &stpb.Struct{ {"Struct", marshaler, &pb.KnownTypes{St: &stpb.Struct{
Fields: map[string]*stpb.Value{ Fields: map[string]*stpb.Value{
"one": {Kind: &stpb.Value_StringValue{"loneliest number"}}, "one": {Kind: &stpb.Value_StringValue{"loneliest number"}},
@@ -549,15 +556,17 @@ func TestMarshalIllegalTime(t *testing.T) {
pb proto.Message pb proto.Message
fail bool fail bool
}{ }{
{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: 1, Nanos: 0}}, false}, {&durpb.Duration{Seconds: 1, Nanos: 0}, false},
{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: -1, Nanos: 0}}, false}, {&durpb.Duration{Seconds: -1, Nanos: 0}, false},
{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: 1, Nanos: -1}}, true}, {&durpb.Duration{Seconds: 1, Nanos: -1}, true},
{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: -1, Nanos: 1}}, true}, {&durpb.Duration{Seconds: -1, Nanos: 1}, true},
{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: 1, Nanos: 1000000000}}, true}, {&durpb.Duration{Seconds: 315576000001}, true},
{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: -1, Nanos: -1000000000}}, true}, {&durpb.Duration{Seconds: -315576000001}, true},
{&pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 1, Nanos: 1}}, false}, {&durpb.Duration{Seconds: 1, Nanos: 1000000000}, true},
{&pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 1, Nanos: -1}}, true}, {&durpb.Duration{Seconds: -1, Nanos: -1000000000}, true},
{&pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 1, Nanos: 1000000000}}, true}, {&tspb.Timestamp{Seconds: 1, Nanos: 1}, false},
{&tspb.Timestamp{Seconds: 1, Nanos: -1}, true},
{&tspb.Timestamp{Seconds: 1, Nanos: 1000000000}, true},
} }
for _, tt := range tests { for _, tt := range tests {
_, err := marshaler.MarshalToString(tt.pb) _, err := marshaler.MarshalToString(tt.pb)
@@ -598,6 +607,28 @@ func TestMarshalAnyJSONPBMarshaler(t *testing.T) {
if str != expected { if str != expected {
t.Errorf("marshalling JSON produced incorrect output: got %s, wanted %s", str, expected) t.Errorf("marshalling JSON produced incorrect output: got %s, wanted %s", str, expected)
} }
// Do it again, but this time with indentation:
marshaler := Marshaler{Indent: " "}
str, err = marshaler.MarshalToString(a)
if err != nil {
t.Errorf("an unexpected error occurred when marshalling Any to JSON: %v", err)
}
// same as expected above, but pretty-printed w/ indentation
expected = `{
"@type": "type.googleapis.com/` + dynamicMessageName + `",
"baz": [
0,
1,
2,
3
],
"foo": "bar"
}`
if str != expected {
t.Errorf("marshalling JSON produced incorrect output: got %s, wanted %s", str, expected)
}
} }
func TestMarshalWithCustomValidation(t *testing.T) { func TestMarshalWithCustomValidation(t *testing.T) {

View File

@@ -38,7 +38,6 @@ package proto
import ( import (
"fmt" "fmt"
"log" "log"
"os"
"reflect" "reflect"
"sort" "sort"
"strconv" "strconv"
@@ -194,7 +193,7 @@ func (p *Properties) Parse(s string) {
// "bytes,49,opt,name=foo,def=hello!" // "bytes,49,opt,name=foo,def=hello!"
fields := strings.Split(s, ",") // breaks def=, but handled below. fields := strings.Split(s, ",") // breaks def=, but handled below.
if len(fields) < 2 { if len(fields) < 2 {
fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) log.Printf("proto: tag has too few fields: %q", s)
return return
} }
@@ -214,7 +213,7 @@ func (p *Properties) Parse(s string) {
p.WireType = WireBytes p.WireType = WireBytes
// no numeric converter for non-numeric types // no numeric converter for non-numeric types
default: default:
fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) log.Printf("proto: tag has unknown wire type: %q", s)
return return
} }

View File

@@ -54,6 +54,8 @@ const generatedCodeVersion = 4
const ( const (
contextPkgPath = "context" contextPkgPath = "context"
grpcPkgPath = "google.golang.org/grpc" grpcPkgPath = "google.golang.org/grpc"
codePkgPath = "google.golang.org/grpc/codes"
statusPkgPath = "google.golang.org/grpc/status"
) )
func init() { func init() {
@@ -216,6 +218,12 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
g.P("}") g.P("}")
g.P() g.P()
// Server Unimplemented struct for forward compatability.
if deprecated {
g.P(deprecationComment)
}
g.generateUnimplementedServer(servName, service)
// Server registration. // Server registration.
if deprecated { if deprecated {
g.P(deprecationComment) g.P(deprecationComment)
@@ -269,6 +277,35 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
g.P() g.P()
} }
// generateUnimplementedServer creates the unimplemented server struct
func (g *grpc) generateUnimplementedServer(servName string, service *pb.ServiceDescriptorProto) {
serverType := servName + "Server"
g.P("// Unimplemented", serverType, " can be embedded to have forward compatible implementations.")
g.P("type Unimplemented", serverType, " struct {")
g.P("}")
g.P()
// Unimplemented<service_name>Server's concrete methods
for _, method := range service.Method {
g.generateServerMethodConcrete(servName, method)
}
g.P()
}
// generateServerMethodConcrete returns unimplemented methods which ensure forward compatibility
func (g *grpc) generateServerMethodConcrete(servName string, method *pb.MethodDescriptorProto) {
header := g.generateServerSignatureWithParamNames(servName, method)
g.P("func (*Unimplemented", servName, "Server) ", header, " {")
var nilArg string
if !method.GetServerStreaming() && !method.GetClientStreaming() {
nilArg = "nil, "
}
methName := generator.CamelCase(method.GetName())
statusPkg := string(g.gen.AddImport(statusPkgPath))
codePkg := string(g.gen.AddImport(codePkgPath))
g.P("return ", nilArg, statusPkg, `.Errorf(`, codePkg, `.Unimplemented, "method `, methName, ` not implemented")`)
g.P("}")
}
// generateClientSignature returns the client-side signature for a method. // generateClientSignature returns the client-side signature for a method.
func (g *grpc) generateClientSignature(servName string, method *pb.MethodDescriptorProto) string { func (g *grpc) generateClientSignature(servName string, method *pb.MethodDescriptorProto) string {
origMethName := method.GetName() origMethName := method.GetName()
@@ -368,6 +405,30 @@ func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar strin
} }
} }
// generateServerSignatureWithParamNames returns the server-side signature for a method with parameter names.
func (g *grpc) generateServerSignatureWithParamNames(servName string, method *pb.MethodDescriptorProto) string {
origMethName := method.GetName()
methName := generator.CamelCase(origMethName)
if reservedClientName[methName] {
methName += "_"
}
var reqArgs []string
ret := "error"
if !method.GetServerStreaming() && !method.GetClientStreaming() {
reqArgs = append(reqArgs, "ctx "+contextPkg+".Context")
ret = "(*" + g.typeName(method.GetOutputType()) + ", error)"
}
if !method.GetClientStreaming() {
reqArgs = append(reqArgs, "req *"+g.typeName(method.GetInputType()))
}
if method.GetServerStreaming() || method.GetClientStreaming() {
reqArgs = append(reqArgs, "srv "+servName+"_"+generator.CamelCase(origMethName)+"Server")
}
return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret
}
// generateServerSignature returns the server-side signature for a method. // generateServerSignature returns the server-side signature for a method.
func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescriptorProto) string { func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescriptorProto) string {
origMethName := method.GetName() origMethName := method.GetName()

View File

@@ -10,6 +10,8 @@ import (
fmt "fmt" fmt "fmt"
proto "github.com/golang/protobuf/proto" proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math" math "math"
) )
@@ -235,6 +237,15 @@ type DeprecatedServiceServer interface {
DeprecatedCall(context.Context, *DeprecatedRequest) (*DeprecatedResponse, error) DeprecatedCall(context.Context, *DeprecatedRequest) (*DeprecatedResponse, error)
} }
// Deprecated: Do not use.
// UnimplementedDeprecatedServiceServer can be embedded to have forward compatible implementations.
type UnimplementedDeprecatedServiceServer struct {
}
func (*UnimplementedDeprecatedServiceServer) DeprecatedCall(ctx context.Context, req *DeprecatedRequest) (*DeprecatedResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeprecatedCall not implemented")
}
// Deprecated: Do not use. // Deprecated: Do not use.
func RegisterDeprecatedServiceServer(s *grpc.Server, srv DeprecatedServiceServer) { func RegisterDeprecatedServiceServer(s *grpc.Server, srv DeprecatedServiceServer) {
s.RegisterService(&_DeprecatedService_serviceDesc, srv) s.RegisterService(&_DeprecatedService_serviceDesc, srv)

View File

@@ -8,6 +8,8 @@ import (
fmt "fmt" fmt "fmt"
proto "github.com/golang/protobuf/proto" proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math" math "math"
) )
@@ -321,6 +323,23 @@ type TestServer interface {
Bidi(Test_BidiServer) error Bidi(Test_BidiServer) error
} }
// UnimplementedTestServer can be embedded to have forward compatible implementations.
type UnimplementedTestServer struct {
}
func (*UnimplementedTestServer) UnaryCall(ctx context.Context, req *SimpleRequest) (*SimpleResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented")
}
func (*UnimplementedTestServer) Downstream(req *SimpleRequest, srv Test_DownstreamServer) error {
return status.Errorf(codes.Unimplemented, "method Downstream not implemented")
}
func (*UnimplementedTestServer) Upstream(srv Test_UpstreamServer) error {
return status.Errorf(codes.Unimplemented, "method Upstream not implemented")
}
func (*UnimplementedTestServer) Bidi(srv Test_BidiServer) error {
return status.Errorf(codes.Unimplemented, "method Bidi not implemented")
}
func RegisterTestServer(s *grpc.Server, srv TestServer) { func RegisterTestServer(s *grpc.Server, srv TestServer) {
s.RegisterService(&_Test_serviceDesc, srv) s.RegisterService(&_Test_serviceDesc, srv)
} }

View File

@@ -0,0 +1,79 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: grpc/grpc_empty.proto
package testing
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
func init() { proto.RegisterFile("grpc/grpc_empty.proto", fileDescriptor_c580a37f1c90e9b1) }
var fileDescriptor_c580a37f1c90e9b1 = []byte{
// 125 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4d, 0x2f, 0x2a, 0x48,
0xd6, 0x07, 0x11, 0xf1, 0xa9, 0xb9, 0x05, 0x25, 0x95, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42,
0x3c, 0x20, 0x11, 0xbd, 0x92, 0xd4, 0xe2, 0x92, 0xcc, 0xbc, 0x74, 0x23, 0x3e, 0x2e, 0x1e, 0x57,
0x90, 0x64, 0x70, 0x6a, 0x51, 0x59, 0x66, 0x72, 0xaa, 0x93, 0x43, 0x94, 0x5d, 0x7a, 0x66, 0x49,
0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e, 0xba, 0x3e, 0x58,
0x63, 0x52, 0x69, 0x1a, 0x84, 0x91, 0xac, 0x9b, 0x9e, 0x9a, 0xa7, 0x9b, 0x9e, 0xaf, 0x0f, 0x32,
0x23, 0x25, 0xb1, 0x24, 0x11, 0x6c, 0x87, 0x35, 0xd4, 0xc4, 0x24, 0x36, 0xb0, 0x22, 0x63, 0x40,
0x00, 0x00, 0x00, 0xff, 0xff, 0x93, 0x1d, 0xf2, 0x47, 0x7f, 0x00, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// EmptyServiceClient is the client API for EmptyService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type EmptyServiceClient interface {
}
type emptyServiceClient struct {
cc *grpc.ClientConn
}
func NewEmptyServiceClient(cc *grpc.ClientConn) EmptyServiceClient {
return &emptyServiceClient{cc}
}
// EmptyServiceServer is the server API for EmptyService service.
type EmptyServiceServer interface {
}
// UnimplementedEmptyServiceServer can be embedded to have forward compatible implementations.
type UnimplementedEmptyServiceServer struct {
}
func RegisterEmptyServiceServer(s *grpc.Server, srv EmptyServiceServer) {
s.RegisterService(&_EmptyService_serviceDesc, srv)
}
var _EmptyService_serviceDesc = grpc.ServiceDesc{
ServiceName: "grpc.testing.EmptyService",
HandlerType: (*EmptyServiceServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{},
Metadata: "grpc/grpc_empty.proto",
}

View File

@@ -0,0 +1,38 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2019 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package grpc.testing;
option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/grpc;testing";
service EmptyService {}

View File

@@ -0,0 +1,47 @@
package test
import (
"bytes"
"encoding/json"
"testing"
jsoniter "github.com/json-iterator/go"
"github.com/stretchr/testify/require"
)
var marshalConfig = jsoniter.Config{
EscapeHTML: false,
SortMapKeys: true,
ValidateJsonRawMessage: true,
}.Froze()
type Container struct {
Bar interface{}
}
func (c *Container) MarshalJSON() ([]byte, error) {
return marshalConfig.Marshal(&c.Bar)
}
func TestEncodeEscape(t *testing.T) {
should := require.New(t)
container := &Container{
Bar: []string{"123<ab>", "ooo"},
}
out, err := marshalConfig.Marshal(container)
should.Nil(err)
bufout := string(out)
var stdbuf bytes.Buffer
stdenc := json.NewEncoder(&stdbuf)
stdenc.SetEscapeHTML(false)
err = stdenc.Encode(container)
should.Nil(err)
stdout := string(stdbuf.Bytes())
if stdout[len(stdout)-1:] == "\n" {
stdout = stdout[:len(stdout)-1]
}
should.Equal(stdout, bufout)
}

View File

@@ -74,6 +74,7 @@ type Iterator struct {
buf []byte buf []byte
head int head int
tail int tail int
depth int
captureStartedAt int captureStartedAt int
captured []byte captured []byte
Error error Error error
@@ -88,6 +89,7 @@ func NewIterator(cfg API) *Iterator {
buf: nil, buf: nil,
head: 0, head: 0,
tail: 0, tail: 0,
depth: 0,
} }
} }
@@ -99,6 +101,7 @@ func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
buf: make([]byte, bufSize), buf: make([]byte, bufSize),
head: 0, head: 0,
tail: 0, tail: 0,
depth: 0,
} }
} }
@@ -110,6 +113,7 @@ func ParseBytes(cfg API, input []byte) *Iterator {
buf: input, buf: input,
head: 0, head: 0,
tail: len(input), tail: len(input),
depth: 0,
} }
} }
@@ -128,6 +132,7 @@ func (iter *Iterator) Reset(reader io.Reader) *Iterator {
iter.reader = reader iter.reader = reader
iter.head = 0 iter.head = 0
iter.tail = 0 iter.tail = 0
iter.depth = 0
return iter return iter
} }
@@ -137,6 +142,7 @@ func (iter *Iterator) ResetBytes(input []byte) *Iterator {
iter.buf = input iter.buf = input
iter.head = 0 iter.head = 0
iter.tail = len(input) iter.tail = len(input)
iter.depth = 0
return iter return iter
} }
@@ -320,3 +326,24 @@ func (iter *Iterator) Read() interface{} {
return nil return nil
} }
} }
// limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9
const maxDepth = 10000
func (iter *Iterator) incrementDepth() (success bool) {
iter.depth++
if iter.depth <= maxDepth {
return true
}
iter.ReportError("incrementDepth", "exceeded max depth")
return false
}
func (iter *Iterator) decrementDepth() (success bool) {
iter.depth--
if iter.depth >= 0 {
return true
}
iter.ReportError("decrementDepth", "unexpected negative nesting")
return false
}

View File

@@ -28,26 +28,32 @@ func (iter *Iterator) ReadArray() (ret bool) {
func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
c := iter.nextToken() c := iter.nextToken()
if c == '[' { if c == '[' {
if !iter.incrementDepth() {
return false
}
c = iter.nextToken() c = iter.nextToken()
if c != ']' { if c != ']' {
iter.unreadByte() iter.unreadByte()
if !callback(iter) { if !callback(iter) {
iter.decrementDepth()
return false return false
} }
c = iter.nextToken() c = iter.nextToken()
for c == ',' { for c == ',' {
if !callback(iter) { if !callback(iter) {
iter.decrementDepth()
return false return false
} }
c = iter.nextToken() c = iter.nextToken()
} }
if c != ']' { if c != ']' {
iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c}))
iter.decrementDepth()
return false return false
} }
return true return iter.decrementDepth()
} }
return true return iter.decrementDepth()
} }
if c == 'n' { if c == 'n' {
iter.skipThreeBytes('u', 'l', 'l') iter.skipThreeBytes('u', 'l', 'l')

View File

@@ -112,6 +112,9 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
c := iter.nextToken() c := iter.nextToken()
var field string var field string
if c == '{' { if c == '{' {
if !iter.incrementDepth() {
return false
}
c = iter.nextToken() c = iter.nextToken()
if c == '"' { if c == '"' {
iter.unreadByte() iter.unreadByte()
@@ -121,6 +124,7 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
} }
if !callback(iter, field) { if !callback(iter, field) {
iter.decrementDepth()
return false return false
} }
c = iter.nextToken() c = iter.nextToken()
@@ -131,20 +135,23 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
} }
if !callback(iter, field) { if !callback(iter, field) {
iter.decrementDepth()
return false return false
} }
c = iter.nextToken() c = iter.nextToken()
} }
if c != '}' { if c != '}' {
iter.ReportError("ReadObjectCB", `object not ended with }`) iter.ReportError("ReadObjectCB", `object not ended with }`)
iter.decrementDepth()
return false return false
} }
return true return iter.decrementDepth()
} }
if c == '}' { if c == '}' {
return true return iter.decrementDepth()
} }
iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c})) iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c}))
iter.decrementDepth()
return false return false
} }
if c == 'n' { if c == 'n' {
@@ -159,15 +166,20 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
c := iter.nextToken() c := iter.nextToken()
if c == '{' { if c == '{' {
if !iter.incrementDepth() {
return false
}
c = iter.nextToken() c = iter.nextToken()
if c == '"' { if c == '"' {
iter.unreadByte() iter.unreadByte()
field := iter.ReadString() field := iter.ReadString()
if iter.nextToken() != ':' { if iter.nextToken() != ':' {
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
iter.decrementDepth()
return false return false
} }
if !callback(iter, field) { if !callback(iter, field) {
iter.decrementDepth()
return false return false
} }
c = iter.nextToken() c = iter.nextToken()
@@ -175,23 +187,27 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
field = iter.ReadString() field = iter.ReadString()
if iter.nextToken() != ':' { if iter.nextToken() != ':' {
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
iter.decrementDepth()
return false return false
} }
if !callback(iter, field) { if !callback(iter, field) {
iter.decrementDepth()
return false return false
} }
c = iter.nextToken() c = iter.nextToken()
} }
if c != '}' { if c != '}' {
iter.ReportError("ReadMapCB", `object not ended with }`) iter.ReportError("ReadMapCB", `object not ended with }`)
iter.decrementDepth()
return false return false
} }
return true return iter.decrementDepth()
} }
if c == '}' { if c == '}' {
return true return iter.decrementDepth()
} }
iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
iter.decrementDepth()
return false return false
} }
if c == 'n' { if c == 'n' {

View File

@@ -22,6 +22,9 @@ func (iter *Iterator) skipNumber() {
func (iter *Iterator) skipArray() { func (iter *Iterator) skipArray() {
level := 1 level := 1
if !iter.incrementDepth() {
return
}
for { for {
for i := iter.head; i < iter.tail; i++ { for i := iter.head; i < iter.tail; i++ {
switch iter.buf[i] { switch iter.buf[i] {
@@ -31,8 +34,14 @@ func (iter *Iterator) skipArray() {
i = iter.head - 1 // it will be i++ soon i = iter.head - 1 // it will be i++ soon
case '[': // If open symbol, increase level case '[': // If open symbol, increase level
level++ level++
if !iter.incrementDepth() {
return
}
case ']': // If close symbol, increase level case ']': // If close symbol, increase level
level-- level--
if !iter.decrementDepth() {
return
}
// If we have returned to the original level, we're done // If we have returned to the original level, we're done
if level == 0 { if level == 0 {
@@ -50,6 +59,10 @@ func (iter *Iterator) skipArray() {
func (iter *Iterator) skipObject() { func (iter *Iterator) skipObject() {
level := 1 level := 1
if !iter.incrementDepth() {
return
}
for { for {
for i := iter.head; i < iter.tail; i++ { for i := iter.head; i < iter.tail; i++ {
switch iter.buf[i] { switch iter.buf[i] {
@@ -59,8 +72,14 @@ func (iter *Iterator) skipObject() {
i = iter.head - 1 // it will be i++ soon i = iter.head - 1 // it will be i++ soon
case '{': // If open symbol, increase level case '{': // If open symbol, increase level
level++ level++
if !iter.incrementDepth() {
return
}
case '}': // If close symbol, increase level case '}': // If close symbol, increase level
level-- level--
if !iter.decrementDepth() {
return
}
// If we have returned to the original level, we're done // If we have returned to the original level, we're done
if level == 0 { if level == 0 {

View File

@@ -42,3 +42,11 @@ func Test_map_eface_of_eface(t *testing.T) {
should.NoError(err) should.NoError(err)
should.Equal(`{"1":2,"3":"4"}`, output) should.Equal(`{"1":2,"3":"4"}`, output)
} }
func Test_encode_nil_map(t *testing.T) {
should := require.New(t)
var nilMap map[string]string
output, err := jsoniter.MarshalToString(nilMap)
should.NoError(err)
should.Equal(`null`, output)
}

View File

@@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"github.com/json-iterator/go" "github.com/json-iterator/go"
"reflect" "reflect"
"strings"
"testing" "testing"
) )
@@ -15,6 +16,243 @@ type Level2 struct {
World string World string
} }
func Test_deep_nested(t *testing.T) {
type unstructured interface{}
testcases := []struct {
name string
data []byte
expectError string
}{
{
name: "array under maxDepth",
data: []byte(`{"a":` + strings.Repeat(`[`, 10000-1) + strings.Repeat(`]`, 10000-1) + `}`),
expectError: "",
},
{
name: "array over maxDepth",
data: []byte(`{"a":` + strings.Repeat(`[`, 10000) + strings.Repeat(`]`, 10000) + `}`),
expectError: "max depth",
},
{
name: "object under maxDepth",
data: []byte(`{"a":` + strings.Repeat(`{"a":`, 10000-1) + `0` + strings.Repeat(`}`, 10000-1) + `}`),
expectError: "",
},
{
name: "object over maxDepth",
data: []byte(`{"a":` + strings.Repeat(`{"a":`, 10000) + `0` + strings.Repeat(`}`, 10000) + `}`),
expectError: "max depth",
},
}
targets := []struct {
name string
new func() interface{}
}{
{
name: "unstructured",
new: func() interface{} {
var v interface{}
return &v
},
},
{
name: "typed named field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
}{}
return &v
},
},
{
name: "typed missing field",
new: func() interface{} {
v := struct {
B interface{} `json:"b"`
}{}
return &v
},
},
{
name: "typed 1 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
}{}
return &v
},
},
{
name: "typed 2 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
}{}
return &v
},
},
{
name: "typed 3 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
C interface{} `json:"c"`
}{}
return &v
},
},
{
name: "typed 4 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
C interface{} `json:"c"`
D interface{} `json:"d"`
}{}
return &v
},
},
{
name: "typed 5 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
C interface{} `json:"c"`
D interface{} `json:"d"`
E interface{} `json:"e"`
}{}
return &v
},
},
{
name: "typed 6 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
C interface{} `json:"c"`
D interface{} `json:"d"`
E interface{} `json:"e"`
F interface{} `json:"f"`
}{}
return &v
},
},
{
name: "typed 7 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
C interface{} `json:"c"`
D interface{} `json:"d"`
E interface{} `json:"e"`
F interface{} `json:"f"`
G interface{} `json:"g"`
}{}
return &v
},
},
{
name: "typed 8 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
C interface{} `json:"c"`
D interface{} `json:"d"`
E interface{} `json:"e"`
F interface{} `json:"f"`
G interface{} `json:"g"`
H interface{} `json:"h"`
}{}
return &v
},
},
{
name: "typed 9 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
C interface{} `json:"c"`
D interface{} `json:"d"`
E interface{} `json:"e"`
F interface{} `json:"f"`
G interface{} `json:"g"`
H interface{} `json:"h"`
I interface{} `json:"i"`
}{}
return &v
},
},
{
name: "typed 10 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
C interface{} `json:"c"`
D interface{} `json:"d"`
E interface{} `json:"e"`
F interface{} `json:"f"`
G interface{} `json:"g"`
H interface{} `json:"h"`
I interface{} `json:"i"`
J interface{} `json:"j"`
}{}
return &v
},
},
{
name: "typed 11 field",
new: func() interface{} {
v := struct {
A interface{} `json:"a"`
B interface{} `json:"b"`
C interface{} `json:"c"`
D interface{} `json:"d"`
E interface{} `json:"e"`
F interface{} `json:"f"`
G interface{} `json:"g"`
H interface{} `json:"h"`
I interface{} `json:"i"`
J interface{} `json:"j"`
K interface{} `json:"k"`
}{}
return &v
},
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
for _, target := range targets {
t.Run(target.name, func(t *testing.T) {
err := jsoniter.Unmarshal(tc.data, target.new())
if len(tc.expectError) == 0 {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
} else {
if err == nil {
t.Errorf("expected error, got none")
} else if !strings.Contains(err.Error(), tc.expectError) {
t.Errorf("expected error containing '%s', got: %v", tc.expectError, err)
}
}
})
}
})
}
}
func Test_nested(t *testing.T) { func Test_nested(t *testing.T) {
iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{"hello": [{"world": "value1"}, {"world": "value2"}]}`) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{"hello": [{"world": "value1"}, {"world": "value2"}]}`)
l1 := Level1{} l1 := Level1{}

View File

@@ -60,6 +60,7 @@ func (b *ctx) append(prefix string) *ctx {
// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal // ReadVal copy the underlying JSON into go interface, same as json.Unmarshal
func (iter *Iterator) ReadVal(obj interface{}) { func (iter *Iterator) ReadVal(obj interface{}) {
depth := iter.depth
cacheKey := reflect2.RTypeOf(obj) cacheKey := reflect2.RTypeOf(obj)
decoder := iter.cfg.getDecoderFromCache(cacheKey) decoder := iter.cfg.getDecoderFromCache(cacheKey)
if decoder == nil { if decoder == nil {
@@ -76,6 +77,10 @@ func (iter *Iterator) ReadVal(obj interface{}) {
return return
} }
decoder.Decode(ptr, iter) decoder.Decode(ptr, iter)
if iter.depth != depth {
iter.ReportError("ReadVal", "unexpected mismatched nesting")
return
}
} }
// WriteVal copy the go interface into underlying JSON, same as json.Marshal // WriteVal copy the go interface into underlying JSON, same as json.Marshal

View File

@@ -341,10 +341,10 @@ func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {
if ctx.onlyTaggedField && !hastag && !field.Anonymous() { if ctx.onlyTaggedField && !hastag && !field.Anonymous() {
continue continue
} }
tagParts := strings.Split(tag, ",")
if tag == "-" { if tag == "-" {
continue continue
} }
tagParts := strings.Split(tag, ",")
if field.Anonymous() && (tag == "" || tagParts[0] == "") { if field.Anonymous() && (tag == "" || tagParts[0] == "") {
if field.Type().Kind() == reflect.Struct { if field.Type().Kind() == reflect.Struct {
structDescriptor := describeStruct(ctx, field.Type()) structDescriptor := describeStruct(ctx, field.Type())

View File

@@ -249,6 +249,10 @@ type mapEncoder struct {
} }
func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if *(*unsafe.Pointer)(ptr) == nil {
stream.WriteNil()
return
}
stream.WriteObjectStart() stream.WriteObjectStart()
iter := encoder.mapType.UnsafeIterate(ptr) iter := encoder.mapType.UnsafeIterate(ptr)
for i := 0; iter.HasNext(); i++ { for i := 0; iter.HasNext(); i++ {

View File

@@ -3,8 +3,9 @@ package jsoniter
import ( import (
"encoding" "encoding"
"encoding/json" "encoding/json"
"github.com/modern-go/reflect2"
"unsafe" "unsafe"
"github.com/modern-go/reflect2"
) )
var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem() var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem()
@@ -93,10 +94,17 @@ func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteNil() stream.WriteNil()
return return
} }
bytes, err := json.Marshal(obj) marshaler := obj.(json.Marshaler)
bytes, err := marshaler.MarshalJSON()
if err != nil { if err != nil {
stream.Error = err stream.Error = err
} else { } else {
// html escape was already done by jsoniter
// but the extra '\n' should be trimed
l := len(bytes)
if l > 0 && bytes[l-1] == '\n' {
bytes = bytes[:l-1]
}
stream.Write(bytes) stream.Write(bytes)
} }
} }

View File

@@ -500,6 +500,9 @@ func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
var c byte var c byte
for c = ','; c == ','; c = iter.nextToken() { for c = ','; c == ','; c = iter.nextToken() {
decoder.decodeOneField(ptr, iter) decoder.decodeOneField(ptr, iter)
@@ -510,6 +513,7 @@ func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
if c != '}' { if c != '}' {
iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c})) iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c}))
} }
iter.decrementDepth()
} }
func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) { func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) {
@@ -571,6 +575,9 @@ func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
if iter.readFieldHash() == decoder.fieldHash { if iter.readFieldHash() == decoder.fieldHash {
decoder.fieldDecoder.Decode(ptr, iter) decoder.fieldDecoder.Decode(ptr, iter)
@@ -584,6 +591,7 @@ func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type twoFieldsStructDecoder struct { type twoFieldsStructDecoder struct {
@@ -598,6 +606,9 @@ func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
switch iter.readFieldHash() { switch iter.readFieldHash() {
case decoder.fieldHash1: case decoder.fieldHash1:
@@ -614,6 +625,7 @@ func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type threeFieldsStructDecoder struct { type threeFieldsStructDecoder struct {
@@ -630,6 +642,9 @@ func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
switch iter.readFieldHash() { switch iter.readFieldHash() {
case decoder.fieldHash1: case decoder.fieldHash1:
@@ -648,6 +663,7 @@ func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type fourFieldsStructDecoder struct { type fourFieldsStructDecoder struct {
@@ -666,6 +682,9 @@ func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
switch iter.readFieldHash() { switch iter.readFieldHash() {
case decoder.fieldHash1: case decoder.fieldHash1:
@@ -686,6 +705,7 @@ func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type fiveFieldsStructDecoder struct { type fiveFieldsStructDecoder struct {
@@ -706,6 +726,9 @@ func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
switch iter.readFieldHash() { switch iter.readFieldHash() {
case decoder.fieldHash1: case decoder.fieldHash1:
@@ -728,6 +751,7 @@ func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type sixFieldsStructDecoder struct { type sixFieldsStructDecoder struct {
@@ -750,6 +774,9 @@ func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
switch iter.readFieldHash() { switch iter.readFieldHash() {
case decoder.fieldHash1: case decoder.fieldHash1:
@@ -774,6 +801,7 @@ func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type sevenFieldsStructDecoder struct { type sevenFieldsStructDecoder struct {
@@ -798,6 +826,9 @@ func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
switch iter.readFieldHash() { switch iter.readFieldHash() {
case decoder.fieldHash1: case decoder.fieldHash1:
@@ -824,6 +855,7 @@ func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type eightFieldsStructDecoder struct { type eightFieldsStructDecoder struct {
@@ -850,6 +882,9 @@ func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
switch iter.readFieldHash() { switch iter.readFieldHash() {
case decoder.fieldHash1: case decoder.fieldHash1:
@@ -878,6 +913,7 @@ func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type nineFieldsStructDecoder struct { type nineFieldsStructDecoder struct {
@@ -906,6 +942,9 @@ func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
switch iter.readFieldHash() { switch iter.readFieldHash() {
case decoder.fieldHash1: case decoder.fieldHash1:
@@ -936,6 +975,7 @@ func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type tenFieldsStructDecoder struct { type tenFieldsStructDecoder struct {
@@ -966,6 +1006,9 @@ func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
if !iter.incrementDepth() {
return
}
for { for {
switch iter.readFieldHash() { switch iter.readFieldHash() {
case decoder.fieldHash1: case decoder.fieldHash1:
@@ -998,6 +1041,7 @@ func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
} }
iter.decrementDepth()
} }
type structFieldDecoder struct { type structFieldDecoder struct {

View File

@@ -77,6 +77,10 @@ const (
type Client struct { type Client struct {
// Key is the account key used to register with a CA and sign requests. // Key is the account key used to register with a CA and sign requests.
// Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey. // Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
//
// The following algorithms are supported:
// RS256, ES256, ES384 and ES512.
// See RFC7518 for more details about the algorithms.
Key crypto.Signer Key crypto.Signer
// HTTPClient optionally specifies an HTTP client to use // HTTPClient optionally specifies an HTTP client to use
@@ -105,6 +109,13 @@ type Client struct {
// The jitter is a random value up to 1 second. // The jitter is a random value up to 1 second.
RetryBackoff func(n int, r *http.Request, resp *http.Response) time.Duration RetryBackoff func(n int, r *http.Request, resp *http.Response) time.Duration
// UserAgent is prepended to the User-Agent header sent to the ACME server,
// which by default is this package's name and version.
//
// Reusable libraries and tools in particular should set this value to be
// identifiable by the server, in case they are causing issues.
UserAgent string
dirMu sync.Mutex // guards writes to dir dirMu sync.Mutex // guards writes to dir
dir *Directory // cached result of Client's Discover method dir *Directory // cached result of Client's Discover method
@@ -124,11 +135,7 @@ func (c *Client) Discover(ctx context.Context) (Directory, error) {
return *c.dir, nil return *c.dir, nil
} }
dirURL := c.DirectoryURL res, err := c.get(ctx, c.directoryURL(), wantStatus(http.StatusOK))
if dirURL == "" {
dirURL = LetsEncryptURL
}
res, err := c.get(ctx, dirURL, wantStatus(http.StatusOK))
if err != nil { if err != nil {
return Directory{}, err return Directory{}, err
} }
@@ -161,6 +168,13 @@ func (c *Client) Discover(ctx context.Context) (Directory, error) {
return *c.dir, nil return *c.dir, nil
} }
func (c *Client) directoryURL() string {
if c.DirectoryURL != "" {
return c.DirectoryURL
}
return LetsEncryptURL
}
// CreateCert requests a new certificate using the Certificate Signing Request csr encoded in DER format. // CreateCert requests a new certificate using the Certificate Signing Request csr encoded in DER format.
// The exp argument indicates the desired certificate validity duration. CA may issue a certificate // The exp argument indicates the desired certificate validity duration. CA may issue a certificate
// with a different duration. // with a different duration.
@@ -319,6 +333,20 @@ func (c *Client) UpdateReg(ctx context.Context, a *Account) (*Account, error) {
// a valid authorization (Authorization.Status is StatusValid). If so, the caller // a valid authorization (Authorization.Status is StatusValid). If so, the caller
// need not fulfill any challenge and can proceed to requesting a certificate. // need not fulfill any challenge and can proceed to requesting a certificate.
func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) { func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) {
return c.authorize(ctx, "dns", domain)
}
// AuthorizeIP is the same as Authorize but requests IP address authorization.
// Clients which successfully obtain such authorization may request to issue
// a certificate for IP addresses.
//
// See the ACME spec extension for more details about IP address identifiers:
// https://tools.ietf.org/html/draft-ietf-acme-ip.
func (c *Client) AuthorizeIP(ctx context.Context, ipaddr string) (*Authorization, error) {
return c.authorize(ctx, "ip", ipaddr)
}
func (c *Client) authorize(ctx context.Context, typ, val string) (*Authorization, error) {
if _, err := c.Discover(ctx); err != nil { if _, err := c.Discover(ctx); err != nil {
return nil, err return nil, err
} }
@@ -332,7 +360,7 @@ func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization,
Identifier authzID `json:"identifier"` Identifier authzID `json:"identifier"`
}{ }{
Resource: "new-authz", Resource: "new-authz",
Identifier: authzID{Type: "dns", Value: domain}, Identifier: authzID{Type: typ, Value: val},
} }
res, err := c.post(ctx, c.Key, c.dir.AuthzURL, req, wantStatus(http.StatusCreated)) res, err := c.post(ctx, c.Key, c.dir.AuthzURL, req, wantStatus(http.StatusCreated))
if err != nil { if err != nil {
@@ -693,12 +721,18 @@ func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Accoun
} }
// popNonce returns a nonce value previously stored with c.addNonce // popNonce returns a nonce value previously stored with c.addNonce
// or fetches a fresh one from the given URL. // or fetches a fresh one from a URL by issuing a HEAD request.
// It first tries c.directoryURL() and then the provided url if the former fails.
func (c *Client) popNonce(ctx context.Context, url string) (string, error) { func (c *Client) popNonce(ctx context.Context, url string) (string, error) {
c.noncesMu.Lock() c.noncesMu.Lock()
defer c.noncesMu.Unlock() defer c.noncesMu.Unlock()
if len(c.nonces) == 0 { if len(c.nonces) == 0 {
return c.fetchNonce(ctx, url) dirURL := c.directoryURL()
v, err := c.fetchNonce(ctx, dirURL)
if err != nil && url != dirURL {
v, err = c.fetchNonce(ctx, url)
}
return v, err
} }
var nonce string var nonce string
for nonce = range c.nonces { for nonce = range c.nonces {

View File

@@ -75,6 +75,7 @@ func TestDiscover(t *testing.T) {
) )
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Header().Set("Replay-Nonce", "testnonce")
fmt.Fprintf(w, `{ fmt.Fprintf(w, `{
"new-reg": %q, "new-reg": %q,
"new-authz": %q, "new-authz": %q,
@@ -100,6 +101,9 @@ func TestDiscover(t *testing.T) {
if dir.RevokeURL != revoke { if dir.RevokeURL != revoke {
t.Errorf("dir.RevokeURL = %q; want %q", dir.RevokeURL, revoke) t.Errorf("dir.RevokeURL = %q; want %q", dir.RevokeURL, revoke)
} }
if _, exist := c.nonces["testnonce"]; !exist {
t.Errorf("c.nonces = %q; want 'testnonce' in the map", c.nonces)
}
} }
func TestRegister(t *testing.T) { func TestRegister(t *testing.T) {
@@ -147,7 +151,11 @@ func TestRegister(t *testing.T) {
return false return false
} }
c := Client{Key: testKeyEC, dir: &Directory{RegURL: ts.URL}} c := Client{
Key: testKeyEC,
DirectoryURL: ts.URL,
dir: &Directory{RegURL: ts.URL},
}
a := &Account{Contact: contacts} a := &Account{Contact: contacts}
var err error var err error
if a, err = c.Register(context.Background(), a, prompt); err != nil { if a, err = c.Register(context.Background(), a, prompt); err != nil {
@@ -288,106 +296,131 @@ func TestGetReg(t *testing.T) {
} }
func TestAuthorize(t *testing.T) { func TestAuthorize(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { tt := []struct{ typ, value string }{
if r.Method == "HEAD" { {"dns", "example.com"},
w.Header().Set("Replay-Nonce", "test-nonce") {"ip", "1.2.3.4"},
return }
} for _, test := range tt {
if r.Method != "POST" { t.Run(test.typ, func(t *testing.T) {
t.Errorf("r.Method = %q; want POST", r.Method) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
} if r.Method == "HEAD" {
w.Header().Set("Replay-Nonce", "test-nonce")
var j struct { return
Resource string }
Identifier struct { if r.Method != "POST" {
Type string t.Errorf("r.Method = %q; want POST", r.Method)
Value string
}
}
decodeJWSRequest(t, &j, r)
// Test request
if j.Resource != "new-authz" {
t.Errorf("j.Resource = %q; want new-authz", j.Resource)
}
if j.Identifier.Type != "dns" {
t.Errorf("j.Identifier.Type = %q; want dns", j.Identifier.Type)
}
if j.Identifier.Value != "example.com" {
t.Errorf("j.Identifier.Value = %q; want example.com", j.Identifier.Value)
}
w.Header().Set("Location", "https://ca.tld/acme/auth/1")
w.WriteHeader(http.StatusCreated)
fmt.Fprintf(w, `{
"identifier": {"type":"dns","value":"example.com"},
"status":"pending",
"challenges":[
{
"type":"http-01",
"status":"pending",
"uri":"https://ca.tld/acme/challenge/publickey/id1",
"token":"token1"
},
{
"type":"tls-sni-01",
"status":"pending",
"uri":"https://ca.tld/acme/challenge/publickey/id2",
"token":"token2"
} }
],
"combinations":[[0],[1]]}`)
}))
defer ts.Close()
cl := Client{Key: testKeyEC, dir: &Directory{AuthzURL: ts.URL}} var j struct {
auth, err := cl.Authorize(context.Background(), "example.com") Resource string
if err != nil { Identifier struct {
t.Fatal(err) Type string
} Value string
}
}
decodeJWSRequest(t, &j, r)
if auth.URI != "https://ca.tld/acme/auth/1" { // Test request
t.Errorf("URI = %q; want https://ca.tld/acme/auth/1", auth.URI) if j.Resource != "new-authz" {
} t.Errorf("j.Resource = %q; want new-authz", j.Resource)
if auth.Status != "pending" { }
t.Errorf("Status = %q; want pending", auth.Status) if j.Identifier.Type != test.typ {
} t.Errorf("j.Identifier.Type = %q; want %q", j.Identifier.Type, test.typ)
if auth.Identifier.Type != "dns" { }
t.Errorf("Identifier.Type = %q; want dns", auth.Identifier.Type) if j.Identifier.Value != test.value {
} t.Errorf("j.Identifier.Value = %q; want %q", j.Identifier.Value, test.value)
if auth.Identifier.Value != "example.com" { }
t.Errorf("Identifier.Value = %q; want example.com", auth.Identifier.Value)
}
if n := len(auth.Challenges); n != 2 { w.Header().Set("Location", "https://ca.tld/acme/auth/1")
t.Fatalf("len(auth.Challenges) = %d; want 2", n) w.WriteHeader(http.StatusCreated)
} fmt.Fprintf(w, `{
"identifier": {"type":%q,"value":%q},
"status":"pending",
"challenges":[
{
"type":"http-01",
"status":"pending",
"uri":"https://ca.tld/acme/challenge/publickey/id1",
"token":"token1"
},
{
"type":"tls-sni-01",
"status":"pending",
"uri":"https://ca.tld/acme/challenge/publickey/id2",
"token":"token2"
}
],
"combinations":[[0],[1]]
}`, test.typ, test.value)
}))
defer ts.Close()
c := auth.Challenges[0] var (
if c.Type != "http-01" { auth *Authorization
t.Errorf("c.Type = %q; want http-01", c.Type) err error
} )
if c.URI != "https://ca.tld/acme/challenge/publickey/id1" { cl := Client{
t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", c.URI) Key: testKeyEC,
} DirectoryURL: ts.URL,
if c.Token != "token1" { dir: &Directory{AuthzURL: ts.URL},
t.Errorf("c.Token = %q; want token1", c.Token) }
} switch test.typ {
case "dns":
auth, err = cl.Authorize(context.Background(), test.value)
case "ip":
auth, err = cl.AuthorizeIP(context.Background(), test.value)
default:
t.Fatalf("unknown identifier type: %q", test.typ)
}
if err != nil {
t.Fatal(err)
}
c = auth.Challenges[1] if auth.URI != "https://ca.tld/acme/auth/1" {
if c.Type != "tls-sni-01" { t.Errorf("URI = %q; want https://ca.tld/acme/auth/1", auth.URI)
t.Errorf("c.Type = %q; want tls-sni-01", c.Type) }
} if auth.Status != "pending" {
if c.URI != "https://ca.tld/acme/challenge/publickey/id2" { t.Errorf("Status = %q; want pending", auth.Status)
t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id2", c.URI) }
} if auth.Identifier.Type != test.typ {
if c.Token != "token2" { t.Errorf("Identifier.Type = %q; want %q", auth.Identifier.Type, test.typ)
t.Errorf("c.Token = %q; want token2", c.Token) }
} if auth.Identifier.Value != test.value {
t.Errorf("Identifier.Value = %q; want %q", auth.Identifier.Value, test.value)
}
combs := [][]int{{0}, {1}} if n := len(auth.Challenges); n != 2 {
if !reflect.DeepEqual(auth.Combinations, combs) { t.Fatalf("len(auth.Challenges) = %d; want 2", n)
t.Errorf("auth.Combinations: %+v\nwant: %+v\n", auth.Combinations, combs) }
c := auth.Challenges[0]
if c.Type != "http-01" {
t.Errorf("c.Type = %q; want http-01", c.Type)
}
if c.URI != "https://ca.tld/acme/challenge/publickey/id1" {
t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", c.URI)
}
if c.Token != "token1" {
t.Errorf("c.Token = %q; want token1", c.Token)
}
c = auth.Challenges[1]
if c.Type != "tls-sni-01" {
t.Errorf("c.Type = %q; want tls-sni-01", c.Type)
}
if c.URI != "https://ca.tld/acme/challenge/publickey/id2" {
t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id2", c.URI)
}
if c.Token != "token2" {
t.Errorf("c.Token = %q; want token2", c.Token)
}
combs := [][]int{{0}, {1}}
if !reflect.DeepEqual(auth.Combinations, combs) {
t.Errorf("auth.Combinations: %+v\nwant: %+v\n", auth.Combinations, combs)
}
})
} }
} }
@@ -401,7 +434,11 @@ func TestAuthorizeValid(t *testing.T) {
w.Write([]byte(`{"status":"valid"}`)) w.Write([]byte(`{"status":"valid"}`))
})) }))
defer ts.Close() defer ts.Close()
client := Client{Key: testKey, dir: &Directory{AuthzURL: ts.URL}} client := Client{
Key: testKey,
DirectoryURL: ts.URL,
dir: &Directory{AuthzURL: ts.URL},
}
_, err := client.Authorize(context.Background(), "example.com") _, err := client.Authorize(context.Background(), "example.com")
if err != nil { if err != nil {
t.Errorf("err = %v", err) t.Errorf("err = %v", err)
@@ -1016,6 +1053,53 @@ func TestNonce_fetchError(t *testing.T) {
} }
} }
func TestNonce_popWhenEmpty(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "HEAD" {
t.Errorf("r.Method = %q; want HEAD", r.Method)
}
switch r.URL.Path {
case "/dir-with-nonce":
w.Header().Set("Replay-Nonce", "dirnonce")
case "/new-nonce":
w.Header().Set("Replay-Nonce", "newnonce")
case "/dir-no-nonce", "/empty":
// No nonce in the header.
default:
t.Errorf("Unknown URL: %s", r.URL)
}
}))
defer ts.Close()
ctx := context.Background()
tt := []struct {
dirURL, popURL, nonce string
wantOK bool
}{
{ts.URL + "/dir-with-nonce", ts.URL + "/new-nonce", "dirnonce", true},
{ts.URL + "/dir-no-nonce", ts.URL + "/new-nonce", "newnonce", true},
{ts.URL + "/dir-no-nonce", ts.URL + "/empty", "", false},
}
for _, test := range tt {
t.Run(fmt.Sprintf("nonce:%s wantOK:%v", test.nonce, test.wantOK), func(t *testing.T) {
c := Client{DirectoryURL: test.dirURL}
v, err := c.popNonce(ctx, test.popURL)
if !test.wantOK {
if err == nil {
t.Fatalf("c.popNonce(%q) returned nil error", test.popURL)
}
return
}
if err != nil {
t.Fatalf("c.popNonce(%q): %v", test.popURL, err)
}
if v != test.nonce {
t.Errorf("c.popNonce(%q) = %q; want %q", test.popURL, v, test.nonce)
}
})
}
}
func TestNonce_postJWS(t *testing.T) { func TestNonce_postJWS(t *testing.T) {
var count int var count int
seen := make(map[string]bool) seen := make(map[string]bool)
@@ -1049,7 +1133,11 @@ func TestNonce_postJWS(t *testing.T) {
})) }))
defer ts.Close() defer ts.Close()
client := Client{Key: testKey, dir: &Directory{AuthzURL: ts.URL}} client := Client{
Key: testKey,
DirectoryURL: ts.URL, // nonces are fetched from here first
dir: &Directory{AuthzURL: ts.URL},
}
if _, err := client.Authorize(context.Background(), "example.com"); err != nil { if _, err := client.Authorize(context.Background(), "example.com"); err != nil {
t.Errorf("client.Authorize 1: %v", err) t.Errorf("client.Authorize 1: %v", err)
} }

View File

@@ -32,6 +32,7 @@ import (
"time" "time"
"golang.org/x/crypto/acme" "golang.org/x/crypto/acme"
"golang.org/x/net/idna"
) )
// createCertRetryAfter is how much time to wait before removing a failed state // createCertRetryAfter is how much time to wait before removing a failed state
@@ -62,10 +63,16 @@ type HostPolicy func(ctx context.Context, host string) error
// HostWhitelist returns a policy where only the specified host names are allowed. // HostWhitelist returns a policy where only the specified host names are allowed.
// Only exact matches are currently supported. Subdomains, regexp or wildcard // Only exact matches are currently supported. Subdomains, regexp or wildcard
// will not match. // will not match.
//
// Note that all hosts will be converted to Punycode via idna.Lookup.ToASCII so that
// Manager.GetCertificate can handle the Unicode IDN and mixedcase hosts correctly.
// Invalid hosts will be silently ignored.
func HostWhitelist(hosts ...string) HostPolicy { func HostWhitelist(hosts ...string) HostPolicy {
whitelist := make(map[string]bool, len(hosts)) whitelist := make(map[string]bool, len(hosts))
for _, h := range hosts { for _, h := range hosts {
whitelist[h] = true if h, err := idna.Lookup.ToASCII(h); err == nil {
whitelist[h] = true
}
} }
return func(_ context.Context, host string) error { return func(_ context.Context, host string) error {
if !whitelist[host] { if !whitelist[host] {
@@ -243,7 +250,17 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
if !strings.Contains(strings.Trim(name, "."), ".") { if !strings.Contains(strings.Trim(name, "."), ".") {
return nil, errors.New("acme/autocert: server name component count invalid") return nil, errors.New("acme/autocert: server name component count invalid")
} }
if strings.ContainsAny(name, `+/\`) {
// Note that this conversion is necessary because some server names in the handshakes
// started by some clients (such as cURL) are not converted to Punycode, which will
// prevent us from obtaining certificates for them. In addition, we should also treat
// example.com and EXAMPLE.COM as equivalent and return the same certificate for them.
// Fortunately, this conversion also helped us deal with this kind of mixedcase problems.
//
// Due to the "σςΣ" problem (see https://unicode.org/faq/idn.html#22), we can't use
// idna.Punycode.ToASCII (or just idna.ToASCII) here.
name, err := idna.Lookup.ToASCII(name)
if err != nil {
return nil, errors.New("acme/autocert: server name contains invalid character") return nil, errors.New("acme/autocert: server name contains invalid character")
} }
@@ -963,6 +980,9 @@ func (m *Manager) acmeClient(ctx context.Context) (*acme.Client, error) {
return nil, err return nil, err
} }
} }
if client.UserAgent == "" {
client.UserAgent = "autocert"
}
var contact []string var contact []string
if m.Email != "" { if m.Email != "" {
contact = []string{"mailto:" + m.Email} contact = []string{"mailto:" + m.Email}

View File

@@ -209,6 +209,28 @@ func TestGetCertificate_trailingDot(t *testing.T) {
testGetCertificate(t, man, "example.org", hello) testGetCertificate(t, man, "example.org", hello)
} }
func TestGetCertificate_unicodeIDN(t *testing.T) {
man := &Manager{Prompt: AcceptTOS}
defer man.stopRenew()
hello := clientHelloInfo("σσσ.com", true)
testGetCertificate(t, man, "xn--4xaaa.com", hello)
hello = clientHelloInfo("σςΣ.com", true)
testGetCertificate(t, man, "xn--4xaaa.com", hello)
}
func TestGetCertificate_mixedcase(t *testing.T) {
man := &Manager{Prompt: AcceptTOS}
defer man.stopRenew()
hello := clientHelloInfo("example.org", true)
testGetCertificate(t, man, "example.org", hello)
hello = clientHelloInfo("EXAMPLE.ORG", true)
testGetCertificate(t, man, "example.org", hello)
}
func TestGetCertificate_ForceRSA(t *testing.T) { func TestGetCertificate_ForceRSA(t *testing.T) {
man := &Manager{ man := &Manager{
Prompt: AcceptTOS, Prompt: AcceptTOS,
@@ -906,13 +928,14 @@ func TestCache(t *testing.T) {
} }
func TestHostWhitelist(t *testing.T) { func TestHostWhitelist(t *testing.T) {
policy := HostWhitelist("example.com", "example.org", "*.example.net") policy := HostWhitelist("example.com", "EXAMPLE.ORG", "*.example.net", "σςΣ.com")
tt := []struct { tt := []struct {
host string host string
allow bool allow bool
}{ }{
{"example.com", true}, {"example.com", true},
{"example.org", true}, {"example.org", true},
{"xn--4xaaa.com", true},
{"one.example.com", false}, {"one.example.com", false},
{"two.example.org", false}, {"two.example.org", false},
{"three.example.net", false}, {"three.example.net", false},

View File

@@ -77,6 +77,7 @@ func (d DirCache) Put(ctx context.Context, name string, data []byte) error {
if tmp, err = d.writeTempFile(name, data); err != nil { if tmp, err = d.writeTempFile(name, data); err != nil {
return return
} }
defer os.Remove(tmp)
select { select {
case <-ctx.Done(): case <-ctx.Done():
// Don't overwrite the file if the context was canceled. // Don't overwrite the file if the context was canceled.
@@ -116,12 +117,17 @@ func (d DirCache) Delete(ctx context.Context, name string) error {
} }
// writeTempFile writes b to a temporary file, closes the file and returns its path. // writeTempFile writes b to a temporary file, closes the file and returns its path.
func (d DirCache) writeTempFile(prefix string, b []byte) (string, error) { func (d DirCache) writeTempFile(prefix string, b []byte) (name string, reterr error) {
// TempFile uses 0600 permissions // TempFile uses 0600 permissions
f, err := ioutil.TempFile(string(d), prefix) f, err := ioutil.TempFile(string(d), prefix)
if err != nil { if err != nil {
return "", err return "", err
} }
defer func() {
if reterr != nil {
os.Remove(f.Name())
}
}()
if _, err := f.Write(b); err != nil { if _, err := f.Write(b); err != nil {
f.Close() f.Close()
return "", err return "", err

View File

@@ -48,6 +48,15 @@ func TestDirCache(t *testing.T) {
t.Error(err) t.Error(err)
} }
// test put deletes temp file
tmp, err := filepath.Glob(name + "?*")
if err != nil {
t.Error(err)
}
if tmp != nil {
t.Errorf("temp file exists: %s", tmp)
}
// test delete // test delete
if err := cache.Delete(ctx, "dummy"); err != nil { if err := cache.Delete(ctx, "dummy"); err != nil {
t.Fatalf("delete: %v", err) t.Fatalf("delete: %v", err)

View File

@@ -219,6 +219,7 @@ func (c *Client) postNoRetry(ctx context.Context, key crypto.Signer, url string,
// doNoRetry issues a request req, replacing its context (if any) with ctx. // doNoRetry issues a request req, replacing its context (if any) with ctx.
func (c *Client) doNoRetry(ctx context.Context, req *http.Request) (*http.Response, error) { func (c *Client) doNoRetry(ctx context.Context, req *http.Request) (*http.Response, error) {
req.Header.Set("User-Agent", c.userAgent())
res, err := c.httpClient().Do(req.WithContext(ctx)) res, err := c.httpClient().Do(req.WithContext(ctx))
if err != nil { if err != nil {
select { select {
@@ -243,6 +244,23 @@ func (c *Client) httpClient() *http.Client {
return http.DefaultClient return http.DefaultClient
} }
// packageVersion is the version of the module that contains this package, for
// sending as part of the User-Agent header. It's set in version_go112.go.
var packageVersion string
// userAgent returns the User-Agent header value. It includes the package name,
// the module version (if available), and the c.UserAgent value (if set).
func (c *Client) userAgent() string {
ua := "golang.org/x/crypto/acme"
if packageVersion != "" {
ua += "@" + packageVersion
}
if c.UserAgent != "" {
ua = c.UserAgent + " " + ua
}
return ua
}
// isBadNonce reports whether err is an ACME "badnonce" error. // isBadNonce reports whether err is an ACME "badnonce" error.
func isBadNonce(err error) bool { func isBadNonce(err error) bool {
// According to the spec badNonce is urn:ietf:params:acme:error:badNonce. // According to the spec badNonce is urn:ietf:params:acme:error:badNonce.

View File

@@ -106,7 +106,11 @@ func TestPostWithRetries(t *testing.T) {
})) }))
defer ts.Close() defer ts.Close()
client := &Client{Key: testKey, dir: &Directory{AuthzURL: ts.URL}} client := &Client{
Key: testKey,
DirectoryURL: ts.URL,
dir: &Directory{AuthzURL: ts.URL},
}
// This call will fail with badNonce, causing a retry // This call will fail with badNonce, causing a retry
if _, err := client.Authorize(context.Background(), "example.com"); err != nil { if _, err := client.Authorize(context.Background(), "example.com"); err != nil {
t.Errorf("client.Authorize 1: %v", err) t.Errorf("client.Authorize 1: %v", err)
@@ -207,3 +211,30 @@ func TestRetryBackoffArgs(t *testing.T) {
t.Errorf("nretry = %d; want 3", nretry) t.Errorf("nretry = %d; want 3", nretry)
} }
} }
func TestUserAgent(t *testing.T) {
for _, custom := range []string{"", "CUSTOM_UA"} {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Log(r.UserAgent())
if s := "golang.org/x/crypto/acme"; !strings.Contains(r.UserAgent(), s) {
t.Errorf("expected User-Agent to contain %q, got %q", s, r.UserAgent())
}
if !strings.Contains(r.UserAgent(), custom) {
t.Errorf("expected User-Agent to contain %q, got %q", custom, r.UserAgent())
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{}`))
}))
defer ts.Close()
client := &Client{
Key: testKey,
DirectoryURL: ts.URL,
UserAgent: custom,
}
if _, err := client.Discover(context.Background()); err != nil {
t.Errorf("client.Discover: %v", err)
}
}
}

View File

@@ -25,7 +25,7 @@ func jwsEncodeJSON(claimset interface{}, key crypto.Signer, nonce string) ([]byt
if err != nil { if err != nil {
return nil, err return nil, err
} }
alg, sha := jwsHasher(key) alg, sha := jwsHasher(key.Public())
if alg == "" || !sha.Available() { if alg == "" || !sha.Available() {
return nil, ErrUnsupportedKey return nil, ErrUnsupportedKey
} }
@@ -97,13 +97,16 @@ func jwkEncode(pub crypto.PublicKey) (string, error) {
} }
// jwsSign signs the digest using the given key. // jwsSign signs the digest using the given key.
// It returns ErrUnsupportedKey if the key type is unknown. // The hash is unused for ECDSA keys.
// The hash is used only for RSA keys. //
// Note: non-stdlib crypto.Signer implementations are expected to return
// the signature in the format as specified in RFC7518.
// See https://tools.ietf.org/html/rfc7518 for more details.
func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) { func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
switch key := key.(type) { if key, ok := key.(*ecdsa.PrivateKey); ok {
case *rsa.PrivateKey: // The key.Sign method of ecdsa returns ASN1-encoded signature.
return key.Sign(rand.Reader, digest, hash) // So, we use the package Sign function instead
case *ecdsa.PrivateKey: // to get R and S values directly and format the result accordingly.
r, s, err := ecdsa.Sign(rand.Reader, key, digest) r, s, err := ecdsa.Sign(rand.Reader, key, digest)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -118,18 +121,18 @@ func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error)
copy(sig[size*2-len(sb):], sb) copy(sig[size*2-len(sb):], sb)
return sig, nil return sig, nil
} }
return nil, ErrUnsupportedKey return key.Sign(rand.Reader, digest, hash)
} }
// jwsHasher indicates suitable JWS algorithm name and a hash function // jwsHasher indicates suitable JWS algorithm name and a hash function
// to use for signing a digest with the provided key. // to use for signing a digest with the provided key.
// It returns ("", 0) if the key is not supported. // It returns ("", 0) if the key is not supported.
func jwsHasher(key crypto.Signer) (string, crypto.Hash) { func jwsHasher(pub crypto.PublicKey) (string, crypto.Hash) {
switch key := key.(type) { switch pub := pub.(type) {
case *rsa.PrivateKey: case *rsa.PublicKey:
return "RS256", crypto.SHA256 return "RS256", crypto.SHA256
case *ecdsa.PrivateKey: case *ecdsa.PublicKey:
switch key.Params().Name { switch pub.Params().Name {
case "P-256": case "P-256":
return "ES256", crypto.SHA256 return "ES256", crypto.SHA256
case "P-384": case "P-384":

View File

@@ -5,6 +5,7 @@
package acme package acme
import ( import (
"crypto"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/elliptic" "crypto/elliptic"
"crypto/rsa" "crypto/rsa"
@@ -13,6 +14,7 @@ import (
"encoding/json" "encoding/json"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"io"
"math/big" "math/big"
"testing" "testing"
) )
@@ -241,6 +243,79 @@ func TestJWSEncodeJSONEC(t *testing.T) {
} }
} }
type customTestSigner struct {
sig []byte
pub crypto.PublicKey
}
func (s *customTestSigner) Public() crypto.PublicKey { return s.pub }
func (s *customTestSigner) Sign(io.Reader, []byte, crypto.SignerOpts) ([]byte, error) {
return s.sig, nil
}
func TestJWSEncodeJSONCustom(t *testing.T) {
claims := struct{ Msg string }{"hello"}
const (
// printf '{"Msg":"hello"}' | base64 | tr -d '=' | tr '/+' '_-'
payload = "eyJNc2ciOiJoZWxsbyJ9"
// printf 'testsig' | base64 | tr -d '='
testsig = "dGVzdHNpZw"
// printf '{"alg":"ES256","jwk":{"crv":"P-256","kty":"EC","x":<testKeyECPubY>,"y":<testKeyECPubY>,"nonce":"nonce"}' | \
// base64 | tr -d '=' | tr '/+' '_-'
es256phead = "eyJhbGciOiJFUzI1NiIsImp3ayI6eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6IjVsaEV1" +
"ZzV4SzR4QkRaMm5BYmF4THRhTGl2ODVieEo3ZVBkMWRrTzIzSFEiLCJ5IjoiNGFpSzcyc0JlVUFH" +
"a3YwVGFMc213b2tZVVl5TnhHc1M1RU1JS3dzTklLayJ9LCJub25jZSI6Im5vbmNlIn0"
// {"alg":"RS256","jwk":{"e":"AQAB","kty":"RSA","n":"..."},"nonce":"nonce"}
rs256phead = "eyJhbGciOiJSUzI1NiIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6" +
"IlJTQSIsIm4iOiI0eGdaM2VSUGt3b1J2eTdxZVJVYm1NRGUwVi14" +
"SDllV0xkdTBpaGVlTGxybUQybXFXWGZQOUllU0tBcGJuMzRnOFR1" +
"QVM5ZzV6aHE4RUxRM2ttanItS1Y4NkdBTWdJNlZBY0dscTNRcnpw" +
"VENmXzMwQWI3LXphd3JmUmFGT05hMUh3RXpQWTFLSG5HVmt4SmM4" +
"NWdOa3dZSTlTWTJSSFh0dmxuM3pzNXdJVE5yZG9zcUVYZWFJa1ZZ" +
"QkVoYmhOdTU0cHAza3hvNlR1V0xpOWU2cFhlV2V0RXdtbEJ3dFda" +
"bFBvaWIyajNUeExCa3NLWmZveUZ5ZWszODBtSGdKQXVtUV9JMmZq" +
"ajk4Xzk3bWszaWhPWTRBZ1ZkQ0RqMXpfR0NvWmtHNVJxN25iQ0d5" +
"b3N5S1d5RFgwMFpzLW5OcVZob0xlSXZYQzRubldkSk1aNnJvZ3h5" +
"UVEifSwibm9uY2UiOiJub25jZSJ9"
)
tt := []struct {
alg, phead string
pub crypto.PublicKey
}{
{"RS256", rs256phead, testKey.Public()},
{"ES256", es256phead, testKeyEC.Public()},
}
for _, tc := range tt {
tc := tc
t.Run(tc.alg, func(t *testing.T) {
signer := &customTestSigner{
sig: []byte("testsig"),
pub: tc.pub,
}
b, err := jwsEncodeJSON(claims, signer, "nonce")
if err != nil {
t.Fatal(err)
}
var j struct{ Protected, Payload, Signature string }
if err := json.Unmarshal(b, &j); err != nil {
t.Fatal(err)
}
if j.Protected != tc.phead {
t.Errorf("j.Protected = %q\nwant %q", j.Protected, tc.phead)
}
if j.Payload != payload {
t.Errorf("j.Payload = %q\nwant %q", j.Payload, payload)
}
if j.Signature != testsig {
t.Errorf("j.Signature = %q\nwant %q", j.Signature, testsig)
}
})
}
}
func TestJWKThumbprintRSA(t *testing.T) { func TestJWKThumbprintRSA(t *testing.T) {
// Key example from RFC 7638 // Key example from RFC 7638
const base64N = "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAt" + const base64N = "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAt" +

27
vendor/golang.org/x/crypto/acme/version_go112.go generated vendored Normal file
View File

@@ -0,0 +1,27 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.12
package acme
import "runtime/debug"
func init() {
// Set packageVersion if the binary was built in modules mode and x/crypto
// was not replaced with a different module.
info, ok := debug.ReadBuildInfo()
if !ok {
return
}
for _, m := range info.Deps {
if m.Path != "golang.org/x/crypto" {
continue
}
if m.Replace == nil {
packageVersion = m.Version
}
break
}
}

View File

@@ -209,19 +209,19 @@ func TestMinorNotRequired(t *testing.T) {
func BenchmarkEqual(b *testing.B) { func BenchmarkEqual(b *testing.B) {
b.StopTimer() b.StopTimer()
passwd := []byte("somepasswordyoulike") passwd := []byte("somepasswordyoulike")
hash, _ := GenerateFromPassword(passwd, 10) hash, _ := GenerateFromPassword(passwd, DefaultCost)
b.StartTimer() b.StartTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
CompareHashAndPassword(hash, passwd) CompareHashAndPassword(hash, passwd)
} }
} }
func BenchmarkGeneration(b *testing.B) { func BenchmarkDefaultCost(b *testing.B) {
b.StopTimer() b.StopTimer()
passwd := []byte("mylongpassword1234") passwd := []byte("mylongpassword1234")
b.StartTimer() b.StartTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
GenerateFromPassword(passwd, 10) GenerateFromPassword(passwd, DefaultCost)
} }
} }

View File

@@ -75,19 +75,19 @@ func Sum256(data []byte) [Size256]byte {
} }
// New512 returns a new hash.Hash computing the BLAKE2b-512 checksum. A non-nil // 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. // key turns the hash into a MAC. The key must be between zero and 64 bytes long.
func New512(key []byte) (hash.Hash, error) { return newDigest(Size, key) } 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 // 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. // key turns the hash into a MAC. The key must be between zero and 64 bytes long.
func New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) } 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 // 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. // key turns the hash into a MAC. The key must be between zero and 64 bytes long.
func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) } func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) }
// New returns a new hash.Hash computing the BLAKE2b checksum with a custom length. // New returns a new hash.Hash computing the BLAKE2b checksum with a custom length.
// A non-nil key turns the hash into a MAC. The key must between zero and 64 bytes long. // A non-nil key turns the hash into a MAC. The key must be between zero and 64 bytes long.
// The hash size can be a value between 1 and 64 but it is highly recommended to use // The hash size can be a value between 1 and 64 but it is highly recommended to use
// values equal or greater than: // values equal or greater than:
// - 32 if BLAKE2b is used as a hash function (The key is zero bytes long). // - 32 if BLAKE2b is used as a hash function (The key is zero bytes long).

View File

@@ -4,7 +4,10 @@
package blake2b package blake2b
import "encoding/binary" import (
"encoding/binary"
"math/bits"
)
// the precomputed values for BLAKE2b // the precomputed values for BLAKE2b
// there are 12 16-byte arrays - one for each round // there are 12 16-byte arrays - one for each round
@@ -51,118 +54,118 @@ func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
v0 += m[s[0]] v0 += m[s[0]]
v0 += v4 v0 += v4
v12 ^= v0 v12 ^= v0
v12 = v12<<(64-32) | v12>>32 v12 = bits.RotateLeft64(v12, -32)
v8 += v12 v8 += v12
v4 ^= v8 v4 ^= v8
v4 = v4<<(64-24) | v4>>24 v4 = bits.RotateLeft64(v4, -24)
v1 += m[s[1]] v1 += m[s[1]]
v1 += v5 v1 += v5
v13 ^= v1 v13 ^= v1
v13 = v13<<(64-32) | v13>>32 v13 = bits.RotateLeft64(v13, -32)
v9 += v13 v9 += v13
v5 ^= v9 v5 ^= v9
v5 = v5<<(64-24) | v5>>24 v5 = bits.RotateLeft64(v5, -24)
v2 += m[s[2]] v2 += m[s[2]]
v2 += v6 v2 += v6
v14 ^= v2 v14 ^= v2
v14 = v14<<(64-32) | v14>>32 v14 = bits.RotateLeft64(v14, -32)
v10 += v14 v10 += v14
v6 ^= v10 v6 ^= v10
v6 = v6<<(64-24) | v6>>24 v6 = bits.RotateLeft64(v6, -24)
v3 += m[s[3]] v3 += m[s[3]]
v3 += v7 v3 += v7
v15 ^= v3 v15 ^= v3
v15 = v15<<(64-32) | v15>>32 v15 = bits.RotateLeft64(v15, -32)
v11 += v15 v11 += v15
v7 ^= v11 v7 ^= v11
v7 = v7<<(64-24) | v7>>24 v7 = bits.RotateLeft64(v7, -24)
v0 += m[s[4]] v0 += m[s[4]]
v0 += v4 v0 += v4
v12 ^= v0 v12 ^= v0
v12 = v12<<(64-16) | v12>>16 v12 = bits.RotateLeft64(v12, -16)
v8 += v12 v8 += v12
v4 ^= v8 v4 ^= v8
v4 = v4<<(64-63) | v4>>63 v4 = bits.RotateLeft64(v4, -63)
v1 += m[s[5]] v1 += m[s[5]]
v1 += v5 v1 += v5
v13 ^= v1 v13 ^= v1
v13 = v13<<(64-16) | v13>>16 v13 = bits.RotateLeft64(v13, -16)
v9 += v13 v9 += v13
v5 ^= v9 v5 ^= v9
v5 = v5<<(64-63) | v5>>63 v5 = bits.RotateLeft64(v5, -63)
v2 += m[s[6]] v2 += m[s[6]]
v2 += v6 v2 += v6
v14 ^= v2 v14 ^= v2
v14 = v14<<(64-16) | v14>>16 v14 = bits.RotateLeft64(v14, -16)
v10 += v14 v10 += v14
v6 ^= v10 v6 ^= v10
v6 = v6<<(64-63) | v6>>63 v6 = bits.RotateLeft64(v6, -63)
v3 += m[s[7]] v3 += m[s[7]]
v3 += v7 v3 += v7
v15 ^= v3 v15 ^= v3
v15 = v15<<(64-16) | v15>>16 v15 = bits.RotateLeft64(v15, -16)
v11 += v15 v11 += v15
v7 ^= v11 v7 ^= v11
v7 = v7<<(64-63) | v7>>63 v7 = bits.RotateLeft64(v7, -63)
v0 += m[s[8]] v0 += m[s[8]]
v0 += v5 v0 += v5
v15 ^= v0 v15 ^= v0
v15 = v15<<(64-32) | v15>>32 v15 = bits.RotateLeft64(v15, -32)
v10 += v15 v10 += v15
v5 ^= v10 v5 ^= v10
v5 = v5<<(64-24) | v5>>24 v5 = bits.RotateLeft64(v5, -24)
v1 += m[s[9]] v1 += m[s[9]]
v1 += v6 v1 += v6
v12 ^= v1 v12 ^= v1
v12 = v12<<(64-32) | v12>>32 v12 = bits.RotateLeft64(v12, -32)
v11 += v12 v11 += v12
v6 ^= v11 v6 ^= v11
v6 = v6<<(64-24) | v6>>24 v6 = bits.RotateLeft64(v6, -24)
v2 += m[s[10]] v2 += m[s[10]]
v2 += v7 v2 += v7
v13 ^= v2 v13 ^= v2
v13 = v13<<(64-32) | v13>>32 v13 = bits.RotateLeft64(v13, -32)
v8 += v13 v8 += v13
v7 ^= v8 v7 ^= v8
v7 = v7<<(64-24) | v7>>24 v7 = bits.RotateLeft64(v7, -24)
v3 += m[s[11]] v3 += m[s[11]]
v3 += v4 v3 += v4
v14 ^= v3 v14 ^= v3
v14 = v14<<(64-32) | v14>>32 v14 = bits.RotateLeft64(v14, -32)
v9 += v14 v9 += v14
v4 ^= v9 v4 ^= v9
v4 = v4<<(64-24) | v4>>24 v4 = bits.RotateLeft64(v4, -24)
v0 += m[s[12]] v0 += m[s[12]]
v0 += v5 v0 += v5
v15 ^= v0 v15 ^= v0
v15 = v15<<(64-16) | v15>>16 v15 = bits.RotateLeft64(v15, -16)
v10 += v15 v10 += v15
v5 ^= v10 v5 ^= v10
v5 = v5<<(64-63) | v5>>63 v5 = bits.RotateLeft64(v5, -63)
v1 += m[s[13]] v1 += m[s[13]]
v1 += v6 v1 += v6
v12 ^= v1 v12 ^= v1
v12 = v12<<(64-16) | v12>>16 v12 = bits.RotateLeft64(v12, -16)
v11 += v12 v11 += v12
v6 ^= v11 v6 ^= v11
v6 = v6<<(64-63) | v6>>63 v6 = bits.RotateLeft64(v6, -63)
v2 += m[s[14]] v2 += m[s[14]]
v2 += v7 v2 += v7
v13 ^= v2 v13 ^= v2
v13 = v13<<(64-16) | v13>>16 v13 = bits.RotateLeft64(v13, -16)
v8 += v13 v8 += v13
v7 ^= v8 v7 ^= v8
v7 = v7<<(64-63) | v7>>63 v7 = bits.RotateLeft64(v7, -63)
v3 += m[s[15]] v3 += m[s[15]]
v3 += v4 v3 += v4
v14 ^= v3 v14 ^= v3
v14 = v14<<(64-16) | v14>>16 v14 = bits.RotateLeft64(v14, -16)
v9 += v14 v9 += v14
v4 ^= v9 v4 ^= v9
v4 = v4<<(64-63) | v4>>63 v4 = bits.RotateLeft64(v4, -63)
} }

View File

@@ -29,7 +29,7 @@ type XOF interface {
} }
// OutputLengthUnknown can be used as the size argument to NewXOF to indicate // OutputLengthUnknown can be used as the size argument to NewXOF to indicate
// the the length of the output is not known in advance. // the length of the output is not known in advance.
const OutputLengthUnknown = 0 const OutputLengthUnknown = 0
// magicUnknownOutputLength is a magic value for the output size that indicates // magicUnknownOutputLength is a magic value for the output size that indicates

View File

@@ -4,6 +4,10 @@
package blake2s package blake2s
import (
"math/bits"
)
// the precomputed values for BLAKE2s // the precomputed values for BLAKE2s
// there are 10 16-byte arrays - one for each round // there are 10 16-byte arrays - one for each round
// the entries are calculated from the sigma constants. // the entries are calculated from the sigma constants.
@@ -47,118 +51,118 @@ func hashBlocksGeneric(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
v0 += m[s[0]] v0 += m[s[0]]
v0 += v4 v0 += v4
v12 ^= v0 v12 ^= v0
v12 = v12<<(32-16) | v12>>16 v12 = bits.RotateLeft32(v12, -16)
v8 += v12 v8 += v12
v4 ^= v8 v4 ^= v8
v4 = v4<<(32-12) | v4>>12 v4 = bits.RotateLeft32(v4, -12)
v1 += m[s[1]] v1 += m[s[1]]
v1 += v5 v1 += v5
v13 ^= v1 v13 ^= v1
v13 = v13<<(32-16) | v13>>16 v13 = bits.RotateLeft32(v13, -16)
v9 += v13 v9 += v13
v5 ^= v9 v5 ^= v9
v5 = v5<<(32-12) | v5>>12 v5 = bits.RotateLeft32(v5, -12)
v2 += m[s[2]] v2 += m[s[2]]
v2 += v6 v2 += v6
v14 ^= v2 v14 ^= v2
v14 = v14<<(32-16) | v14>>16 v14 = bits.RotateLeft32(v14, -16)
v10 += v14 v10 += v14
v6 ^= v10 v6 ^= v10
v6 = v6<<(32-12) | v6>>12 v6 = bits.RotateLeft32(v6, -12)
v3 += m[s[3]] v3 += m[s[3]]
v3 += v7 v3 += v7
v15 ^= v3 v15 ^= v3
v15 = v15<<(32-16) | v15>>16 v15 = bits.RotateLeft32(v15, -16)
v11 += v15 v11 += v15
v7 ^= v11 v7 ^= v11
v7 = v7<<(32-12) | v7>>12 v7 = bits.RotateLeft32(v7, -12)
v0 += m[s[4]] v0 += m[s[4]]
v0 += v4 v0 += v4
v12 ^= v0 v12 ^= v0
v12 = v12<<(32-8) | v12>>8 v12 = bits.RotateLeft32(v12, -8)
v8 += v12 v8 += v12
v4 ^= v8 v4 ^= v8
v4 = v4<<(32-7) | v4>>7 v4 = bits.RotateLeft32(v4, -7)
v1 += m[s[5]] v1 += m[s[5]]
v1 += v5 v1 += v5
v13 ^= v1 v13 ^= v1
v13 = v13<<(32-8) | v13>>8 v13 = bits.RotateLeft32(v13, -8)
v9 += v13 v9 += v13
v5 ^= v9 v5 ^= v9
v5 = v5<<(32-7) | v5>>7 v5 = bits.RotateLeft32(v5, -7)
v2 += m[s[6]] v2 += m[s[6]]
v2 += v6 v2 += v6
v14 ^= v2 v14 ^= v2
v14 = v14<<(32-8) | v14>>8 v14 = bits.RotateLeft32(v14, -8)
v10 += v14 v10 += v14
v6 ^= v10 v6 ^= v10
v6 = v6<<(32-7) | v6>>7 v6 = bits.RotateLeft32(v6, -7)
v3 += m[s[7]] v3 += m[s[7]]
v3 += v7 v3 += v7
v15 ^= v3 v15 ^= v3
v15 = v15<<(32-8) | v15>>8 v15 = bits.RotateLeft32(v15, -8)
v11 += v15 v11 += v15
v7 ^= v11 v7 ^= v11
v7 = v7<<(32-7) | v7>>7 v7 = bits.RotateLeft32(v7, -7)
v0 += m[s[8]] v0 += m[s[8]]
v0 += v5 v0 += v5
v15 ^= v0 v15 ^= v0
v15 = v15<<(32-16) | v15>>16 v15 = bits.RotateLeft32(v15, -16)
v10 += v15 v10 += v15
v5 ^= v10 v5 ^= v10
v5 = v5<<(32-12) | v5>>12 v5 = bits.RotateLeft32(v5, -12)
v1 += m[s[9]] v1 += m[s[9]]
v1 += v6 v1 += v6
v12 ^= v1 v12 ^= v1
v12 = v12<<(32-16) | v12>>16 v12 = bits.RotateLeft32(v12, -16)
v11 += v12 v11 += v12
v6 ^= v11 v6 ^= v11
v6 = v6<<(32-12) | v6>>12 v6 = bits.RotateLeft32(v6, -12)
v2 += m[s[10]] v2 += m[s[10]]
v2 += v7 v2 += v7
v13 ^= v2 v13 ^= v2
v13 = v13<<(32-16) | v13>>16 v13 = bits.RotateLeft32(v13, -16)
v8 += v13 v8 += v13
v7 ^= v8 v7 ^= v8
v7 = v7<<(32-12) | v7>>12 v7 = bits.RotateLeft32(v7, -12)
v3 += m[s[11]] v3 += m[s[11]]
v3 += v4 v3 += v4
v14 ^= v3 v14 ^= v3
v14 = v14<<(32-16) | v14>>16 v14 = bits.RotateLeft32(v14, -16)
v9 += v14 v9 += v14
v4 ^= v9 v4 ^= v9
v4 = v4<<(32-12) | v4>>12 v4 = bits.RotateLeft32(v4, -12)
v0 += m[s[12]] v0 += m[s[12]]
v0 += v5 v0 += v5
v15 ^= v0 v15 ^= v0
v15 = v15<<(32-8) | v15>>8 v15 = bits.RotateLeft32(v15, -8)
v10 += v15 v10 += v15
v5 ^= v10 v5 ^= v10
v5 = v5<<(32-7) | v5>>7 v5 = bits.RotateLeft32(v5, -7)
v1 += m[s[13]] v1 += m[s[13]]
v1 += v6 v1 += v6
v12 ^= v1 v12 ^= v1
v12 = v12<<(32-8) | v12>>8 v12 = bits.RotateLeft32(v12, -8)
v11 += v12 v11 += v12
v6 ^= v11 v6 ^= v11
v6 = v6<<(32-7) | v6>>7 v6 = bits.RotateLeft32(v6, -7)
v2 += m[s[14]] v2 += m[s[14]]
v2 += v7 v2 += v7
v13 ^= v2 v13 ^= v2
v13 = v13<<(32-8) | v13>>8 v13 = bits.RotateLeft32(v13, -8)
v8 += v13 v8 += v13
v7 ^= v8 v7 ^= v8
v7 = v7<<(32-7) | v7>>7 v7 = bits.RotateLeft32(v7, -7)
v3 += m[s[15]] v3 += m[s[15]]
v3 += v4 v3 += v4
v14 ^= v3 v14 ^= v3
v14 = v14<<(32-8) | v14>>8 v14 = bits.RotateLeft32(v14, -8)
v9 += v14 v9 += v14
v4 ^= v9 v4 ^= v9
v4 = v4<<(32-7) | v4>>7 v4 = bits.RotateLeft32(v4, -7)
} }
h[0] ^= v0 ^ v8 h[0] ^= v0 ^ v8

View File

@@ -29,7 +29,7 @@ type XOF interface {
} }
// OutputLengthUnknown can be used as the size argument to NewXOF to indicate // OutputLengthUnknown can be used as the size argument to NewXOF to indicate
// the the length of the output is not known in advance. // the length of the output is not known in advance.
const OutputLengthUnknown = 0 const OutputLengthUnknown = 0
// magicUnknownOutputLength is a magic value for the output size that indicates // magicUnknownOutputLength is a magic value for the output size that indicates

View File

@@ -3,6 +3,14 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm. // Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.
//
// Blowfish is a legacy cipher and its short block size makes it vulnerable to
// birthday bound attacks (see https://sweet32.info). It should only be used
// where compatibility with legacy systems, not security, is the goal.
//
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
// golang.org/x/crypto/chacha20poly1305).
package blowfish // import "golang.org/x/crypto/blowfish" package blowfish // import "golang.org/x/crypto/blowfish"
// The code is a port of Bruce Schneier's C implementation. // The code is a port of Bruce Schneier's C implementation.

View File

@@ -15,9 +15,14 @@
// http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible // http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible
// with the implementation described in that paper. // with the implementation described in that paper.
// //
// (This package previously claimed to operate at a 128-bit security level. // This package previously claimed to operate at a 128-bit security level.
// However, recent improvements in attacks mean that is no longer true. See // However, recent improvements in attacks mean that is no longer true. See
// https://moderncrypto.org/mail-archive/curves/2016/000740.html.) // https://moderncrypto.org/mail-archive/curves/2016/000740.html.
//
// Deprecated: due to its weakened security, new systems should not rely on this
// elliptic curve. This package is frozen, and not implemented in constant time.
// There is a more complete implementation at github.com/cloudflare/bn256, but
// note that it suffers from the same security issues of the underlying curve.
package bn256 // import "golang.org/x/crypto/bn256" package bn256 // import "golang.org/x/crypto/bn256"
import ( import (
@@ -26,9 +31,6 @@ import (
"math/big" "math/big"
) )
// BUG(agl): this implementation is not constant time.
// TODO(agl): keep GF(p²) elements in Mongomery form.
// G1 is an abstract cyclic group. The zero value is suitable for use as the // G1 is an abstract cyclic group. The zero value is suitable for use as the
// output of an operation, but cannot be used as an input. // output of an operation, but cannot be used as an input.
type G1 struct { type G1 struct {
@@ -54,6 +56,9 @@ func RandomG1(r io.Reader) (*big.Int, *G1, error) {
} }
func (e *G1) String() string { func (e *G1) String() string {
if e.p == nil {
return "bn256.G1" + newCurvePoint(nil).String()
}
return "bn256.G1" + e.p.String() return "bn256.G1" + e.p.String()
} }
@@ -77,7 +82,8 @@ func (e *G1) ScalarMult(a *G1, k *big.Int) *G1 {
} }
// Add sets e to a+b and then returns e. // Add sets e to a+b and then returns e.
// BUG(agl): this function is not complete: a==b fails. //
// Warning: this function is not complete, it fails for a equal to b.
func (e *G1) Add(a, b *G1) *G1 { func (e *G1) Add(a, b *G1) *G1 {
if e.p == nil { if e.p == nil {
e.p = newCurvePoint(nil) e.p = newCurvePoint(nil)
@@ -175,6 +181,9 @@ func RandomG2(r io.Reader) (*big.Int, *G2, error) {
} }
func (e *G2) String() string { func (e *G2) String() string {
if e.p == nil {
return "bn256.G2" + newTwistPoint(nil).String()
}
return "bn256.G2" + e.p.String() return "bn256.G2" + e.p.String()
} }
@@ -198,7 +207,8 @@ func (e *G2) ScalarMult(a *G2, k *big.Int) *G2 {
} }
// Add sets e to a+b and then returns e. // Add sets e to a+b and then returns e.
// BUG(agl): this function is not complete: a==b fails. //
// Warning: this function is not complete, it fails for a equal to b.
func (e *G2) Add(a, b *G2) *G2 { func (e *G2) Add(a, b *G2) *G2 {
if e.p == nil { if e.p == nil {
e.p = newTwistPoint(nil) e.p = newTwistPoint(nil)
@@ -277,8 +287,11 @@ type GT struct {
p *gfP12 p *gfP12
} }
func (g *GT) String() string { func (e *GT) String() string {
return "bn256.GT" + g.p.String() if e.p == nil {
return "bn256.GT" + newGFp12(nil).String()
}
return "bn256.GT" + e.p.String()
} }
// ScalarMult sets e to a*k and then returns e. // ScalarMult sets e to a*k and then returns e.

View File

@@ -125,8 +125,8 @@ func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 {
} }
func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 { func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 {
e.x.Mul(e.x, b, pool) e.x.Mul(a.x, b, pool)
e.y.Mul(e.y, b, pool) e.y.Mul(a.y, b, pool)
return e return e
} }

View File

@@ -2,8 +2,15 @@
// 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.
// Package cast5 implements CAST5, as defined in RFC 2144. CAST5 is a common // Package cast5 implements CAST5, as defined in RFC 2144.
// OpenPGP cipher. //
// CAST5 is a legacy cipher and its short block size makes it vulnerable to
// birthday bound attacks (see https://sweet32.info). It should only be used
// where compatibility with legacy systems, not security, is the goal.
//
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
// golang.org/x/crypto/chacha20poly1305).
package cast5 // import "golang.org/x/crypto/cast5" package cast5 // import "golang.org/x/crypto/cast5"
import "errors" import "errors"

View File

@@ -200,7 +200,7 @@ GLOBL ·andMask<>(SB), (NOPTR+RODATA), $240
#define polyMulStage1 MOVQ (0*8)(BP), AX; MOVQ AX, t2; MULQ acc0; MOVQ AX, t0; MOVQ DX, t1; MOVQ (0*8)(BP), AX; MULQ acc1; IMULQ acc2, t2; ADDQ AX, t1; ADCQ DX, t2 #define polyMulStage1 MOVQ (0*8)(BP), AX; MOVQ AX, t2; MULQ acc0; MOVQ AX, t0; MOVQ DX, t1; MOVQ (0*8)(BP), AX; MULQ acc1; IMULQ acc2, t2; ADDQ AX, t1; ADCQ DX, t2
#define polyMulStage2 MOVQ (1*8)(BP), AX; MOVQ AX, t3; MULQ acc0; ADDQ AX, t1; ADCQ $0, DX; MOVQ DX, acc0; MOVQ (1*8)(BP), AX; MULQ acc1; ADDQ AX, t2; ADCQ $0, DX #define polyMulStage2 MOVQ (1*8)(BP), AX; MOVQ AX, t3; MULQ acc0; ADDQ AX, t1; ADCQ $0, DX; MOVQ DX, acc0; MOVQ (1*8)(BP), AX; MULQ acc1; ADDQ AX, t2; ADCQ $0, DX
#define polyMulStage3 IMULQ acc2, t3; ADDQ acc0, t2; ADCQ DX, t3 #define polyMulStage3 IMULQ acc2, t3; ADDQ acc0, t2; ADCQ DX, t3
#define polyMulReduceStage MOVQ t0, acc0; MOVQ t1, acc1; MOVQ t2, acc2; ANDQ $3, acc2; MOVQ t2, t0; ANDQ $-4, t0; MOVQ t3, t1; SHRQ $2, t2:t3; SHRQ $2, t3; ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $0, acc2; ADDQ t2, acc0; ADCQ t3, acc1; ADCQ $0, acc2 #define polyMulReduceStage MOVQ t0, acc0; MOVQ t1, acc1; MOVQ t2, acc2; ANDQ $3, acc2; MOVQ t2, t0; ANDQ $-4, t0; MOVQ t3, t1; SHRQ $2, t3, t2; SHRQ $2, t3; ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $0, acc2; ADDQ t2, acc0; ADCQ t3, acc1; ADCQ $0, acc2
#define polyMulStage1_AVX2 MOVQ (0*8)(BP), DX; MOVQ DX, t2; MULXQ acc0, t0, t1; IMULQ acc2, t2; MULXQ acc1, AX, DX; ADDQ AX, t1; ADCQ DX, t2 #define polyMulStage1_AVX2 MOVQ (0*8)(BP), DX; MOVQ DX, t2; MULXQ acc0, t0, t1; IMULQ acc2, t2; MULXQ acc1, AX, DX; ADDQ AX, t1; ADCQ DX, t2
#define polyMulStage2_AVX2 MOVQ (1*8)(BP), DX; MULXQ acc0, acc0, AX; ADDQ acc0, t1; MULXQ acc1, acc1, t3; ADCQ acc1, t2; ADCQ $0, t3 #define polyMulStage2_AVX2 MOVQ (1*8)(BP), DX; MULXQ acc0, acc0, AX; ADDQ acc0, t1; MULXQ acc1, acc1, t3; ADCQ acc1, t2; ADCQ $0, t3
@@ -248,7 +248,7 @@ hashADTail:
ADDQ itr2, adp ADDQ itr2, adp
hashADTailLoop: hashADTailLoop:
SHLQ $8, t1:t0 SHLQ $8, t0, t1
SHLQ $8, t0 SHLQ $8, t0
MOVB -1(adp), t2 MOVB -1(adp), t2
XORQ t2, t0 XORQ t2, t0

View File

@@ -50,8 +50,14 @@ func NewFixedBuilder(buffer []byte) *Builder {
} }
} }
// SetError sets the value to be returned as the error from Bytes. Writes
// performed after calling SetError are ignored.
func (b *Builder) SetError(err error) {
b.err = err
}
// Bytes returns the bytes written by the builder or an error if one has // Bytes returns the bytes written by the builder or an error if one has
// occurred during during building. // occurred during building.
func (b *Builder) Bytes() ([]byte, error) { func (b *Builder) Bytes() ([]byte, error) {
if b.err != nil { if b.err != nil {
return nil, b.err return nil, b.err
@@ -94,7 +100,7 @@ func (b *Builder) AddBytes(v []byte) {
b.add(v...) b.add(v...)
} }
// BuilderContinuation is continuation-passing interface for building // BuilderContinuation is a continuation-passing interface for building
// length-prefixed byte sequences. Builder methods for length-prefixed // length-prefixed byte sequences. Builder methods for length-prefixed
// sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation // sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation
// supplied to them. The child builder passed to the continuation can be used // supplied to them. The child builder passed to the continuation can be used
@@ -268,9 +274,11 @@ func (b *Builder) flushChild() {
return return
} }
if !b.fixedSize { if b.fixedSize && &b.result[0] != &child.result[0] {
b.result = child.result // In case child reallocated result. panic("cryptobyte: BuilderContinuation reallocated a fixed-size buffer")
} }
b.result = child.result
} }
func (b *Builder) add(bytes ...byte) { func (b *Builder) add(bytes ...byte) {
@@ -278,7 +286,7 @@ func (b *Builder) add(bytes ...byte) {
return return
} }
if b.child != nil { if b.child != nil {
panic("attempted write while child is pending") panic("cryptobyte: attempted write while child is pending")
} }
if len(b.result)+len(bytes) < len(bytes) { if len(b.result)+len(bytes) < len(bytes) {
b.err = errors.New("cryptobyte: length overflow") b.err = errors.New("cryptobyte: length overflow")
@@ -290,6 +298,26 @@ func (b *Builder) add(bytes ...byte) {
b.result = append(b.result, bytes...) b.result = append(b.result, bytes...)
} }
// Unwrite rolls back n bytes written directly to the Builder. An attempt by a
// child builder passed to a continuation to unwrite bytes from its parent will
// panic.
func (b *Builder) Unwrite(n int) {
if b.err != nil {
return
}
if b.child != nil {
panic("cryptobyte: attempted unwrite while child is pending")
}
length := len(b.result) - b.pendingLenLen - b.offset
if length < 0 {
panic("cryptobyte: internal error")
}
if n > length {
panic("cryptobyte: attempted to unwrite more than was written")
}
b.result = b.result[:len(b.result)-n]
}
// A MarshalingValue marshals itself into a Builder. // A MarshalingValue marshals itself into a Builder.
type MarshalingValue interface { type MarshalingValue interface {
// Marshal is called by Builder.AddValue. It receives a pointer to a builder // Marshal is called by Builder.AddValue. It receives a pointer to a builder

View File

@@ -327,12 +327,14 @@ func TestWriteWithPendingChild(t *testing.T) {
var b Builder var b Builder
b.AddUint8LengthPrefixed(func(c *Builder) { b.AddUint8LengthPrefixed(func(c *Builder) {
c.AddUint8LengthPrefixed(func(d *Builder) { c.AddUint8LengthPrefixed(func(d *Builder) {
defer func() { func() {
if recover() == nil { defer func() {
t.Errorf("recover() = nil, want error; c.AddUint8() did not panic") if recover() == nil {
} t.Errorf("recover() = nil, want error; c.AddUint8() did not panic")
}
}()
c.AddUint8(2) // panics
}() }()
c.AddUint8(2) // panics
defer func() { defer func() {
if recover() == nil { if recover() == nil {
@@ -351,6 +353,92 @@ func TestWriteWithPendingChild(t *testing.T) {
}) })
} }
func TestSetError(t *testing.T) {
const errorStr = "TestSetError"
var b Builder
b.SetError(errors.New(errorStr))
ret, err := b.Bytes()
if ret != nil {
t.Error("expected nil result")
}
if err == nil {
t.Fatal("unexpected nil error")
}
if s := err.Error(); s != errorStr {
t.Errorf("expected error %q, got %v", errorStr, s)
}
}
func TestUnwrite(t *testing.T) {
var b Builder
b.AddBytes([]byte{1, 2, 3, 4, 5})
b.Unwrite(2)
if err := builderBytesEq(&b, 1, 2, 3); err != nil {
t.Error(err)
}
func() {
defer func() {
if recover() == nil {
t.Errorf("recover() = nil, want error; b.Unwrite() did not panic")
}
}()
b.Unwrite(4) // panics
}()
b = Builder{}
b.AddBytes([]byte{1, 2, 3, 4, 5})
b.AddUint8LengthPrefixed(func(b *Builder) {
b.AddBytes([]byte{1, 2, 3, 4, 5})
defer func() {
if recover() == nil {
t.Errorf("recover() = nil, want error; b.Unwrite() did not panic")
}
}()
b.Unwrite(6) // panics
})
b = Builder{}
b.AddBytes([]byte{1, 2, 3, 4, 5})
b.AddUint8LengthPrefixed(func(c *Builder) {
defer func() {
if recover() == nil {
t.Errorf("recover() = nil, want error; b.Unwrite() did not panic")
}
}()
b.Unwrite(2) // panics (attempted unwrite while child is pending)
})
}
func TestFixedBuilderLengthPrefixed(t *testing.T) {
bufCap := 10
inner := bytes.Repeat([]byte{0xff}, bufCap-2)
buf := make([]byte, 0, bufCap)
b := NewFixedBuilder(buf)
b.AddUint16LengthPrefixed(func(b *Builder) {
b.AddBytes(inner)
})
if got := b.BytesOrPanic(); len(got) != bufCap {
t.Errorf("Expected output length to be %d, got %d", bufCap, len(got))
}
}
func TestFixedBuilderPanicReallocate(t *testing.T) {
defer func() {
recover()
}()
b := NewFixedBuilder(make([]byte, 0, 10))
b1 := NewFixedBuilder(make([]byte, 0, 10))
b.AddUint16LengthPrefixed(func(b *Builder) {
*b = *b1
})
t.Error("Builder did not panic")
}
// ASN.1 // ASN.1
func TestASN1Int64(t *testing.T) { func TestASN1Int64(t *testing.T) {

View File

@@ -86,7 +86,7 @@ func feFromBytes(dst *fieldElement, src *[32]byte) {
h6 := load3(src[20:]) << 7 h6 := load3(src[20:]) << 7
h7 := load3(src[23:]) << 5 h7 := load3(src[23:]) << 5
h8 := load3(src[26:]) << 4 h8 := load3(src[26:]) << 4
h9 := load3(src[29:]) << 2 h9 := (load3(src[29:]) & 0x7fffff) << 2
var carry [10]int64 var carry [10]int64
carry[9] = (h9 + 1<<24) >> 25 carry[9] = (h9 + 1<<24) >> 25

View File

@@ -5,6 +5,8 @@
package curve25519 package curve25519
import ( import (
"bytes"
"crypto/rand"
"fmt" "fmt"
"testing" "testing"
) )
@@ -28,6 +30,44 @@ func TestBaseScalarMult(t *testing.T) {
} }
} }
func TestTestVectors(t *testing.T) {
for _, tv := range testVectors {
var got [32]byte
ScalarMult(&got, &tv.In, &tv.Base)
if !bytes.Equal(got[:], tv.Expect[:]) {
t.Logf(" in = %x", tv.In)
t.Logf(" base = %x", tv.Base)
t.Logf(" got = %x", got)
t.Logf("expect = %x", tv.Expect)
t.Fail()
}
}
}
// TestHighBitIgnored tests the following requirement in RFC 7748:
//
// When receiving such an array, implementations of X25519 (but not X448) MUST
// mask the most significant bit in the final byte.
//
// Regression test for issue #30095.
func TestHighBitIgnored(t *testing.T) {
var s, u [32]byte
rand.Read(s[:])
rand.Read(u[:])
var hi0, hi1 [32]byte
u[31] &= 0x7f
ScalarMult(&hi0, &s, &u)
u[31] |= 0x80
ScalarMult(&hi1, &s, &u)
if !bytes.Equal(hi0[:], hi1[:]) {
t.Errorf("high bit of group point should not affect result")
}
}
func BenchmarkScalarBaseMult(b *testing.B) { func BenchmarkScalarBaseMult(b *testing.B) {
var in, out [32]byte var in, out [32]byte
in[0] = 1 in[0] = 1

View File

@@ -121,18 +121,18 @@ TEXT ·ladderstep(SB),0,$296-8
ADDQ AX,R12 ADDQ AX,R12
ADCQ DX,R13 ADCQ DX,R13
MOVQ $REDMASK51,DX MOVQ $REDMASK51,DX
SHLQ $13,CX:SI SHLQ $13,SI,CX
ANDQ DX,SI ANDQ DX,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ DX,R8 ANDQ DX,R8
ADDQ CX,R8 ADDQ CX,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ DX,R10 ANDQ DX,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ DX,R12 ANDQ DX,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ DX,R14 ANDQ DX,R14
ADDQ R13,R14 ADDQ R13,R14
IMUL3Q $19,R15,CX IMUL3Q $19,R15,CX
@@ -236,18 +236,18 @@ TEXT ·ladderstep(SB),0,$296-8
ADDQ AX,R12 ADDQ AX,R12
ADCQ DX,R13 ADCQ DX,R13
MOVQ $REDMASK51,DX MOVQ $REDMASK51,DX
SHLQ $13,CX:SI SHLQ $13,SI,CX
ANDQ DX,SI ANDQ DX,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ DX,R8 ANDQ DX,R8
ADDQ CX,R8 ADDQ CX,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ DX,R10 ANDQ DX,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ DX,R12 ANDQ DX,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ DX,R14 ANDQ DX,R14
ADDQ R13,R14 ADDQ R13,R14
IMUL3Q $19,R15,CX IMUL3Q $19,R15,CX
@@ -441,18 +441,18 @@ TEXT ·ladderstep(SB),0,$296-8
ADDQ AX,R12 ADDQ AX,R12
ADCQ DX,R13 ADCQ DX,R13
MOVQ $REDMASK51,DX MOVQ $REDMASK51,DX
SHLQ $13,CX:SI SHLQ $13,SI,CX
ANDQ DX,SI ANDQ DX,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ DX,R8 ANDQ DX,R8
ADDQ CX,R8 ADDQ CX,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ DX,R10 ANDQ DX,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ DX,R12 ANDQ DX,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ DX,R14 ANDQ DX,R14
ADDQ R13,R14 ADDQ R13,R14
IMUL3Q $19,R15,CX IMUL3Q $19,R15,CX
@@ -591,18 +591,18 @@ TEXT ·ladderstep(SB),0,$296-8
ADDQ AX,R12 ADDQ AX,R12
ADCQ DX,R13 ADCQ DX,R13
MOVQ $REDMASK51,DX MOVQ $REDMASK51,DX
SHLQ $13,CX:SI SHLQ $13,SI,CX
ANDQ DX,SI ANDQ DX,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ DX,R8 ANDQ DX,R8
ADDQ CX,R8 ADDQ CX,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ DX,R10 ANDQ DX,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ DX,R12 ANDQ DX,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ DX,R14 ANDQ DX,R14
ADDQ R13,R14 ADDQ R13,R14
IMUL3Q $19,R15,CX IMUL3Q $19,R15,CX
@@ -731,18 +731,18 @@ TEXT ·ladderstep(SB),0,$296-8
ADDQ AX,R12 ADDQ AX,R12
ADCQ DX,R13 ADCQ DX,R13
MOVQ $REDMASK51,DX MOVQ $REDMASK51,DX
SHLQ $13,CX:SI SHLQ $13,SI,CX
ANDQ DX,SI ANDQ DX,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ DX,R8 ANDQ DX,R8
ADDQ CX,R8 ADDQ CX,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ DX,R10 ANDQ DX,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ DX,R12 ANDQ DX,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ DX,R14 ANDQ DX,R14
ADDQ R13,R14 ADDQ R13,R14
IMUL3Q $19,R15,CX IMUL3Q $19,R15,CX
@@ -846,18 +846,18 @@ TEXT ·ladderstep(SB),0,$296-8
ADDQ AX,R12 ADDQ AX,R12
ADCQ DX,R13 ADCQ DX,R13
MOVQ $REDMASK51,DX MOVQ $REDMASK51,DX
SHLQ $13,CX:SI SHLQ $13,SI,CX
ANDQ DX,SI ANDQ DX,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ DX,R8 ANDQ DX,R8
ADDQ CX,R8 ADDQ CX,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ DX,R10 ANDQ DX,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ DX,R12 ANDQ DX,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ DX,R14 ANDQ DX,R14
ADDQ R13,R14 ADDQ R13,R14
IMUL3Q $19,R15,CX IMUL3Q $19,R15,CX
@@ -996,18 +996,18 @@ TEXT ·ladderstep(SB),0,$296-8
ADDQ AX,R12 ADDQ AX,R12
ADCQ DX,R13 ADCQ DX,R13
MOVQ $REDMASK51,DX MOVQ $REDMASK51,DX
SHLQ $13,CX:SI SHLQ $13,SI,CX
ANDQ DX,SI ANDQ DX,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ DX,R8 ANDQ DX,R8
ADDQ CX,R8 ADDQ CX,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ DX,R10 ANDQ DX,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ DX,R12 ANDQ DX,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ DX,R14 ANDQ DX,R14
ADDQ R13,R14 ADDQ R13,R14
IMUL3Q $19,R15,CX IMUL3Q $19,R15,CX
@@ -1146,18 +1146,18 @@ TEXT ·ladderstep(SB),0,$296-8
ADDQ AX,R12 ADDQ AX,R12
ADCQ DX,R13 ADCQ DX,R13
MOVQ $REDMASK51,DX MOVQ $REDMASK51,DX
SHLQ $13,CX:SI SHLQ $13,SI,CX
ANDQ DX,SI ANDQ DX,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ DX,R8 ANDQ DX,R8
ADDQ CX,R8 ADDQ CX,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ DX,R10 ANDQ DX,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ DX,R12 ANDQ DX,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ DX,R14 ANDQ DX,R14
ADDQ R13,R14 ADDQ R13,R14
IMUL3Q $19,R15,CX IMUL3Q $19,R15,CX
@@ -1332,18 +1332,18 @@ TEXT ·ladderstep(SB),0,$296-8
ADDQ AX,R12 ADDQ AX,R12
ADCQ DX,R13 ADCQ DX,R13
MOVQ $REDMASK51,DX MOVQ $REDMASK51,DX
SHLQ $13,CX:SI SHLQ $13,SI,CX
ANDQ DX,SI ANDQ DX,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ DX,R8 ANDQ DX,R8
ADDQ CX,R8 ADDQ CX,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ DX,R10 ANDQ DX,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ DX,R12 ANDQ DX,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ DX,R14 ANDQ DX,R14
ADDQ R13,R14 ADDQ R13,R14
IMUL3Q $19,R15,CX IMUL3Q $19,R15,CX

View File

@@ -124,18 +124,18 @@ TEXT ·mul(SB),0,$16-24
ADDQ AX,R14 ADDQ AX,R14
ADCQ DX,R15 ADCQ DX,R15
MOVQ $REDMASK51,SI MOVQ $REDMASK51,SI
SHLQ $13,R9:R8 SHLQ $13,R8,R9
ANDQ SI,R8 ANDQ SI,R8
SHLQ $13,R11:R10 SHLQ $13,R10,R11
ANDQ SI,R10 ANDQ SI,R10
ADDQ R9,R10 ADDQ R9,R10
SHLQ $13,R13:R12 SHLQ $13,R12,R13
ANDQ SI,R12 ANDQ SI,R12
ADDQ R11,R12 ADDQ R11,R12
SHLQ $13,R15:R14 SHLQ $13,R14,R15
ANDQ SI,R14 ANDQ SI,R14
ADDQ R13,R14 ADDQ R13,R14
SHLQ $13,BP:BX SHLQ $13,BX,BP
ANDQ SI,BX ANDQ SI,BX
ADDQ R15,BX ADDQ R15,BX
IMUL3Q $19,BP,DX IMUL3Q $19,BP,DX

View File

@@ -87,18 +87,18 @@ TEXT ·square(SB),7,$0-16
ADDQ AX,R13 ADDQ AX,R13
ADCQ DX,R14 ADCQ DX,R14
MOVQ $REDMASK51,SI MOVQ $REDMASK51,SI
SHLQ $13,R8:CX SHLQ $13,CX,R8
ANDQ SI,CX ANDQ SI,CX
SHLQ $13,R10:R9 SHLQ $13,R9,R10
ANDQ SI,R9 ANDQ SI,R9
ADDQ R8,R9 ADDQ R8,R9
SHLQ $13,R12:R11 SHLQ $13,R11,R12
ANDQ SI,R11 ANDQ SI,R11
ADDQ R10,R11 ADDQ R10,R11
SHLQ $13,R14:R13 SHLQ $13,R13,R14
ANDQ SI,R13 ANDQ SI,R13
ADDQ R12,R13 ADDQ R12,R13
SHLQ $13,BX:R15 SHLQ $13,R15,BX
ANDQ SI,R15 ANDQ SI,R15
ADDQ R14,R15 ADDQ R14,R15
IMUL3Q $19,BX,DX IMUL3Q $19,BX,DX

View File

@@ -0,0 +1,93 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package curve25519
// testVectors generated with BoringSSL.
var testVectors = []struct {
In [32]byte
Base [32]byte
Expect [32]byte
}{
{
In: [32]byte{0x66, 0x8f, 0xb9, 0xf7, 0x6a, 0xd9, 0x71, 0xc8, 0x1a, 0xc9, 0x0, 0x7, 0x1a, 0x15, 0x60, 0xbc, 0xe2, 0xca, 0x0, 0xca, 0xc7, 0xe6, 0x7a, 0xf9, 0x93, 0x48, 0x91, 0x37, 0x61, 0x43, 0x40, 0x14},
Base: [32]byte{0xdb, 0x5f, 0x32, 0xb7, 0xf8, 0x41, 0xe7, 0xa1, 0xa0, 0x9, 0x68, 0xef, 0xfd, 0xed, 0x12, 0x73, 0x5f, 0xc4, 0x7a, 0x3e, 0xb1, 0x3b, 0x57, 0x9a, 0xac, 0xad, 0xea, 0xe8, 0x9, 0x39, 0xa7, 0xdd},
Expect: [32]byte{0x9, 0xd, 0x85, 0xe5, 0x99, 0xea, 0x8e, 0x2b, 0xee, 0xb6, 0x13, 0x4, 0xd3, 0x7b, 0xe1, 0xe, 0xc5, 0xc9, 0x5, 0xf9, 0x92, 0x7d, 0x32, 0xf4, 0x2a, 0x9a, 0xa, 0xfb, 0x3e, 0xb, 0x40, 0x74},
},
{
In: [32]byte{0x63, 0x66, 0x95, 0xe3, 0x4f, 0x75, 0xb9, 0xa2, 0x79, 0xc8, 0x70, 0x6f, 0xad, 0x12, 0x89, 0xf2, 0xc0, 0xb1, 0xe2, 0x2e, 0x16, 0xf8, 0xb8, 0x86, 0x17, 0x29, 0xc1, 0xa, 0x58, 0x29, 0x58, 0xaf},
Base: [32]byte{0x9, 0xd, 0x7, 0x1, 0xf8, 0xfd, 0xe2, 0x8f, 0x70, 0x4, 0x3b, 0x83, 0xf2, 0x34, 0x62, 0x25, 0x41, 0x9b, 0x18, 0xa7, 0xf2, 0x7e, 0x9e, 0x3d, 0x2b, 0xfd, 0x4, 0xe1, 0xf, 0x3d, 0x21, 0x3e},
Expect: [32]byte{0xbf, 0x26, 0xec, 0x7e, 0xc4, 0x13, 0x6, 0x17, 0x33, 0xd4, 0x40, 0x70, 0xea, 0x67, 0xca, 0xb0, 0x2a, 0x85, 0xdc, 0x1b, 0xe8, 0xcf, 0xe1, 0xff, 0x73, 0xd5, 0x41, 0xcc, 0x8, 0x32, 0x55, 0x6},
},
{
In: [32]byte{0x73, 0x41, 0x81, 0xcd, 0x1a, 0x94, 0x6, 0x52, 0x2a, 0x56, 0xfe, 0x25, 0xe4, 0x3e, 0xcb, 0xf0, 0x29, 0x5d, 0xb5, 0xdd, 0xd0, 0x60, 0x9b, 0x3c, 0x2b, 0x4e, 0x79, 0xc0, 0x6f, 0x8b, 0xd4, 0x6d},
Base: [32]byte{0xf8, 0xa8, 0x42, 0x1c, 0x7d, 0x21, 0xa9, 0x2d, 0xb3, 0xed, 0xe9, 0x79, 0xe1, 0xfa, 0x6a, 0xcb, 0x6, 0x2b, 0x56, 0xb1, 0x88, 0x5c, 0x71, 0xc5, 0x11, 0x53, 0xcc, 0xb8, 0x80, 0xac, 0x73, 0x15},
Expect: [32]byte{0x11, 0x76, 0xd0, 0x16, 0x81, 0xf2, 0xcf, 0x92, 0x9d, 0xa2, 0xc7, 0xa3, 0xdf, 0x66, 0xb5, 0xd7, 0x72, 0x9f, 0xd4, 0x22, 0x22, 0x6f, 0xd6, 0x37, 0x42, 0x16, 0xbf, 0x7e, 0x2, 0xfd, 0xf, 0x62},
},
{
In: [32]byte{0x1f, 0x70, 0x39, 0x1f, 0x6b, 0xa8, 0x58, 0x12, 0x94, 0x13, 0xbd, 0x80, 0x1b, 0x12, 0xac, 0xbf, 0x66, 0x23, 0x62, 0x82, 0x5c, 0xa2, 0x50, 0x9c, 0x81, 0x87, 0x59, 0xa, 0x2b, 0xe, 0x61, 0x72},
Base: [32]byte{0xd3, 0xea, 0xd0, 0x7a, 0x0, 0x8, 0xf4, 0x45, 0x2, 0xd5, 0x80, 0x8b, 0xff, 0xc8, 0x97, 0x9f, 0x25, 0xa8, 0x59, 0xd5, 0xad, 0xf4, 0x31, 0x2e, 0xa4, 0x87, 0x48, 0x9c, 0x30, 0xe0, 0x1b, 0x3b},
Expect: [32]byte{0xf8, 0x48, 0x2f, 0x2e, 0x9e, 0x58, 0xbb, 0x6, 0x7e, 0x86, 0xb2, 0x87, 0x24, 0xb3, 0xc0, 0xa3, 0xbb, 0xb5, 0x7, 0x3e, 0x4c, 0x6a, 0xcd, 0x93, 0xdf, 0x54, 0x5e, 0xff, 0xdb, 0xba, 0x50, 0x5f},
},
{
In: [32]byte{0x3a, 0x7a, 0xe6, 0xcf, 0x8b, 0x88, 0x9d, 0x2b, 0x7a, 0x60, 0xa4, 0x70, 0xad, 0x6a, 0xd9, 0x99, 0x20, 0x6b, 0xf5, 0x7d, 0x90, 0x30, 0xdd, 0xf7, 0xf8, 0x68, 0xc, 0x8b, 0x1a, 0x64, 0x5d, 0xaa},
Base: [32]byte{0x4d, 0x25, 0x4c, 0x80, 0x83, 0xd8, 0x7f, 0x1a, 0x9b, 0x3e, 0xa7, 0x31, 0xef, 0xcf, 0xf8, 0xa6, 0xf2, 0x31, 0x2d, 0x6f, 0xed, 0x68, 0xe, 0xf8, 0x29, 0x18, 0x51, 0x61, 0xc8, 0xfc, 0x50, 0x60},
Expect: [32]byte{0x47, 0xb3, 0x56, 0xd5, 0x81, 0x8d, 0xe8, 0xef, 0xac, 0x77, 0x4b, 0x71, 0x4c, 0x42, 0xc4, 0x4b, 0xe6, 0x85, 0x23, 0xdd, 0x57, 0xdb, 0xd7, 0x39, 0x62, 0xd5, 0xa5, 0x26, 0x31, 0x87, 0x62, 0x37},
},
{
In: [32]byte{0x20, 0x31, 0x61, 0xc3, 0x15, 0x9a, 0x87, 0x6a, 0x2b, 0xea, 0xec, 0x29, 0xd2, 0x42, 0x7f, 0xb0, 0xc7, 0xc3, 0xd, 0x38, 0x2c, 0xd0, 0x13, 0xd2, 0x7c, 0xc3, 0xd3, 0x93, 0xdb, 0xd, 0xaf, 0x6f},
Base: [32]byte{0x6a, 0xb9, 0x5d, 0x1a, 0xbe, 0x68, 0xc0, 0x9b, 0x0, 0x5c, 0x3d, 0xb9, 0x4, 0x2c, 0xc9, 0x1a, 0xc8, 0x49, 0xf7, 0xe9, 0x4a, 0x2a, 0x4a, 0x9b, 0x89, 0x36, 0x78, 0x97, 0xb, 0x7b, 0x95, 0xbf},
Expect: [32]byte{0x11, 0xed, 0xae, 0xdc, 0x95, 0xff, 0x78, 0xf5, 0x63, 0xa1, 0xc8, 0xf1, 0x55, 0x91, 0xc0, 0x71, 0xde, 0xa0, 0x92, 0xb4, 0xd7, 0xec, 0xaa, 0xc8, 0xe0, 0x38, 0x7b, 0x5a, 0x16, 0xc, 0x4e, 0x5d},
},
{
In: [32]byte{0x13, 0xd6, 0x54, 0x91, 0xfe, 0x75, 0xf2, 0x3, 0xa0, 0x8, 0xb4, 0x41, 0x5a, 0xbc, 0x60, 0xd5, 0x32, 0xe6, 0x95, 0xdb, 0xd2, 0xf1, 0xe8, 0x3, 0xac, 0xcb, 0x34, 0xb2, 0xb7, 0x2c, 0x3d, 0x70},
Base: [32]byte{0x2e, 0x78, 0x4e, 0x4, 0xca, 0x0, 0x73, 0x33, 0x62, 0x56, 0xa8, 0x39, 0x25, 0x5e, 0xd2, 0xf7, 0xd4, 0x79, 0x6a, 0x64, 0xcd, 0xc3, 0x7f, 0x1e, 0xb0, 0xe5, 0xc4, 0xc8, 0xd1, 0xd1, 0xe0, 0xf5},
Expect: [32]byte{0x56, 0x3e, 0x8c, 0x9a, 0xda, 0xa7, 0xd7, 0x31, 0x1, 0xb0, 0xf2, 0xea, 0xd3, 0xca, 0xe1, 0xea, 0x5d, 0x8f, 0xcd, 0x5c, 0xd3, 0x60, 0x80, 0xbb, 0x8e, 0x6e, 0xc0, 0x3d, 0x61, 0x45, 0x9, 0x17},
},
{
In: [32]byte{0x68, 0x6f, 0x7d, 0xa9, 0x3b, 0xf2, 0x68, 0xe5, 0x88, 0x6, 0x98, 0x31, 0xf0, 0x47, 0x16, 0x3f, 0x33, 0x58, 0x99, 0x89, 0xd0, 0x82, 0x6e, 0x98, 0x8, 0xfb, 0x67, 0x8e, 0xd5, 0x7e, 0x67, 0x49},
Base: [32]byte{0x8b, 0x54, 0x9b, 0x2d, 0xf6, 0x42, 0xd3, 0xb2, 0x5f, 0xe8, 0x38, 0xf, 0x8c, 0xc4, 0x37, 0x5f, 0x99, 0xb7, 0xbb, 0x4d, 0x27, 0x5f, 0x77, 0x9f, 0x3b, 0x7c, 0x81, 0xb8, 0xa2, 0xbb, 0xc1, 0x29},
Expect: [32]byte{0x1, 0x47, 0x69, 0x65, 0x42, 0x6b, 0x61, 0x71, 0x74, 0x9a, 0x8a, 0xdd, 0x92, 0x35, 0x2, 0x5c, 0xe5, 0xf5, 0x57, 0xfe, 0x40, 0x9, 0xf7, 0x39, 0x30, 0x44, 0xeb, 0xbb, 0x8a, 0xe9, 0x52, 0x79},
},
{
In: [32]byte{0x82, 0xd6, 0x1c, 0xce, 0xdc, 0x80, 0x6a, 0x60, 0x60, 0xa3, 0x34, 0x9a, 0x5e, 0x87, 0xcb, 0xc7, 0xac, 0x11, 0x5e, 0x4f, 0x87, 0x77, 0x62, 0x50, 0xae, 0x25, 0x60, 0x98, 0xa7, 0xc4, 0x49, 0x59},
Base: [32]byte{0x8b, 0x6b, 0x9d, 0x8, 0xf6, 0x1f, 0xc9, 0x1f, 0xe8, 0xb3, 0x29, 0x53, 0xc4, 0x23, 0x40, 0xf0, 0x7, 0xb5, 0x71, 0xdc, 0xb0, 0xa5, 0x6d, 0x10, 0x72, 0x4e, 0xce, 0xf9, 0x95, 0xc, 0xfb, 0x25},
Expect: [32]byte{0x9c, 0x49, 0x94, 0x1f, 0x9c, 0x4f, 0x18, 0x71, 0xfa, 0x40, 0x91, 0xfe, 0xd7, 0x16, 0xd3, 0x49, 0x99, 0xc9, 0x52, 0x34, 0xed, 0xf2, 0xfd, 0xfb, 0xa6, 0xd1, 0x4a, 0x5a, 0xfe, 0x9e, 0x5, 0x58},
},
{
In: [32]byte{0x7d, 0xc7, 0x64, 0x4, 0x83, 0x13, 0x97, 0xd5, 0x88, 0x4f, 0xdf, 0x6f, 0x97, 0xe1, 0x74, 0x4c, 0x9e, 0xb1, 0x18, 0xa3, 0x1a, 0x7b, 0x23, 0xf8, 0xd7, 0x9f, 0x48, 0xce, 0x9c, 0xad, 0x15, 0x4b},
Base: [32]byte{0x1a, 0xcd, 0x29, 0x27, 0x84, 0xf4, 0x79, 0x19, 0xd4, 0x55, 0xf8, 0x87, 0x44, 0x83, 0x58, 0x61, 0xb, 0xb9, 0x45, 0x96, 0x70, 0xeb, 0x99, 0xde, 0xe4, 0x60, 0x5, 0xf6, 0x89, 0xca, 0x5f, 0xb6},
Expect: [32]byte{0x0, 0xf4, 0x3c, 0x2, 0x2e, 0x94, 0xea, 0x38, 0x19, 0xb0, 0x36, 0xae, 0x2b, 0x36, 0xb2, 0xa7, 0x61, 0x36, 0xaf, 0x62, 0x8a, 0x75, 0x1f, 0xe5, 0xd0, 0x1e, 0x3, 0xd, 0x44, 0x25, 0x88, 0x59},
},
{
In: [32]byte{0xfb, 0xc4, 0x51, 0x1d, 0x23, 0xa6, 0x82, 0xae, 0x4e, 0xfd, 0x8, 0xc8, 0x17, 0x9c, 0x1c, 0x6, 0x7f, 0x9c, 0x8b, 0xe7, 0x9b, 0xbc, 0x4e, 0xff, 0x5c, 0xe2, 0x96, 0xc6, 0xbc, 0x1f, 0xf4, 0x45},
Base: [32]byte{0x55, 0xca, 0xff, 0x21, 0x81, 0xf2, 0x13, 0x6b, 0xe, 0xd0, 0xe1, 0xe2, 0x99, 0x44, 0x48, 0xe1, 0x6c, 0xc9, 0x70, 0x64, 0x6a, 0x98, 0x3d, 0x14, 0xd, 0xc4, 0xea, 0xb3, 0xd9, 0x4c, 0x28, 0x4e},
Expect: [32]byte{0xae, 0x39, 0xd8, 0x16, 0x53, 0x23, 0x45, 0x79, 0x4d, 0x26, 0x91, 0xe0, 0x80, 0x1c, 0xaa, 0x52, 0x5f, 0xc3, 0x63, 0x4d, 0x40, 0x2c, 0xe9, 0x58, 0xb, 0x33, 0x38, 0xb4, 0x6f, 0x8b, 0xb9, 0x72},
},
{
In: [32]byte{0x4e, 0x6, 0xc, 0xe1, 0xc, 0xeb, 0xf0, 0x95, 0x9, 0x87, 0x16, 0xc8, 0x66, 0x19, 0xeb, 0x9f, 0x7d, 0xf6, 0x65, 0x24, 0x69, 0x8b, 0xa7, 0x98, 0x8c, 0x3b, 0x90, 0x95, 0xd9, 0xf5, 0x1, 0x34},
Base: [32]byte{0x57, 0x73, 0x3f, 0x2d, 0x86, 0x96, 0x90, 0xd0, 0xd2, 0xed, 0xae, 0xc9, 0x52, 0x3d, 0xaa, 0x2d, 0xa9, 0x54, 0x45, 0xf4, 0x4f, 0x57, 0x83, 0xc1, 0xfa, 0xec, 0x6c, 0x3a, 0x98, 0x28, 0x18, 0xf3},
Expect: [32]byte{0xa6, 0x1e, 0x74, 0x55, 0x2c, 0xce, 0x75, 0xf5, 0xe9, 0x72, 0xe4, 0x24, 0xf2, 0xcc, 0xb0, 0x9c, 0x83, 0xbc, 0x1b, 0x67, 0x1, 0x47, 0x48, 0xf0, 0x2c, 0x37, 0x1a, 0x20, 0x9e, 0xf2, 0xfb, 0x2c},
},
{
In: [32]byte{0x5c, 0x49, 0x2c, 0xba, 0x2c, 0xc8, 0x92, 0x48, 0x8a, 0x9c, 0xeb, 0x91, 0x86, 0xc2, 0xaa, 0xc2, 0x2f, 0x1, 0x5b, 0xf3, 0xef, 0x8d, 0x3e, 0xcc, 0x9c, 0x41, 0x76, 0x97, 0x62, 0x61, 0xaa, 0xb1},
Base: [32]byte{0x67, 0x97, 0xc2, 0xe7, 0xdc, 0x92, 0xcc, 0xbe, 0x7c, 0x5, 0x6b, 0xec, 0x35, 0xa, 0xb6, 0xd3, 0xbd, 0x2a, 0x2c, 0x6b, 0xc5, 0xa8, 0x7, 0xbb, 0xca, 0xe1, 0xf6, 0xc2, 0xaf, 0x80, 0x36, 0x44},
Expect: [32]byte{0xfc, 0xf3, 0x7, 0xdf, 0xbc, 0x19, 0x2, 0xb, 0x28, 0xa6, 0x61, 0x8c, 0x6c, 0x62, 0x2f, 0x31, 0x7e, 0x45, 0x96, 0x7d, 0xac, 0xf4, 0xae, 0x4a, 0xa, 0x69, 0x9a, 0x10, 0x76, 0x9f, 0xde, 0x14},
},
{
In: [32]byte{0xea, 0x33, 0x34, 0x92, 0x96, 0x5, 0x5a, 0x4e, 0x8b, 0x19, 0x2e, 0x3c, 0x23, 0xc5, 0xf4, 0xc8, 0x44, 0x28, 0x2a, 0x3b, 0xfc, 0x19, 0xec, 0xc9, 0xdc, 0x64, 0x6a, 0x42, 0xc3, 0x8d, 0xc2, 0x48},
Base: [32]byte{0x2c, 0x75, 0xd8, 0x51, 0x42, 0xec, 0xad, 0x3e, 0x69, 0x44, 0x70, 0x4, 0x54, 0xc, 0x1c, 0x23, 0x54, 0x8f, 0xc8, 0xf4, 0x86, 0x25, 0x1b, 0x8a, 0x19, 0x46, 0x3f, 0x3d, 0xf6, 0xf8, 0xac, 0x61},
Expect: [32]byte{0x5d, 0xca, 0xb6, 0x89, 0x73, 0xf9, 0x5b, 0xd3, 0xae, 0x4b, 0x34, 0xfa, 0xb9, 0x49, 0xfb, 0x7f, 0xb1, 0x5a, 0xf1, 0xd8, 0xca, 0xe2, 0x8c, 0xd6, 0x99, 0xf9, 0xc1, 0xaa, 0x33, 0x37, 0x34, 0x2f},
},
{
In: [32]byte{0x4f, 0x29, 0x79, 0xb1, 0xec, 0x86, 0x19, 0xe4, 0x5c, 0xa, 0xb, 0x2b, 0x52, 0x9, 0x34, 0x54, 0x1a, 0xb9, 0x44, 0x7, 0xb6, 0x4d, 0x19, 0xa, 0x76, 0xf3, 0x23, 0x14, 0xef, 0xe1, 0x84, 0xe7},
Base: [32]byte{0xf7, 0xca, 0xe1, 0x8d, 0x8d, 0x36, 0xa7, 0xf5, 0x61, 0x17, 0xb8, 0xb7, 0xe, 0x25, 0x52, 0x27, 0x7f, 0xfc, 0x99, 0xdf, 0x87, 0x56, 0xb5, 0xe1, 0x38, 0xbf, 0x63, 0x68, 0xbc, 0x87, 0xf7, 0x4c},
Expect: [32]byte{0xe4, 0xe6, 0x34, 0xeb, 0xb4, 0xfb, 0x66, 0x4f, 0xe8, 0xb2, 0xcf, 0xa1, 0x61, 0x5f, 0x0, 0xe6, 0x46, 0x6f, 0xff, 0x73, 0x2c, 0xe1, 0xf8, 0xa0, 0xc8, 0xd2, 0x72, 0x74, 0x31, 0xd1, 0x6f, 0x14},
},
{
In: [32]byte{0xf5, 0xd8, 0xa9, 0x27, 0x90, 0x1d, 0x4f, 0xa4, 0x24, 0x90, 0x86, 0xb7, 0xff, 0xec, 0x24, 0xf5, 0x29, 0x7d, 0x80, 0x11, 0x8e, 0x4a, 0xc9, 0xd3, 0xfc, 0x9a, 0x82, 0x37, 0x95, 0x1e, 0x3b, 0x7f},
Base: [32]byte{0x3c, 0x23, 0x5e, 0xdc, 0x2, 0xf9, 0x11, 0x56, 0x41, 0xdb, 0xf5, 0x16, 0xd5, 0xde, 0x8a, 0x73, 0x5d, 0x6e, 0x53, 0xe2, 0x2a, 0xa2, 0xac, 0x14, 0x36, 0x56, 0x4, 0x5f, 0xf2, 0xe9, 0x52, 0x49},
Expect: [32]byte{0xab, 0x95, 0x15, 0xab, 0x14, 0xaf, 0x9d, 0x27, 0xe, 0x1d, 0xae, 0xc, 0x56, 0x80, 0xcb, 0xc8, 0x88, 0xb, 0xd8, 0xa8, 0xe7, 0xeb, 0x67, 0xb4, 0xda, 0x42, 0xa6, 0x61, 0x96, 0x1e, 0xfc, 0xb},
},
}

View File

@@ -2,6 +2,11 @@
// 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.
// In Go 1.13, the ed25519 package was promoted to the standard library as
// crypto/ed25519, and this package became a wrapper for the standard library one.
//
// +build !go1.13
// Package ed25519 implements the Ed25519 signature algorithm. See // Package ed25519 implements the Ed25519 signature algorithm. See
// https://ed25519.cr.yp.to/. // https://ed25519.cr.yp.to/.
// //

73
vendor/golang.org/x/crypto/ed25519/ed25519_go113.go generated vendored Normal file
View File

@@ -0,0 +1,73 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.13
// Package ed25519 implements the Ed25519 signature algorithm. See
// https://ed25519.cr.yp.to/.
//
// These functions are also compatible with the “Ed25519” function defined in
// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
// representation includes a public key suffix to make multiple signing
// operations with the same key more efficient. This package refers to the RFC
// 8032 private key as the “seed”.
//
// Beginning with Go 1.13, the functionality of this package was moved to the
// standard library as crypto/ed25519. This package only acts as a compatibility
// wrapper.
package ed25519
import (
"crypto/ed25519"
"io"
)
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
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
SeedSize = 32
)
// PublicKey is the type of Ed25519 public keys.
//
// This type is an alias for crypto/ed25519's PublicKey type.
// See the crypto/ed25519 package for the methods on this type.
type PublicKey = ed25519.PublicKey
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
//
// This type is an alias for crypto/ed25519's PrivateKey type.
// See the crypto/ed25519 package for the methods on this type.
type PrivateKey = ed25519.PrivateKey
// GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
return ed25519.GenerateKey(rand)
}
// NewKeyFromSeed calculates a private key from a seed. It will panic if
// len(seed) is not SeedSize. This function is provided for interoperability
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
// package.
func NewKeyFromSeed(seed []byte) PrivateKey {
return ed25519.NewKeyFromSeed(seed)
}
// 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 {
return ed25519.Sign(privateKey, message)
}
// 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 {
return ed25519.Verify(publicKey, message, sig)
}

View File

@@ -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.
package ed25519 package ed25519_test
import ( import (
"bufio" "bufio"
@@ -15,6 +15,7 @@ import (
"strings" "strings"
"testing" "testing"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ed25519/internal/edwards25519" "golang.org/x/crypto/ed25519/internal/edwards25519"
) )
@@ -28,7 +29,7 @@ func (zeroReader) Read(buf []byte) (int, error) {
} }
func TestUnmarshalMarshal(t *testing.T) { func TestUnmarshalMarshal(t *testing.T) {
pub, _, _ := GenerateKey(rand.Reader) pub, _, _ := ed25519.GenerateKey(rand.Reader)
var A edwards25519.ExtendedGroupElement var A edwards25519.ExtendedGroupElement
var pubBytes [32]byte var pubBytes [32]byte
@@ -47,28 +48,28 @@ func TestUnmarshalMarshal(t *testing.T) {
func TestSignVerify(t *testing.T) { func TestSignVerify(t *testing.T) {
var zero zeroReader var zero zeroReader
public, private, _ := GenerateKey(zero) public, private, _ := ed25519.GenerateKey(zero)
message := []byte("test message") message := []byte("test message")
sig := Sign(private, message) sig := ed25519.Sign(private, message)
if !Verify(public, message, sig) { if !ed25519.Verify(public, message, sig) {
t.Errorf("valid signature rejected") t.Errorf("valid signature rejected")
} }
wrongMessage := []byte("wrong message") wrongMessage := []byte("wrong message")
if Verify(public, wrongMessage, sig) { if ed25519.Verify(public, wrongMessage, sig) {
t.Errorf("signature of different message accepted") t.Errorf("signature of different message accepted")
} }
} }
func TestCryptoSigner(t *testing.T) { func TestCryptoSigner(t *testing.T) {
var zero zeroReader var zero zeroReader
public, private, _ := GenerateKey(zero) public, private, _ := ed25519.GenerateKey(zero)
signer := crypto.Signer(private) signer := crypto.Signer(private)
publicInterface := signer.Public() publicInterface := signer.Public()
public2, ok := publicInterface.(PublicKey) public2, ok := publicInterface.(ed25519.PublicKey)
if !ok { if !ok {
t.Fatalf("expected PublicKey from Public() but got %T", publicInterface) t.Fatalf("expected PublicKey from Public() but got %T", publicInterface)
} }
@@ -84,7 +85,7 @@ func TestCryptoSigner(t *testing.T) {
t.Fatalf("error from Sign(): %s", err) t.Fatalf("error from Sign(): %s", err)
} }
if !Verify(public, message, signature) { if !ed25519.Verify(public, message, signature) {
t.Errorf("Verify failed on signature from Sign()") t.Errorf("Verify failed on signature from Sign()")
} }
} }
@@ -121,31 +122,31 @@ func TestGolden(t *testing.T) {
sig, _ := hex.DecodeString(parts[3]) sig, _ := hex.DecodeString(parts[3])
// The signatures in the test vectors also include the message // The signatures in the test vectors also include the message
// at the end, but we just want R and S. // at the end, but we just want R and S.
sig = sig[:SignatureSize] sig = sig[:ed25519.SignatureSize]
if l := len(pubKey); l != PublicKeySize { if l := len(pubKey); l != ed25519.PublicKeySize {
t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l) t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l)
} }
var priv [PrivateKeySize]byte var priv [ed25519.PrivateKeySize]byte
copy(priv[:], privBytes) copy(priv[:], privBytes)
copy(priv[32:], pubKey) copy(priv[32:], pubKey)
sig2 := Sign(priv[:], msg) sig2 := ed25519.Sign(priv[:], msg)
if !bytes.Equal(sig, sig2[:]) { if !bytes.Equal(sig, sig2[:]) {
t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2) t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2)
} }
if !Verify(pubKey, msg, sig2) { if !ed25519.Verify(pubKey, msg, sig2) {
t.Errorf("signature failed to verify on line %d", lineNo) t.Errorf("signature failed to verify on line %d", lineNo)
} }
priv2 := NewKeyFromSeed(priv[:32]) priv2 := ed25519.NewKeyFromSeed(priv[:32])
if !bytes.Equal(priv[:], priv2) { if !bytes.Equal(priv[:], priv2) {
t.Errorf("recreating key pair gave different private key on line %d: %x vs %x", lineNo, priv[:], priv2) t.Errorf("recreating key pair gave different private key on line %d: %x vs %x", lineNo, priv[:], priv2)
} }
if pubKey2 := priv2.Public().(PublicKey); !bytes.Equal(pubKey, pubKey2) { if pubKey2 := priv2.Public().(ed25519.PublicKey); !bytes.Equal(pubKey, pubKey2) {
t.Errorf("recreating key pair gave different public key on line %d: %x vs %x", lineNo, pubKey, pubKey2) t.Errorf("recreating key pair gave different public key on line %d: %x vs %x", lineNo, pubKey, pubKey2)
} }
@@ -178,7 +179,7 @@ func TestMalleability(t *testing.T) {
0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa, 0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa,
} }
if Verify(publicKey, msg, sig) { if ed25519.Verify(publicKey, msg, sig) {
t.Fatal("non-canonical signature accepted") t.Fatal("non-canonical signature accepted")
} }
} }
@@ -186,7 +187,7 @@ func TestMalleability(t *testing.T) {
func BenchmarkKeyGeneration(b *testing.B) { func BenchmarkKeyGeneration(b *testing.B) {
var zero zeroReader var zero zeroReader
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
if _, _, err := GenerateKey(zero); err != nil { if _, _, err := ed25519.GenerateKey(zero); err != nil {
b.Fatal(err) b.Fatal(err)
} }
} }
@@ -194,27 +195,27 @@ func BenchmarkKeyGeneration(b *testing.B) {
func BenchmarkSigning(b *testing.B) { func BenchmarkSigning(b *testing.B) {
var zero zeroReader var zero zeroReader
_, priv, err := GenerateKey(zero) _, priv, err := ed25519.GenerateKey(zero)
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
message := []byte("Hello, world!") message := []byte("Hello, world!")
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Sign(priv, message) ed25519.Sign(priv, message)
} }
} }
func BenchmarkVerification(b *testing.B) { func BenchmarkVerification(b *testing.B) {
var zero zeroReader var zero zeroReader
pub, priv, err := GenerateKey(zero) pub, priv, err := ed25519.GenerateKey(zero)
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
message := []byte("Hello, world!") message := []byte("Hello, world!")
signature := Sign(priv, message) signature := ed25519.Sign(priv, message)
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Verify(pub, message, signature) ed25519.Verify(pub, message, signature)
} }
} }

24
vendor/golang.org/x/crypto/ed25519/go113_test.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.13
package ed25519_test
import (
ed25519std "crypto/ed25519"
"golang.org/x/crypto/ed25519"
"testing"
)
func TestTypeAlias(t *testing.T) {
var zero zeroReader
public, private, _ := ed25519std.GenerateKey(zero)
message := []byte("test message")
sig := ed25519.Sign(private, message)
if !ed25519.Verify(public, message, sig) {
t.Errorf("valid signature rejected")
}
}

6
vendor/golang.org/x/crypto/go.mod generated vendored Normal file
View File

@@ -0,0 +1,6 @@
module golang.org/x/crypto
require (
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3
golang.org/x/sys v0.0.0-20190412213103-97732733099d
)

8
vendor/golang.org/x/crypto/go.sum generated vendored Normal file
View File

@@ -0,0 +1,8 @@
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@@ -0,0 +1,308 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.11
// +build !gccgo,!appengine
#include "textflag.h"
#define NUM_ROUNDS 10
// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
MOVD dst+0(FP), R1
MOVD src+24(FP), R2
MOVD src_len+32(FP), R3
MOVD key+48(FP), R4
MOVD nonce+56(FP), R6
MOVD counter+64(FP), R7
MOVD $·constants(SB), R10
MOVD $·incRotMatrix(SB), R11
MOVW (R7), R20
AND $~255, R3, R13
ADD R2, R13, R12 // R12 for block end
AND $255, R3, R13
loop:
MOVD $NUM_ROUNDS, R21
VLD1 (R11), [V30.S4, V31.S4]
// load contants
// VLD4R (R10), [V0.S4, V1.S4, V2.S4, V3.S4]
WORD $0x4D60E940
// load keys
// VLD4R 16(R4), [V4.S4, V5.S4, V6.S4, V7.S4]
WORD $0x4DFFE884
// VLD4R 16(R4), [V8.S4, V9.S4, V10.S4, V11.S4]
WORD $0x4DFFE888
SUB $32, R4
// load counter + nonce
// VLD1R (R7), [V12.S4]
WORD $0x4D40C8EC
// VLD3R (R6), [V13.S4, V14.S4, V15.S4]
WORD $0x4D40E8CD
// update counter
VADD V30.S4, V12.S4, V12.S4
chacha:
// V0..V3 += V4..V7
// V12..V15 <<<= ((V12..V15 XOR V0..V3), 16)
VADD V0.S4, V4.S4, V0.S4
VADD V1.S4, V5.S4, V1.S4
VADD V2.S4, V6.S4, V2.S4
VADD V3.S4, V7.S4, V3.S4
VEOR V12.B16, V0.B16, V12.B16
VEOR V13.B16, V1.B16, V13.B16
VEOR V14.B16, V2.B16, V14.B16
VEOR V15.B16, V3.B16, V15.B16
VREV32 V12.H8, V12.H8
VREV32 V13.H8, V13.H8
VREV32 V14.H8, V14.H8
VREV32 V15.H8, V15.H8
// V8..V11 += V12..V15
// V4..V7 <<<= ((V4..V7 XOR V8..V11), 12)
VADD V8.S4, V12.S4, V8.S4
VADD V9.S4, V13.S4, V9.S4
VADD V10.S4, V14.S4, V10.S4
VADD V11.S4, V15.S4, V11.S4
VEOR V8.B16, V4.B16, V16.B16
VEOR V9.B16, V5.B16, V17.B16
VEOR V10.B16, V6.B16, V18.B16
VEOR V11.B16, V7.B16, V19.B16
VSHL $12, V16.S4, V4.S4
VSHL $12, V17.S4, V5.S4
VSHL $12, V18.S4, V6.S4
VSHL $12, V19.S4, V7.S4
VSRI $20, V16.S4, V4.S4
VSRI $20, V17.S4, V5.S4
VSRI $20, V18.S4, V6.S4
VSRI $20, V19.S4, V7.S4
// V0..V3 += V4..V7
// V12..V15 <<<= ((V12..V15 XOR V0..V3), 8)
VADD V0.S4, V4.S4, V0.S4
VADD V1.S4, V5.S4, V1.S4
VADD V2.S4, V6.S4, V2.S4
VADD V3.S4, V7.S4, V3.S4
VEOR V12.B16, V0.B16, V12.B16
VEOR V13.B16, V1.B16, V13.B16
VEOR V14.B16, V2.B16, V14.B16
VEOR V15.B16, V3.B16, V15.B16
VTBL V31.B16, [V12.B16], V12.B16
VTBL V31.B16, [V13.B16], V13.B16
VTBL V31.B16, [V14.B16], V14.B16
VTBL V31.B16, [V15.B16], V15.B16
// V8..V11 += V12..V15
// V4..V7 <<<= ((V4..V7 XOR V8..V11), 7)
VADD V12.S4, V8.S4, V8.S4
VADD V13.S4, V9.S4, V9.S4
VADD V14.S4, V10.S4, V10.S4
VADD V15.S4, V11.S4, V11.S4
VEOR V8.B16, V4.B16, V16.B16
VEOR V9.B16, V5.B16, V17.B16
VEOR V10.B16, V6.B16, V18.B16
VEOR V11.B16, V7.B16, V19.B16
VSHL $7, V16.S4, V4.S4
VSHL $7, V17.S4, V5.S4
VSHL $7, V18.S4, V6.S4
VSHL $7, V19.S4, V7.S4
VSRI $25, V16.S4, V4.S4
VSRI $25, V17.S4, V5.S4
VSRI $25, V18.S4, V6.S4
VSRI $25, V19.S4, V7.S4
// V0..V3 += V5..V7, V4
// V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 16)
VADD V0.S4, V5.S4, V0.S4
VADD V1.S4, V6.S4, V1.S4
VADD V2.S4, V7.S4, V2.S4
VADD V3.S4, V4.S4, V3.S4
VEOR V15.B16, V0.B16, V15.B16
VEOR V12.B16, V1.B16, V12.B16
VEOR V13.B16, V2.B16, V13.B16
VEOR V14.B16, V3.B16, V14.B16
VREV32 V12.H8, V12.H8
VREV32 V13.H8, V13.H8
VREV32 V14.H8, V14.H8
VREV32 V15.H8, V15.H8
// V10 += V15; V5 <<<= ((V10 XOR V5), 12)
// ...
VADD V15.S4, V10.S4, V10.S4
VADD V12.S4, V11.S4, V11.S4
VADD V13.S4, V8.S4, V8.S4
VADD V14.S4, V9.S4, V9.S4
VEOR V10.B16, V5.B16, V16.B16
VEOR V11.B16, V6.B16, V17.B16
VEOR V8.B16, V7.B16, V18.B16
VEOR V9.B16, V4.B16, V19.B16
VSHL $12, V16.S4, V5.S4
VSHL $12, V17.S4, V6.S4
VSHL $12, V18.S4, V7.S4
VSHL $12, V19.S4, V4.S4
VSRI $20, V16.S4, V5.S4
VSRI $20, V17.S4, V6.S4
VSRI $20, V18.S4, V7.S4
VSRI $20, V19.S4, V4.S4
// V0 += V5; V15 <<<= ((V0 XOR V15), 8)
// ...
VADD V5.S4, V0.S4, V0.S4
VADD V6.S4, V1.S4, V1.S4
VADD V7.S4, V2.S4, V2.S4
VADD V4.S4, V3.S4, V3.S4
VEOR V0.B16, V15.B16, V15.B16
VEOR V1.B16, V12.B16, V12.B16
VEOR V2.B16, V13.B16, V13.B16
VEOR V3.B16, V14.B16, V14.B16
VTBL V31.B16, [V12.B16], V12.B16
VTBL V31.B16, [V13.B16], V13.B16
VTBL V31.B16, [V14.B16], V14.B16
VTBL V31.B16, [V15.B16], V15.B16
// V10 += V15; V5 <<<= ((V10 XOR V5), 7)
// ...
VADD V15.S4, V10.S4, V10.S4
VADD V12.S4, V11.S4, V11.S4
VADD V13.S4, V8.S4, V8.S4
VADD V14.S4, V9.S4, V9.S4
VEOR V10.B16, V5.B16, V16.B16
VEOR V11.B16, V6.B16, V17.B16
VEOR V8.B16, V7.B16, V18.B16
VEOR V9.B16, V4.B16, V19.B16
VSHL $7, V16.S4, V5.S4
VSHL $7, V17.S4, V6.S4
VSHL $7, V18.S4, V7.S4
VSHL $7, V19.S4, V4.S4
VSRI $25, V16.S4, V5.S4
VSRI $25, V17.S4, V6.S4
VSRI $25, V18.S4, V7.S4
VSRI $25, V19.S4, V4.S4
SUB $1, R21
CBNZ R21, chacha
// VLD4R (R10), [V16.S4, V17.S4, V18.S4, V19.S4]
WORD $0x4D60E950
// VLD4R 16(R4), [V20.S4, V21.S4, V22.S4, V23.S4]
WORD $0x4DFFE894
VADD V30.S4, V12.S4, V12.S4
VADD V16.S4, V0.S4, V0.S4
VADD V17.S4, V1.S4, V1.S4
VADD V18.S4, V2.S4, V2.S4
VADD V19.S4, V3.S4, V3.S4
// VLD4R 16(R4), [V24.S4, V25.S4, V26.S4, V27.S4]
WORD $0x4DFFE898
// restore R4
SUB $32, R4
// load counter + nonce
// VLD1R (R7), [V28.S4]
WORD $0x4D40C8FC
// VLD3R (R6), [V29.S4, V30.S4, V31.S4]
WORD $0x4D40E8DD
VADD V20.S4, V4.S4, V4.S4
VADD V21.S4, V5.S4, V5.S4
VADD V22.S4, V6.S4, V6.S4
VADD V23.S4, V7.S4, V7.S4
VADD V24.S4, V8.S4, V8.S4
VADD V25.S4, V9.S4, V9.S4
VADD V26.S4, V10.S4, V10.S4
VADD V27.S4, V11.S4, V11.S4
VADD V28.S4, V12.S4, V12.S4
VADD V29.S4, V13.S4, V13.S4
VADD V30.S4, V14.S4, V14.S4
VADD V31.S4, V15.S4, V15.S4
VZIP1 V1.S4, V0.S4, V16.S4
VZIP2 V1.S4, V0.S4, V17.S4
VZIP1 V3.S4, V2.S4, V18.S4
VZIP2 V3.S4, V2.S4, V19.S4
VZIP1 V5.S4, V4.S4, V20.S4
VZIP2 V5.S4, V4.S4, V21.S4
VZIP1 V7.S4, V6.S4, V22.S4
VZIP2 V7.S4, V6.S4, V23.S4
VZIP1 V9.S4, V8.S4, V24.S4
VZIP2 V9.S4, V8.S4, V25.S4
VZIP1 V11.S4, V10.S4, V26.S4
VZIP2 V11.S4, V10.S4, V27.S4
VZIP1 V13.S4, V12.S4, V28.S4
VZIP2 V13.S4, V12.S4, V29.S4
VZIP1 V15.S4, V14.S4, V30.S4
VZIP2 V15.S4, V14.S4, V31.S4
VZIP1 V18.D2, V16.D2, V0.D2
VZIP2 V18.D2, V16.D2, V4.D2
VZIP1 V19.D2, V17.D2, V8.D2
VZIP2 V19.D2, V17.D2, V12.D2
VLD1.P 64(R2), [V16.B16, V17.B16, V18.B16, V19.B16]
VZIP1 V22.D2, V20.D2, V1.D2
VZIP2 V22.D2, V20.D2, V5.D2
VZIP1 V23.D2, V21.D2, V9.D2
VZIP2 V23.D2, V21.D2, V13.D2
VLD1.P 64(R2), [V20.B16, V21.B16, V22.B16, V23.B16]
VZIP1 V26.D2, V24.D2, V2.D2
VZIP2 V26.D2, V24.D2, V6.D2
VZIP1 V27.D2, V25.D2, V10.D2
VZIP2 V27.D2, V25.D2, V14.D2
VLD1.P 64(R2), [V24.B16, V25.B16, V26.B16, V27.B16]
VZIP1 V30.D2, V28.D2, V3.D2
VZIP2 V30.D2, V28.D2, V7.D2
VZIP1 V31.D2, V29.D2, V11.D2
VZIP2 V31.D2, V29.D2, V15.D2
VLD1.P 64(R2), [V28.B16, V29.B16, V30.B16, V31.B16]
VEOR V0.B16, V16.B16, V16.B16
VEOR V1.B16, V17.B16, V17.B16
VEOR V2.B16, V18.B16, V18.B16
VEOR V3.B16, V19.B16, V19.B16
VST1.P [V16.B16, V17.B16, V18.B16, V19.B16], 64(R1)
VEOR V4.B16, V20.B16, V20.B16
VEOR V5.B16, V21.B16, V21.B16
VEOR V6.B16, V22.B16, V22.B16
VEOR V7.B16, V23.B16, V23.B16
VST1.P [V20.B16, V21.B16, V22.B16, V23.B16], 64(R1)
VEOR V8.B16, V24.B16, V24.B16
VEOR V9.B16, V25.B16, V25.B16
VEOR V10.B16, V26.B16, V26.B16
VEOR V11.B16, V27.B16, V27.B16
VST1.P [V24.B16, V25.B16, V26.B16, V27.B16], 64(R1)
VEOR V12.B16, V28.B16, V28.B16
VEOR V13.B16, V29.B16, V29.B16
VEOR V14.B16, V30.B16, V30.B16
VEOR V15.B16, V31.B16, V31.B16
VST1.P [V28.B16, V29.B16, V30.B16, V31.B16], 64(R1)
ADD $4, R20
MOVW R20, (R7) // update counter
CMP R2, R12
BGT loop
RET
DATA ·constants+0x00(SB)/4, $0x61707865
DATA ·constants+0x04(SB)/4, $0x3320646e
DATA ·constants+0x08(SB)/4, $0x79622d32
DATA ·constants+0x0c(SB)/4, $0x6b206574
GLOBL ·constants(SB), NOPTR|RODATA, $32
DATA ·incRotMatrix+0x00(SB)/4, $0x00000000
DATA ·incRotMatrix+0x04(SB)/4, $0x00000001
DATA ·incRotMatrix+0x08(SB)/4, $0x00000002
DATA ·incRotMatrix+0x0c(SB)/4, $0x00000003
DATA ·incRotMatrix+0x10(SB)/4, $0x02010003
DATA ·incRotMatrix+0x14(SB)/4, $0x06050407
DATA ·incRotMatrix+0x18(SB)/4, $0x0A09080B
DATA ·incRotMatrix+0x1c(SB)/4, $0x0E0D0C0F
GLOBL ·incRotMatrix(SB), NOPTR|RODATA, $32

View File

@@ -0,0 +1,668 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Based on CRYPTOGAMS code with the following comment:
// # ====================================================================
// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
// # project. The module is, however, dual licensed under OpenSSL and
// # CRYPTOGAMS licenses depending on where you obtain it. For further
// # details see http://www.openssl.org/~appro/cryptogams/.
// # ====================================================================
// Original code can be found at the link below:
// https://github.com/dot-asm/cryptogams/commit/a60f5b50ed908e91e5c39ca79126a4a876d5d8ff
// There are some differences between CRYPTOGAMS code and this one. The round
// loop for "_int" isn't the same as the original. Some adjustments were
// necessary because there are less vector registers available. For example, some
// X variables (r12, r13, r14, and r15) share the same register used by the
// counter. The original code uses ctr to name the counter. Here we use CNT
// because golang uses CTR as the counter register name.
// +build ppc64le,!gccgo,!appengine
#include "textflag.h"
#define OUT R3
#define INP R4
#define LEN R5
#define KEY R6
#define CNT R7
#define TEMP R8
#define X0 R11
#define X1 R12
#define X2 R14
#define X3 R15
#define X4 R16
#define X5 R17
#define X6 R18
#define X7 R19
#define X8 R20
#define X9 R21
#define X10 R22
#define X11 R23
#define X12 R24
#define X13 R25
#define X14 R26
#define X15 R27
#define CON0 X0
#define CON1 X1
#define CON2 X2
#define CON3 X3
#define KEY0 X4
#define KEY1 X5
#define KEY2 X6
#define KEY3 X7
#define KEY4 X8
#define KEY5 X9
#define KEY6 X10
#define KEY7 X11
#define CNT0 X12
#define CNT1 X13
#define CNT2 X14
#define CNT3 X15
#define TMP0 R9
#define TMP1 R10
#define TMP2 R28
#define TMP3 R29
#define CONSTS R8
#define A0 V0
#define B0 V1
#define C0 V2
#define D0 V3
#define A1 V4
#define B1 V5
#define C1 V6
#define D1 V7
#define A2 V8
#define B2 V9
#define C2 V10
#define D2 V11
#define T0 V12
#define T1 V13
#define T2 V14
#define K0 V15
#define K1 V16
#define K2 V17
#define K3 V18
#define K4 V19
#define K5 V20
#define FOUR V21
#define SIXTEEN V22
#define TWENTY4 V23
#define TWENTY V24
#define TWELVE V25
#define TWENTY5 V26
#define SEVEN V27
#define INPPERM V28
#define OUTPERM V29
#define OUTMASK V30
#define DD0 V31
#define DD1 SEVEN
#define DD2 T0
#define DD3 T1
#define DD4 T2
DATA ·consts+0x00(SB)/8, $0x3320646e61707865
DATA ·consts+0x08(SB)/8, $0x6b20657479622d32
DATA ·consts+0x10(SB)/8, $0x0000000000000001
DATA ·consts+0x18(SB)/8, $0x0000000000000000
DATA ·consts+0x20(SB)/8, $0x0000000000000004
DATA ·consts+0x28(SB)/8, $0x0000000000000000
DATA ·consts+0x30(SB)/8, $0x0a0b08090e0f0c0d
DATA ·consts+0x38(SB)/8, $0x0203000106070405
DATA ·consts+0x40(SB)/8, $0x090a0b080d0e0f0c
DATA ·consts+0x48(SB)/8, $0x0102030005060704
GLOBL ·consts(SB), RODATA, $80
//func chaCha20_ctr32_vmx(out, inp *byte, len int, key *[32]byte, counter *[16]byte)
TEXT ·chaCha20_ctr32_vmx(SB),NOSPLIT|NOFRAME,$0
// Load the arguments inside the registers
MOVD out+0(FP), OUT
MOVD inp+8(FP), INP
MOVD len+16(FP), LEN
MOVD key+24(FP), KEY
MOVD counter+32(FP), CNT
MOVD $·consts(SB), CONSTS // point to consts addr
MOVD $16, X0
MOVD $32, X1
MOVD $48, X2
MOVD $64, X3
MOVD $31, X4
MOVD $15, X5
// Load key
LVX (KEY)(R0), K1
LVSR (KEY)(R0), T0
LVX (KEY)(X0), K2
LVX (KEY)(X4), DD0
// Load counter
LVX (CNT)(R0), K3
LVSR (CNT)(R0), T1
LVX (CNT)(X5), DD1
// Load constants
LVX (CONSTS)(R0), K0
LVX (CONSTS)(X0), K5
LVX (CONSTS)(X1), FOUR
LVX (CONSTS)(X2), SIXTEEN
LVX (CONSTS)(X3), TWENTY4
// Align key and counter
VPERM K2, K1, T0, K1
VPERM DD0, K2, T0, K2
VPERM DD1, K3, T1, K3
// Load counter to GPR
MOVWZ 0(CNT), CNT0
MOVWZ 4(CNT), CNT1
MOVWZ 8(CNT), CNT2
MOVWZ 12(CNT), CNT3
// Adjust vectors for the initial state
VADDUWM K3, K5, K3
VADDUWM K3, K5, K4
VADDUWM K4, K5, K5
// Synthesized constants
VSPLTISW $-12, TWENTY
VSPLTISW $12, TWELVE
VSPLTISW $-7, TWENTY5
VXOR T0, T0, T0
VSPLTISW $-1, OUTMASK
LVSR (INP)(R0), INPPERM
LVSL (OUT)(R0), OUTPERM
VPERM OUTMASK, T0, OUTPERM, OUTMASK
loop_outer_vmx:
// Load constant
MOVD $0x61707865, CON0
MOVD $0x3320646e, CON1
MOVD $0x79622d32, CON2
MOVD $0x6b206574, CON3
VOR K0, K0, A0
VOR K0, K0, A1
VOR K0, K0, A2
VOR K1, K1, B0
MOVD $10, TEMP
// Load key to GPR
MOVWZ 0(KEY), X4
MOVWZ 4(KEY), X5
MOVWZ 8(KEY), X6
MOVWZ 12(KEY), X7
VOR K1, K1, B1
VOR K1, K1, B2
MOVWZ 16(KEY), X8
MOVWZ 0(CNT), X12
MOVWZ 20(KEY), X9
MOVWZ 4(CNT), X13
VOR K2, K2, C0
VOR K2, K2, C1
MOVWZ 24(KEY), X10
MOVWZ 8(CNT), X14
VOR K2, K2, C2
VOR K3, K3, D0
MOVWZ 28(KEY), X11
MOVWZ 12(CNT), X15
VOR K4, K4, D1
VOR K5, K5, D2
MOVD X4, TMP0
MOVD X5, TMP1
MOVD X6, TMP2
MOVD X7, TMP3
VSPLTISW $7, SEVEN
MOVD TEMP, CTR
loop_vmx:
// CRYPTOGAMS uses a macro to create a loop using perl. This isn't possible
// using assembly macros. Therefore, the macro expansion result was used
// in order to maintain the algorithm efficiency.
// This loop generates three keystream blocks using VMX instructions and,
// in parallel, one keystream block using scalar instructions.
ADD X4, X0, X0
ADD X5, X1, X1
VADDUWM A0, B0, A0
VADDUWM A1, B1, A1
ADD X6, X2, X2
ADD X7, X3, X3
VADDUWM A2, B2, A2
VXOR D0, A0, D0
XOR X0, X12, X12
XOR X1, X13, X13
VXOR D1, A1, D1
VXOR D2, A2, D2
XOR X2, X14, X14
XOR X3, X15, X15
VPERM D0, D0, SIXTEEN, D0
VPERM D1, D1, SIXTEEN, D1
ROTLW $16, X12, X12
ROTLW $16, X13, X13
VPERM D2, D2, SIXTEEN, D2
VADDUWM C0, D0, C0
ROTLW $16, X14, X14
ROTLW $16, X15, X15
VADDUWM C1, D1, C1
VADDUWM C2, D2, C2
ADD X12, X8, X8
ADD X13, X9, X9
VXOR B0, C0, T0
VXOR B1, C1, T1
ADD X14, X10, X10
ADD X15, X11, X11
VXOR B2, C2, T2
VRLW T0, TWELVE, B0
XOR X8, X4, X4
XOR X9, X5, X5
VRLW T1, TWELVE, B1
VRLW T2, TWELVE, B2
XOR X10, X6, X6
XOR X11, X7, X7
VADDUWM A0, B0, A0
VADDUWM A1, B1, A1
ROTLW $12, X4, X4
ROTLW $12, X5, X5
VADDUWM A2, B2, A2
VXOR D0, A0, D0
ROTLW $12, X6, X6
ROTLW $12, X7, X7
VXOR D1, A1, D1
VXOR D2, A2, D2
ADD X4, X0, X0
ADD X5, X1, X1
VPERM D0, D0, TWENTY4, D0
VPERM D1, D1, TWENTY4, D1
ADD X6, X2, X2
ADD X7, X3, X3
VPERM D2, D2, TWENTY4, D2
VADDUWM C0, D0, C0
XOR X0, X12, X12
XOR X1, X13, X13
VADDUWM C1, D1, C1
VADDUWM C2, D2, C2
XOR X2, X14, X14
XOR X3, X15, X15
VXOR B0, C0, T0
VXOR B1, C1, T1
ROTLW $8, X12, X12
ROTLW $8, X13, X13
VXOR B2, C2, T2
VRLW T0, SEVEN, B0
ROTLW $8, X14, X14
ROTLW $8, X15, X15
VRLW T1, SEVEN, B1
VRLW T2, SEVEN, B2
ADD X12, X8, X8
ADD X13, X9, X9
VSLDOI $8, C0, C0, C0
VSLDOI $8, C1, C1, C1
ADD X14, X10, X10
ADD X15, X11, X11
VSLDOI $8, C2, C2, C2
VSLDOI $12, B0, B0, B0
XOR X8, X4, X4
XOR X9, X5, X5
VSLDOI $12, B1, B1, B1
VSLDOI $12, B2, B2, B2
XOR X10, X6, X6
XOR X11, X7, X7
VSLDOI $4, D0, D0, D0
VSLDOI $4, D1, D1, D1
ROTLW $7, X4, X4
ROTLW $7, X5, X5
VSLDOI $4, D2, D2, D2
VADDUWM A0, B0, A0
ROTLW $7, X6, X6
ROTLW $7, X7, X7
VADDUWM A1, B1, A1
VADDUWM A2, B2, A2
ADD X5, X0, X0
ADD X6, X1, X1
VXOR D0, A0, D0
VXOR D1, A1, D1
ADD X7, X2, X2
ADD X4, X3, X3
VXOR D2, A2, D2
VPERM D0, D0, SIXTEEN, D0
XOR X0, X15, X15
XOR X1, X12, X12
VPERM D1, D1, SIXTEEN, D1
VPERM D2, D2, SIXTEEN, D2
XOR X2, X13, X13
XOR X3, X14, X14
VADDUWM C0, D0, C0
VADDUWM C1, D1, C1
ROTLW $16, X15, X15
ROTLW $16, X12, X12
VADDUWM C2, D2, C2
VXOR B0, C0, T0
ROTLW $16, X13, X13
ROTLW $16, X14, X14
VXOR B1, C1, T1
VXOR B2, C2, T2
ADD X15, X10, X10
ADD X12, X11, X11
VRLW T0, TWELVE, B0
VRLW T1, TWELVE, B1
ADD X13, X8, X8
ADD X14, X9, X9
VRLW T2, TWELVE, B2
VADDUWM A0, B0, A0
XOR X10, X5, X5
XOR X11, X6, X6
VADDUWM A1, B1, A1
VADDUWM A2, B2, A2
XOR X8, X7, X7
XOR X9, X4, X4
VXOR D0, A0, D0
VXOR D1, A1, D1
ROTLW $12, X5, X5
ROTLW $12, X6, X6
VXOR D2, A2, D2
VPERM D0, D0, TWENTY4, D0
ROTLW $12, X7, X7
ROTLW $12, X4, X4
VPERM D1, D1, TWENTY4, D1
VPERM D2, D2, TWENTY4, D2
ADD X5, X0, X0
ADD X6, X1, X1
VADDUWM C0, D0, C0
VADDUWM C1, D1, C1
ADD X7, X2, X2
ADD X4, X3, X3
VADDUWM C2, D2, C2
VXOR B0, C0, T0
XOR X0, X15, X15
XOR X1, X12, X12
VXOR B1, C1, T1
VXOR B2, C2, T2
XOR X2, X13, X13
XOR X3, X14, X14
VRLW T0, SEVEN, B0
VRLW T1, SEVEN, B1
ROTLW $8, X15, X15
ROTLW $8, X12, X12
VRLW T2, SEVEN, B2
VSLDOI $8, C0, C0, C0
ROTLW $8, X13, X13
ROTLW $8, X14, X14
VSLDOI $8, C1, C1, C1
VSLDOI $8, C2, C2, C2
ADD X15, X10, X10
ADD X12, X11, X11
VSLDOI $4, B0, B0, B0
VSLDOI $4, B1, B1, B1
ADD X13, X8, X8
ADD X14, X9, X9
VSLDOI $4, B2, B2, B2
VSLDOI $12, D0, D0, D0
XOR X10, X5, X5
XOR X11, X6, X6
VSLDOI $12, D1, D1, D1
VSLDOI $12, D2, D2, D2
XOR X8, X7, X7
XOR X9, X4, X4
ROTLW $7, X5, X5
ROTLW $7, X6, X6
ROTLW $7, X7, X7
ROTLW $7, X4, X4
BC 0x10, 0, loop_vmx
SUB $256, LEN, LEN
// Accumulate key block
ADD $0x61707865, X0, X0
ADD $0x3320646e, X1, X1
ADD $0x79622d32, X2, X2
ADD $0x6b206574, X3, X3
ADD TMP0, X4, X4
ADD TMP1, X5, X5
ADD TMP2, X6, X6
ADD TMP3, X7, X7
MOVWZ 16(KEY), TMP0
MOVWZ 20(KEY), TMP1
MOVWZ 24(KEY), TMP2
MOVWZ 28(KEY), TMP3
ADD TMP0, X8, X8
ADD TMP1, X9, X9
ADD TMP2, X10, X10
ADD TMP3, X11, X11
MOVWZ 12(CNT), TMP0
MOVWZ 8(CNT), TMP1
MOVWZ 4(CNT), TMP2
MOVWZ 0(CNT), TEMP
ADD TMP0, X15, X15
ADD TMP1, X14, X14
ADD TMP2, X13, X13
ADD TEMP, X12, X12
// Accumulate key block
VADDUWM A0, K0, A0
VADDUWM A1, K0, A1
VADDUWM A2, K0, A2
VADDUWM B0, K1, B0
VADDUWM B1, K1, B1
VADDUWM B2, K1, B2
VADDUWM C0, K2, C0
VADDUWM C1, K2, C1
VADDUWM C2, K2, C2
VADDUWM D0, K3, D0
VADDUWM D1, K4, D1
VADDUWM D2, K5, D2
// Increment counter
ADD $4, TEMP, TEMP
MOVW TEMP, 0(CNT)
VADDUWM K3, FOUR, K3
VADDUWM K4, FOUR, K4
VADDUWM K5, FOUR, K5
// XOR the input slice (INP) with the keystream, which is stored in GPRs (X0-X3).
// Load input (aligned or not)
MOVWZ 0(INP), TMP0
MOVWZ 4(INP), TMP1
MOVWZ 8(INP), TMP2
MOVWZ 12(INP), TMP3
// XOR with input
XOR TMP0, X0, X0
XOR TMP1, X1, X1
XOR TMP2, X2, X2
XOR TMP3, X3, X3
MOVWZ 16(INP), TMP0
MOVWZ 20(INP), TMP1
MOVWZ 24(INP), TMP2
MOVWZ 28(INP), TMP3
XOR TMP0, X4, X4
XOR TMP1, X5, X5
XOR TMP2, X6, X6
XOR TMP3, X7, X7
MOVWZ 32(INP), TMP0
MOVWZ 36(INP), TMP1
MOVWZ 40(INP), TMP2
MOVWZ 44(INP), TMP3
XOR TMP0, X8, X8
XOR TMP1, X9, X9
XOR TMP2, X10, X10
XOR TMP3, X11, X11
MOVWZ 48(INP), TMP0
MOVWZ 52(INP), TMP1
MOVWZ 56(INP), TMP2
MOVWZ 60(INP), TMP3
XOR TMP0, X12, X12
XOR TMP1, X13, X13
XOR TMP2, X14, X14
XOR TMP3, X15, X15
// Store output (aligned or not)
MOVW X0, 0(OUT)
MOVW X1, 4(OUT)
MOVW X2, 8(OUT)
MOVW X3, 12(OUT)
ADD $64, INP, INP // INP points to the end of the slice for the alignment code below
MOVW X4, 16(OUT)
MOVD $16, TMP0
MOVW X5, 20(OUT)
MOVD $32, TMP1
MOVW X6, 24(OUT)
MOVD $48, TMP2
MOVW X7, 28(OUT)
MOVD $64, TMP3
MOVW X8, 32(OUT)
MOVW X9, 36(OUT)
MOVW X10, 40(OUT)
MOVW X11, 44(OUT)
MOVW X12, 48(OUT)
MOVW X13, 52(OUT)
MOVW X14, 56(OUT)
MOVW X15, 60(OUT)
ADD $64, OUT, OUT
// Load input
LVX (INP)(R0), DD0
LVX (INP)(TMP0), DD1
LVX (INP)(TMP1), DD2
LVX (INP)(TMP2), DD3
LVX (INP)(TMP3), DD4
ADD $64, INP, INP
VPERM DD1, DD0, INPPERM, DD0 // Align input
VPERM DD2, DD1, INPPERM, DD1
VPERM DD3, DD2, INPPERM, DD2
VPERM DD4, DD3, INPPERM, DD3
VXOR A0, DD0, A0 // XOR with input
VXOR B0, DD1, B0
LVX (INP)(TMP0), DD1 // Keep loading input
VXOR C0, DD2, C0
LVX (INP)(TMP1), DD2
VXOR D0, DD3, D0
LVX (INP)(TMP2), DD3
LVX (INP)(TMP3), DD0
ADD $64, INP, INP
MOVD $63, TMP3 // 63 is not a typo
VPERM A0, A0, OUTPERM, A0
VPERM B0, B0, OUTPERM, B0
VPERM C0, C0, OUTPERM, C0
VPERM D0, D0, OUTPERM, D0
VPERM DD1, DD4, INPPERM, DD4 // Align input
VPERM DD2, DD1, INPPERM, DD1
VPERM DD3, DD2, INPPERM, DD2
VPERM DD0, DD3, INPPERM, DD3
VXOR A1, DD4, A1
VXOR B1, DD1, B1
LVX (INP)(TMP0), DD1 // Keep loading
VXOR C1, DD2, C1
LVX (INP)(TMP1), DD2
VXOR D1, DD3, D1
LVX (INP)(TMP2), DD3
// Note that the LVX address is always rounded down to the nearest 16-byte
// boundary, and that it always points to at most 15 bytes beyond the end of
// the slice, so we cannot cross a page boundary.
LVX (INP)(TMP3), DD4 // Redundant in aligned case.
ADD $64, INP, INP
VPERM A1, A1, OUTPERM, A1 // Pre-misalign output
VPERM B1, B1, OUTPERM, B1
VPERM C1, C1, OUTPERM, C1
VPERM D1, D1, OUTPERM, D1
VPERM DD1, DD0, INPPERM, DD0 // Align Input
VPERM DD2, DD1, INPPERM, DD1
VPERM DD3, DD2, INPPERM, DD2
VPERM DD4, DD3, INPPERM, DD3
VXOR A2, DD0, A2
VXOR B2, DD1, B2
VXOR C2, DD2, C2
VXOR D2, DD3, D2
VPERM A2, A2, OUTPERM, A2
VPERM B2, B2, OUTPERM, B2
VPERM C2, C2, OUTPERM, C2
VPERM D2, D2, OUTPERM, D2
ANDCC $15, OUT, X1 // Is out aligned?
MOVD OUT, X0
VSEL A0, B0, OUTMASK, DD0 // Collect pre-misaligned output
VSEL B0, C0, OUTMASK, DD1
VSEL C0, D0, OUTMASK, DD2
VSEL D0, A1, OUTMASK, DD3
VSEL A1, B1, OUTMASK, B0
VSEL B1, C1, OUTMASK, C0
VSEL C1, D1, OUTMASK, D0
VSEL D1, A2, OUTMASK, A1
VSEL A2, B2, OUTMASK, B1
VSEL B2, C2, OUTMASK, C1
VSEL C2, D2, OUTMASK, D1
STVX DD0, (OUT+TMP0)
STVX DD1, (OUT+TMP1)
STVX DD2, (OUT+TMP2)
ADD $64, OUT, OUT
STVX DD3, (OUT+R0)
STVX B0, (OUT+TMP0)
STVX C0, (OUT+TMP1)
STVX D0, (OUT+TMP2)
ADD $64, OUT, OUT
STVX A1, (OUT+R0)
STVX B1, (OUT+TMP0)
STVX C1, (OUT+TMP1)
STVX D1, (OUT+TMP2)
ADD $64, OUT, OUT
BEQ aligned_vmx
SUB X1, OUT, X2 // in misaligned case edges
MOVD $0, X3 // are written byte-by-byte
unaligned_tail_vmx:
STVEBX D2, (X2+X3)
ADD $1, X3, X3
CMPW X3, X1
BNE unaligned_tail_vmx
SUB X1, X0, X2
unaligned_head_vmx:
STVEBX A0, (X2+X1)
CMPW X1, $15
ADD $1, X1, X1
BNE unaligned_head_vmx
CMPU LEN, $255 // done with 256-byte block yet?
BGT loop_outer_vmx
JMP done_vmx
aligned_vmx:
STVX A0, (X0+R0)
CMPU LEN, $255 // done with 256-byte block yet?
BGT loop_outer_vmx
done_vmx:
RET

View File

@@ -0,0 +1,31 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.11
// +build !gccgo
package chacha20
const (
haveAsm = true
bufSize = 256
)
//go:noescape
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
func (c *Cipher) xorKeyStreamAsm(dst, src []byte) {
if len(src) >= bufSize {
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)
}
if len(src)%bufSize != 0 {
i := len(src) - len(src)%bufSize
c.buf = [bufSize]byte{}
copy(c.buf[:], src[i:])
xorKeyStreamVX(c.buf[:], c.buf[:], &c.key, &c.nonce, &c.counter)
c.len = bufSize - copy(dst[i:], c.buf[:len(src)%bufSize])
}
}

View File

@@ -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 !s390x gccgo appengine // +build !ppc64le,!arm64,!s390x arm64,!go1.11 gccgo appengine
package chacha20 package chacha20

View File

@@ -0,0 +1,52 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ppc64le,!gccgo,!appengine
package chacha20
import "encoding/binary"
const (
bufSize = 256
haveAsm = true
)
//go:noescape
func chaCha20_ctr32_vmx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
func (c *Cipher) xorKeyStreamAsm(dst, src []byte) {
if len(src) >= bufSize {
chaCha20_ctr32_vmx(&dst[0], &src[0], len(src)-len(src)%bufSize, &c.key, &c.counter)
}
if len(src)%bufSize != 0 {
chaCha20_ctr32_vmx(&c.buf[0], &c.buf[0], bufSize, &c.key, &c.counter)
start := len(src) - len(src)%bufSize
ts, td, tb := src[start:], dst[start:], c.buf[:]
// Unroll loop to XOR 32 bytes per iteration.
for i := 0; i < len(ts)-32; i += 32 {
td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination
s0 := binary.LittleEndian.Uint64(ts[0:8])
s1 := binary.LittleEndian.Uint64(ts[8:16])
s2 := binary.LittleEndian.Uint64(ts[16:24])
s3 := binary.LittleEndian.Uint64(ts[24:32])
b0 := binary.LittleEndian.Uint64(tb[0:8])
b1 := binary.LittleEndian.Uint64(tb[8:16])
b2 := binary.LittleEndian.Uint64(tb[16:24])
b3 := binary.LittleEndian.Uint64(tb[24:32])
binary.LittleEndian.PutUint64(td[0:8], s0^b0)
binary.LittleEndian.PutUint64(td[8:16], s1^b1)
binary.LittleEndian.PutUint64(td[16:24], s2^b2)
binary.LittleEndian.PutUint64(td[24:32], s3^b3)
ts, td, tb = ts[32:], td[32:], tb[32:]
}
td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination
for i, v := range ts {
td[i] = tb[i] ^ v
}
c.len = bufSize - (len(src) % bufSize)
}
}

View File

@@ -6,15 +6,14 @@
package chacha20 package chacha20
var haveAsm = hasVectorFacility() import (
"golang.org/x/sys/cpu"
)
var haveAsm = cpu.S390X.HasVX
const bufSize = 256 const bufSize = 256
// hasVectorFacility reports whether the machine supports the vector
// facility (vx).
// Implementation in asm_s390x.s.
func hasVectorFacility() bool
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only // xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
// be called when the vector facility is available. // be called when the vector facility is available.
// Implementation in asm_s390x.s. // Implementation in asm_s390x.s.

View File

@@ -258,26 +258,3 @@ tail:
MOVD R8, R3 MOVD R8, R3
MOVD $0, R4 MOVD $0, R4
JMP continue JMP continue
// func hasVectorFacility() bool
TEXT ·hasVectorFacility(SB), NOSPLIT, $24-1
MOVD $x-24(SP), R1
XC $24, 0(R1), 0(R1) // clear the storage
MOVD $2, R0 // R0 is the number of double words stored -1
WORD $0xB2B01000 // STFLE 0(R1)
XOR R0, R0 // reset the value of R0
MOVBZ z-8(SP), R1
AND $0x40, R1
BEQ novector
vectorinstalled:
// check if the vector instruction has been enabled
VLEIB $0, $0xF, V16
VLGVB $0, V16, R1
CMPBNE R1, $0xF, novector
MOVB $1, ret+0(FP) // have vx
RET
novector:
MOVB $0, ret+0(FP) // no vx
RET

View File

@@ -3,6 +3,10 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package md4 implements the MD4 hash algorithm as defined in RFC 1320. // Package md4 implements the MD4 hash algorithm as defined in RFC 1320.
//
// Deprecated: MD4 is cryptographically broken and should should only be used
// where compatibility with legacy systems, not security, is the goal. Instead,
// use a secure hash like SHA-256 (from crypto/sha256).
package md4 // import "golang.org/x/crypto/md4" package md4 // import "golang.org/x/crypto/md4"
import ( import (

View File

@@ -40,7 +40,7 @@ func TestOpen(t *testing.T) {
if !bytes.Equal(message, testMessage) { if !bytes.Equal(message, testMessage) {
t.Fatalf("message did not match, got\n%x\n, expected\n%x", message, testMessage) t.Fatalf("message did not match, got\n%x\n, expected\n%x", message, testMessage)
} }
message, ok = Open(nil, testSignedMessage[1:], &testPublicKey) _, ok = Open(nil, testSignedMessage[1:], &testPublicKey)
if ok { if ok {
t.Fatalf("invalid signed message successfully verified") t.Fatalf("invalid signed message successfully verified")
} }

View File

@@ -63,7 +63,7 @@ func (r ResponseStatus) String() string {
} }
// ResponseError is an error that may be returned by ParseResponse to indicate // ResponseError is an error that may be returned by ParseResponse to indicate
// that the response itself is an error, not just that its indicating that a // that the response itself is an error, not just that it's indicating that a
// certificate is revoked, unknown, etc. // certificate is revoked, unknown, etc.
type ResponseError struct { type ResponseError struct {
Status ResponseStatus Status ResponseStatus
@@ -487,6 +487,9 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(rest) > 0 {
return nil, ParseError("trailing data in OCSP response")
}
if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 { if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
return nil, ParseError("OCSP response contains bad number of responses") return nil, ParseError("OCSP response contains bad number of responses")

View File

@@ -18,6 +18,7 @@ import (
"io" "io"
"net/textproto" "net/textproto"
"strconv" "strconv"
"strings"
"golang.org/x/crypto/openpgp/armor" "golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/errors" "golang.org/x/crypto/openpgp/errors"
@@ -27,7 +28,7 @@ import (
// A Block represents a clearsigned message. A signature on a Block can // A Block represents a clearsigned message. A signature on a Block can
// be checked by passing Bytes into openpgp.CheckDetachedSignature. // be checked by passing Bytes into openpgp.CheckDetachedSignature.
type Block struct { type Block struct {
Headers textproto.MIMEHeader // Optional message headers Headers textproto.MIMEHeader // Optional unverified Hash headers
Plaintext []byte // The original message text Plaintext []byte // The original message text
Bytes []byte // The signed message Bytes []byte // The signed message
ArmoredSignature *armor.Block // The signature block ArmoredSignature *armor.Block // The signature block
@@ -69,8 +70,13 @@ func getLine(data []byte) (line, rest []byte) {
return data[0:i], data[j:] return data[0:i], data[j:]
} }
// Decode finds the first clearsigned message in data and returns it, as well // Decode finds the first clearsigned message in data and returns it, as well as
// as the suffix of data which remains after the message. // the suffix of data which remains after the message. Any prefix data is
// discarded.
//
// If no message is found, or if the message is invalid, Decode returns nil and
// the whole data slice. The only allowed header type is Hash, and it is not
// verified against the signature hash.
func Decode(data []byte) (b *Block, rest []byte) { func Decode(data []byte) (b *Block, rest []byte) {
// start begins with a newline. However, at the very beginning of // start begins with a newline. However, at the very beginning of
// the byte array, we'll accept the start string without it. // the byte array, we'll accept the start string without it.
@@ -83,8 +89,11 @@ func Decode(data []byte) (b *Block, rest []byte) {
return nil, data return nil, data
} }
// Consume the start line. // Consume the start line and check it does not have a suffix.
_, rest = getLine(rest) suffix, rest := getLine(rest)
if len(suffix) != 0 {
return nil, data
}
var line []byte var line []byte
b = &Block{ b = &Block{
@@ -103,15 +112,25 @@ func Decode(data []byte) (b *Block, rest []byte) {
break break
} }
// Reject headers with control or Unicode characters.
if i := bytes.IndexFunc(line, func(r rune) bool {
return r < 0x20 || r > 0x7e
}); i != -1 {
return nil, data
}
i := bytes.Index(line, []byte{':'}) i := bytes.Index(line, []byte{':'})
if i == -1 { if i == -1 {
return nil, data return nil, data
} }
key, val := line[0:i], line[i+1:] key, val := string(line[0:i]), string(line[i+1:])
key = bytes.TrimSpace(key) key = strings.TrimSpace(key)
val = bytes.TrimSpace(val) if key != "Hash" {
b.Headers.Add(string(key), string(val)) return nil, data
}
val = strings.TrimSpace(val)
b.Headers.Add(key, val)
} }
firstLine := true firstLine := true

View File

@@ -47,12 +47,6 @@ func TestParse(t *testing.T) {
testParse(t, clearsignInput2, "\r\n\r\n(This message has a couple of blank lines at the start and end.)\r\n\r\n", "\n\n(This message has a couple of blank lines at the start and end.)\n\n\n") testParse(t, clearsignInput2, "\r\n\r\n(This message has a couple of blank lines at the start and end.)\r\n\r\n", "\n\n(This message has a couple of blank lines at the start and end.)\n\n\n")
} }
func TestParseInvalid(t *testing.T) {
if b, _ := Decode(clearsignInput3); b != nil {
t.Fatal("decoded a bad clearsigned message without any error")
}
}
func TestParseWithNoNewlineAtEnd(t *testing.T) { func TestParseWithNoNewlineAtEnd(t *testing.T) {
input := clearsignInput input := clearsignInput
input = input[:len(input)-len("trailing")-1] input = input[:len(input)-len("trailing")-1]
@@ -140,6 +134,10 @@ func (qr *quickRand) Read(p []byte) (int, error) {
} }
func TestMultiSign(t *testing.T) { func TestMultiSign(t *testing.T) {
if testing.Short() {
t.Skip("skipping long test in -short mode")
}
zero := quickRand(0) zero := quickRand(0)
config := packet.Config{Rand: &zero} config := packet.Config{Rand: &zero}
@@ -193,6 +191,59 @@ func TestMultiSign(t *testing.T) {
} }
} }
const signatureBlock = `
-----BEGIN PGP SIGNATURE-----
Version: OpenPrivacy 0.99
yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS
vBSFjNSiVHsuAA==
=njUN
-----END PGP SIGNATURE-----
`
var invalidInputs = []string{
`
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
(This message was truncated.)
`,
`
-----BEGIN PGP SIGNED MESSAGE-----garbage
Hash: SHA256
_o/
` + signatureBlock,
`
garbage-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
_o/
` + signatureBlock,
`
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA` + "\x0b\x0b" + `256
_o/
` + signatureBlock,
`
-----BEGIN PGP SIGNED MESSAGE-----
NotHash: SHA256
_o/
` + signatureBlock,
}
func TestParseInvalid(t *testing.T) {
for i, input := range invalidInputs {
if b, rest := Decode([]byte(input)); b != nil {
t.Errorf("#%d: decoded a bad clearsigned message without any error", i)
} else if string(rest) != input {
t.Errorf("#%d: did not return all data with a bad message", i)
}
}
}
var clearsignInput = []byte(` var clearsignInput = []byte(`
;lasjlkfdsa ;lasjlkfdsa
@@ -235,13 +286,6 @@ qZg6BaTvOxepqOxnhVU=
trailing`) trailing`)
var clearsignInput3 = []byte(`
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
(This message was truncated.)
`)
var signingKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- var signingKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1.4.10 (GNU/Linux) Version: GnuPG v1.4.10 (GNU/Linux)

View File

@@ -504,7 +504,7 @@ const defaultRSAKeyBits = 2048
// which may be empty but must not contain any of "()<>\x00". // which may be empty but must not contain any of "()<>\x00".
// If config is nil, sensible defaults will be used. // If config is nil, sensible defaults will be used.
func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) { func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
currentTime := config.Now() creationTime := config.Now()
bits := defaultRSAKeyBits bits := defaultRSAKeyBits
if config != nil && config.RSABits != 0 { if config != nil && config.RSABits != 0 {
@@ -525,8 +525,8 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
} }
e := &Entity{ e := &Entity{
PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey), PrimaryKey: packet.NewRSAPublicKey(creationTime, &signingPriv.PublicKey),
PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv), PrivateKey: packet.NewRSAPrivateKey(creationTime, signingPriv),
Identities: make(map[string]*Identity), Identities: make(map[string]*Identity),
} }
isPrimaryId := true isPrimaryId := true
@@ -534,7 +534,7 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
Name: uid.Id, Name: uid.Id,
UserId: uid, UserId: uid,
SelfSignature: &packet.Signature{ SelfSignature: &packet.Signature{
CreationTime: currentTime, CreationTime: creationTime,
SigType: packet.SigTypePositiveCert, SigType: packet.SigTypePositiveCert,
PubKeyAlgo: packet.PubKeyAlgoRSA, PubKeyAlgo: packet.PubKeyAlgoRSA,
Hash: config.Hash(), Hash: config.Hash(),
@@ -563,10 +563,10 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
e.Subkeys = make([]Subkey, 1) e.Subkeys = make([]Subkey, 1)
e.Subkeys[0] = Subkey{ e.Subkeys[0] = Subkey{
PublicKey: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey), PublicKey: packet.NewRSAPublicKey(creationTime, &encryptingPriv.PublicKey),
PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv), PrivateKey: packet.NewRSAPrivateKey(creationTime, encryptingPriv),
Sig: &packet.Signature{ Sig: &packet.Signature{
CreationTime: currentTime, CreationTime: creationTime,
SigType: packet.SigTypeSubkeyBinding, SigType: packet.SigTypeSubkeyBinding,
PubKeyAlgo: packet.PubKeyAlgoRSA, PubKeyAlgo: packet.PubKeyAlgoRSA,
Hash: config.Hash(), Hash: config.Hash(),

View File

@@ -32,7 +32,7 @@ func TestOpaqueParseReason(t *testing.T) {
break break
} }
// try to parse opaque packet // try to parse opaque packet
p, err := op.Parse() p, _ := op.Parse()
switch pkt := p.(type) { switch pkt := p.(type) {
case *UserId: case *UserId:
uid = pkt uid = pkt

View File

@@ -36,49 +36,49 @@ type PrivateKey struct {
iv []byte iv []byte
} }
func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey { func NewRSAPrivateKey(creationTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
pk := new(PrivateKey) pk := new(PrivateKey)
pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey) pk.PublicKey = *NewRSAPublicKey(creationTime, &priv.PublicKey)
pk.PrivateKey = priv pk.PrivateKey = priv
return pk return pk
} }
func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey { func NewDSAPrivateKey(creationTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
pk := new(PrivateKey) pk := new(PrivateKey)
pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey) pk.PublicKey = *NewDSAPublicKey(creationTime, &priv.PublicKey)
pk.PrivateKey = priv pk.PrivateKey = priv
return pk return pk
} }
func NewElGamalPrivateKey(currentTime time.Time, priv *elgamal.PrivateKey) *PrivateKey { func NewElGamalPrivateKey(creationTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
pk := new(PrivateKey) pk := new(PrivateKey)
pk.PublicKey = *NewElGamalPublicKey(currentTime, &priv.PublicKey) pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey)
pk.PrivateKey = priv pk.PrivateKey = priv
return pk return pk
} }
func NewECDSAPrivateKey(currentTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey { func NewECDSAPrivateKey(creationTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey {
pk := new(PrivateKey) pk := new(PrivateKey)
pk.PublicKey = *NewECDSAPublicKey(currentTime, &priv.PublicKey) pk.PublicKey = *NewECDSAPublicKey(creationTime, &priv.PublicKey)
pk.PrivateKey = priv pk.PrivateKey = priv
return pk return pk
} }
// NewSignerPrivateKey creates a PrivateKey from a crypto.Signer that // NewSignerPrivateKey creates a PrivateKey from a crypto.Signer that
// implements RSA or ECDSA. // implements RSA or ECDSA.
func NewSignerPrivateKey(currentTime time.Time, signer crypto.Signer) *PrivateKey { func NewSignerPrivateKey(creationTime time.Time, signer crypto.Signer) *PrivateKey {
pk := new(PrivateKey) pk := new(PrivateKey)
// In general, the public Keys should be used as pointers. We still // In general, the public Keys should be used as pointers. We still
// type-switch on the values, for backwards-compatibility. // type-switch on the values, for backwards-compatibility.
switch pubkey := signer.Public().(type) { switch pubkey := signer.Public().(type) {
case *rsa.PublicKey: case *rsa.PublicKey:
pk.PublicKey = *NewRSAPublicKey(currentTime, pubkey) pk.PublicKey = *NewRSAPublicKey(creationTime, pubkey)
case rsa.PublicKey: case rsa.PublicKey:
pk.PublicKey = *NewRSAPublicKey(currentTime, &pubkey) pk.PublicKey = *NewRSAPublicKey(creationTime, &pubkey)
case *ecdsa.PublicKey: case *ecdsa.PublicKey:
pk.PublicKey = *NewECDSAPublicKey(currentTime, pubkey) pk.PublicKey = *NewECDSAPublicKey(creationTime, pubkey)
case ecdsa.PublicKey: case ecdsa.PublicKey:
pk.PublicKey = *NewECDSAPublicKey(currentTime, &pubkey) pk.PublicKey = *NewECDSAPublicKey(creationTime, &pubkey)
default: default:
panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey") panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey")
} }

View File

@@ -542,7 +542,7 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e
r, s, err = ecdsa.Sign(config.Random(), pk, digest) r, s, err = ecdsa.Sign(config.Random(), pk, digest)
} else { } else {
var b []byte var b []byte
b, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, nil) b, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
if err == nil { if err == nil {
r, s, err = unwrapECDSASig(b) r, s, err = unwrapECDSASig(b)
} }

View File

@@ -80,7 +80,7 @@ func (uat *UserAttribute) Serialize(w io.Writer) (err error) {
// ImageData returns zero or more byte slices, each containing // ImageData returns zero or more byte slices, each containing
// JPEG File Interchange Format (JFIF), for each photo in the // JPEG File Interchange Format (JFIF), for each photo in the
// the user attribute packet. // user attribute packet.
func (uat *UserAttribute) ImageData() (imageData [][]byte) { func (uat *UserAttribute) ImageData() (imageData [][]byte) {
for _, sp := range uat.Contents { for _, sp := range uat.Contents {
if sp.SubType == UserAttrImageSubpacket && len(sp.Contents) > 16 { if sp.SubType == UserAttrImageSubpacket && len(sp.Contents) > 16 {

View File

@@ -271,6 +271,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint
// These are the possible hash functions that we'll use for the signature. // These are the possible hash functions that we'll use for the signature.
candidateHashes := []uint8{ candidateHashes := []uint8{
hashToHashId(crypto.SHA256), hashToHashId(crypto.SHA256),
hashToHashId(crypto.SHA384),
hashToHashId(crypto.SHA512), hashToHashId(crypto.SHA512),
hashToHashId(crypto.SHA1), hashToHashId(crypto.SHA1),
hashToHashId(crypto.RIPEMD160), hashToHashId(crypto.RIPEMD160),
@@ -349,6 +350,7 @@ func Sign(output io.Writer, signed *Entity, hints *FileHints, config *packet.Con
// These are the possible hash functions that we'll use for the signature. // These are the possible hash functions that we'll use for the signature.
candidateHashes := []uint8{ candidateHashes := []uint8{
hashToHashId(crypto.SHA256), hashToHashId(crypto.SHA256),
hashToHashId(crypto.SHA384),
hashToHashId(crypto.SHA512), hashToHashId(crypto.SHA512),
hashToHashId(crypto.SHA1), hashToHashId(crypto.SHA1),
hashToHashId(crypto.RIPEMD160), hashToHashId(crypto.RIPEMD160),

View File

@@ -4,6 +4,10 @@
// Package otr implements the Off The Record protocol as specified in // Package otr implements the Off The Record protocol as specified in
// http://www.cypherpunks.ca/otr/Protocol-v2-3.1.0.html // http://www.cypherpunks.ca/otr/Protocol-v2-3.1.0.html
//
// The version of OTR implemented by this package has been deprecated
// (https://bugs.otr.im/lib/libotr/issues/140). An implementation of OTRv3 is
// available at https://github.com/coyim/otr3.
package otr // import "golang.org/x/crypto/otr" package otr // import "golang.org/x/crypto/otr"
import ( import (
@@ -637,7 +641,7 @@ func (c *Conversation) serializeDHKey() []byte {
} }
func (c *Conversation) processDHKey(in []byte) (isSame bool, err error) { func (c *Conversation) processDHKey(in []byte) (isSame bool, err error) {
gy, in, ok := getMPI(in) gy, _, ok := getMPI(in)
if !ok { if !ok {
err = errors.New("otr: corrupt DH key message") err = errors.New("otr: corrupt DH key message")
return return

View File

@@ -7,6 +7,9 @@
// This implementation is distilled from https://tools.ietf.org/html/rfc7292 // This implementation is distilled from https://tools.ietf.org/html/rfc7292
// and referenced documents. It is intended for decoding P12/PFX-stored // and referenced documents. It is intended for decoding P12/PFX-stored
// certificates and keys for use with the crypto/tls package. // certificates and keys for use with the crypto/tls package.
//
// This package is frozen. If it's missing functionality you need, consider
// an alternative like software.sslmate.com/src/go-pkcs12.
package pkcs12 package pkcs12
import ( import (
@@ -100,7 +103,7 @@ func unmarshal(in []byte, out interface{}) error {
return nil return nil
} }
// ConvertToPEM converts all "safe bags" contained in pfxData to PEM blocks. // ToPEM converts all "safe bags" contained in pfxData to PEM blocks.
func ToPEM(pfxData []byte, password string) ([]*pem.Block, error) { func ToPEM(pfxData []byte, password string) ([]*pem.Block, error) {
encodedPassword, err := bmpString(password) encodedPassword, err := bmpString(password)
if err != nil { if err != nil {
@@ -208,7 +211,7 @@ func convertAttribute(attribute *pkcs12Attribute) (key, value string, err error)
// Decode extracts a certificate and private key from pfxData. This function // Decode extracts a certificate and private key from pfxData. This function
// assumes that there is only one certificate and only one private key in the // assumes that there is only one certificate and only one private key in the
// pfxData. // pfxData; if there are more use ToPEM instead.
func Decode(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, err error) { func Decode(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, err error) {
encodedPassword, err := bmpString(password) encodedPassword, err := bmpString(password)
if err != nil { if err != nil {

11
vendor/golang.org/x/crypto/poly1305/mac_noasm.go generated vendored Normal file
View File

@@ -0,0 +1,11 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64,!ppc64le gccgo appengine
package poly1305
type mac struct{ macGeneric }
func newMAC(key *[32]byte) mac { return mac{newMACGeneric(key)} }

View File

@@ -2,21 +2,19 @@
// 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.
/* // Package poly1305 implements Poly1305 one-time message authentication code as
Package poly1305 implements Poly1305 one-time message authentication code as // specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
specified in https://cr.yp.to/mac/poly1305-20050329.pdf. //
// Poly1305 is a fast, one-time authentication function. It is infeasible for an
Poly1305 is a fast, one-time authentication function. It is infeasible for an // attacker to generate an authenticator for a message without the key. However, a
attacker to generate an authenticator for a message without the key. However, a // key must only be used for a single message. Authenticating two different
key must only be used for a single message. Authenticating two different // messages with the same key allows an attacker to forge authenticators for other
messages with the same key allows an attacker to forge authenticators for other // messages with the same key.
messages with the same key. //
// Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was // used with a fixed key in order to generate one-time keys from an nonce.
used with a fixed key in order to generate one-time keys from an nonce. // However, in this package AES isn't used and the one-time key is specified
However, in this package AES isn't used and the one-time key is specified // directly.
directly.
*/
package poly1305 // import "golang.org/x/crypto/poly1305" package poly1305 // import "golang.org/x/crypto/poly1305"
import "crypto/subtle" import "crypto/subtle"
@@ -31,3 +29,55 @@ func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
Sum(&tmp, m, key) Sum(&tmp, m, key)
return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
} }
// New returns a new MAC computing an authentication
// tag of all data written to it with the given key.
// This allows writing the message progressively instead
// of passing it as a single slice. Common users should use
// the Sum function instead.
//
// The key must be unique for each message, as authenticating
// two different messages with the same key allows an attacker
// to forge messages at will.
func New(key *[32]byte) *MAC {
return &MAC{
mac: newMAC(key),
finalized: false,
}
}
// MAC is an io.Writer computing an authentication tag
// of the data written to it.
//
// MAC cannot be used like common hash.Hash implementations,
// because using a poly1305 key twice breaks its security.
// Therefore writing data to a running MAC after calling
// Sum causes it to panic.
type MAC struct {
mac // platform-dependent implementation
finalized bool
}
// Size returns the number of bytes Sum will return.
func (h *MAC) Size() int { return TagSize }
// Write adds more data to the running message authentication code.
// It never returns an error.
//
// It must not be called after the first call of Sum.
func (h *MAC) Write(p []byte) (n int, err error) {
if h.finalized {
panic("poly1305: write to MAC after Sum")
}
return h.mac.Write(p)
}
// Sum computes the authenticator of all data written to the
// message authentication code.
func (h *MAC) Sum(b []byte) []byte {
var mac [TagSize]byte
h.mac.Sum(&mac)
h.finalized = true
return append(b, mac[:]...)
}

View File

@@ -100,7 +100,50 @@ func TestSumUnaligned(t *testing.T) { testSum(t, true, Sum) }
func TestSumGeneric(t *testing.T) { testSum(t, false, sumGeneric) } func TestSumGeneric(t *testing.T) { testSum(t, false, sumGeneric) }
func TestSumGenericUnaligned(t *testing.T) { testSum(t, true, sumGeneric) } func TestSumGenericUnaligned(t *testing.T) { testSum(t, true, sumGeneric) }
func benchmark(b *testing.B, size int, unaligned bool) { func TestWriteGeneric(t *testing.T) { testWriteGeneric(t, false) }
func TestWriteGenericUnaligned(t *testing.T) { testWriteGeneric(t, true) }
func TestWrite(t *testing.T) { testWrite(t, false) }
func TestWriteUnaligned(t *testing.T) { testWrite(t, true) }
func testWriteGeneric(t *testing.T, unaligned bool) {
for i, v := range testData {
key := v.Key()
input := v.Input()
var out [16]byte
if unaligned {
input = unalignBytes(input)
}
h := newMACGeneric(&key)
h.Write(input[:len(input)/2])
h.Write(input[len(input)/2:])
h.Sum(&out)
if tag := v.Tag(); out != tag {
t.Errorf("%d: expected %x, got %x", i, tag[:], out[:])
}
}
}
func testWrite(t *testing.T, unaligned bool) {
for i, v := range testData {
key := v.Key()
input := v.Input()
var out [16]byte
if unaligned {
input = unalignBytes(input)
}
h := New(&key)
h.Write(input[:len(input)/2])
h.Write(input[len(input)/2:])
h.Sum(out[:0])
if tag := v.Tag(); out != tag {
t.Errorf("%d: expected %x, got %x", i, tag[:], out[:])
}
}
}
func benchmarkSum(b *testing.B, size int, unaligned bool) {
var out [16]byte var out [16]byte
var key [32]byte var key [32]byte
in := make([]byte, size) in := make([]byte, size)
@@ -114,11 +157,33 @@ func benchmark(b *testing.B, size int, unaligned bool) {
} }
} }
func Benchmark64(b *testing.B) { benchmark(b, 64, false) } func benchmarkWrite(b *testing.B, size int, unaligned bool) {
func Benchmark1K(b *testing.B) { benchmark(b, 1024, false) } var key [32]byte
func Benchmark64Unaligned(b *testing.B) { benchmark(b, 64, true) } h := New(&key)
func Benchmark1KUnaligned(b *testing.B) { benchmark(b, 1024, true) } in := make([]byte, size)
func Benchmark2M(b *testing.B) { benchmark(b, 2097152, true) } if unaligned {
in = unalignBytes(in)
}
b.SetBytes(int64(len(in)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
h.Write(in)
}
}
func Benchmark64(b *testing.B) { benchmarkSum(b, 64, false) }
func Benchmark1K(b *testing.B) { benchmarkSum(b, 1024, false) }
func Benchmark2M(b *testing.B) { benchmarkSum(b, 2*1024*1024, false) }
func Benchmark64Unaligned(b *testing.B) { benchmarkSum(b, 64, true) }
func Benchmark1KUnaligned(b *testing.B) { benchmarkSum(b, 1024, true) }
func Benchmark2MUnaligned(b *testing.B) { benchmarkSum(b, 2*1024*1024, true) }
func BenchmarkWrite64(b *testing.B) { benchmarkWrite(b, 64, false) }
func BenchmarkWrite1K(b *testing.B) { benchmarkWrite(b, 1024, false) }
func BenchmarkWrite2M(b *testing.B) { benchmarkWrite(b, 2*1024*1024, false) }
func BenchmarkWrite64Unaligned(b *testing.B) { benchmarkWrite(b, 64, true) }
func BenchmarkWrite1KUnaligned(b *testing.B) { benchmarkWrite(b, 1024, true) }
func BenchmarkWrite2MUnaligned(b *testing.B) { benchmarkWrite(b, 2*1024*1024, true) }
func unalignBytes(in []byte) []byte { func unalignBytes(in []byte) []byte {
out := make([]byte, len(in)+1) out := make([]byte, len(in)+1)

View File

@@ -6,17 +6,63 @@
package poly1305 package poly1305
// This function is implemented in sum_amd64.s
//go:noescape //go:noescape
func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte) func initialize(state *[7]uint64, key *[32]byte)
//go:noescape
func update(state *[7]uint64, msg []byte)
//go:noescape
func finalize(tag *[TagSize]byte, state *[7]uint64)
// Sum generates an authenticator for m using a one-time key and puts the // Sum generates an authenticator for m using a one-time key and puts the
// 16-byte result into out. Authenticating two different messages with the same // 16-byte result into out. Authenticating two different messages with the same
// key allows an attacker to forge messages at will. // key allows an attacker to forge messages at will.
func Sum(out *[16]byte, m []byte, key *[32]byte) { func Sum(out *[16]byte, m []byte, key *[32]byte) {
var mPtr *byte h := newMAC(key)
if len(m) > 0 { h.Write(m)
mPtr = &m[0] h.Sum(out)
} }
poly1305(out, mPtr, uint64(len(m)), key)
func newMAC(key *[32]byte) (h mac) {
initialize(&h.state, key)
return
}
type mac struct {
state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 }
buffer [TagSize]byte
offset int
}
func (h *mac) Write(p []byte) (n int, err error) {
n = len(p)
if h.offset > 0 {
remaining := TagSize - h.offset
if n < remaining {
h.offset += copy(h.buffer[h.offset:], p)
return n, nil
}
copy(h.buffer[h.offset:], p[:remaining])
p = p[remaining:]
h.offset = 0
update(&h.state, h.buffer[:])
}
if nn := len(p) - (len(p) % TagSize); nn > 0 {
update(&h.state, p[:nn])
p = p[nn:]
}
if len(p) > 0 {
h.offset += copy(h.buffer[h.offset:], p)
}
return n, nil
}
func (h *mac) Sum(out *[16]byte) {
state := h.state
if h.offset > 0 {
update(&state, h.buffer[:h.offset])
}
finalize(out, &state)
} }

View File

@@ -58,20 +58,17 @@ DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
GLOBL ·poly1305Mask<>(SB), RODATA, $16 GLOBL ·poly1305Mask<>(SB), RODATA, $16
// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key) // func update(state *[7]uint64, msg []byte)
TEXT ·poly1305(SB), $0-32 TEXT ·update(SB), $0-32
MOVQ out+0(FP), DI MOVQ state+0(FP), DI
MOVQ m+8(FP), SI MOVQ msg_base+8(FP), SI
MOVQ mlen+16(FP), R15 MOVQ msg_len+16(FP), R15
MOVQ key+24(FP), AX
MOVQ 0(AX), R11 MOVQ 0(DI), R8 // h0
MOVQ 8(AX), R12 MOVQ 8(DI), R9 // h1
ANDQ ·poly1305Mask<>(SB), R11 // r0 MOVQ 16(DI), R10 // h2
ANDQ ·poly1305Mask<>+8(SB), R12 // r1 MOVQ 24(DI), R11 // r0
XORQ R8, R8 // h0 MOVQ 32(DI), R12 // r1
XORQ R9, R9 // h1
XORQ R10, R10 // h2
CMPQ R15, $16 CMPQ R15, $16
JB bytes_between_0_and_15 JB bytes_between_0_and_15
@@ -109,16 +106,42 @@ flush_buffer:
JMP multiply JMP multiply
done: done:
MOVQ R8, AX MOVQ R8, 0(DI)
MOVQ R9, BX MOVQ R9, 8(DI)
MOVQ R10, 16(DI)
RET
// func initialize(state *[7]uint64, key *[32]byte)
TEXT ·initialize(SB), $0-16
MOVQ state+0(FP), DI
MOVQ key+8(FP), SI
// state[0...7] is initialized with zero
MOVOU 0(SI), X0
MOVOU 16(SI), X1
MOVOU ·poly1305Mask<>(SB), X2
PAND X2, X0
MOVOU X0, 24(DI)
MOVOU X1, 40(DI)
RET
// func finalize(tag *[TagSize]byte, state *[7]uint64)
TEXT ·finalize(SB), $0-16
MOVQ tag+0(FP), DI
MOVQ state+8(FP), SI
MOVQ 0(SI), AX
MOVQ 8(SI), BX
MOVQ 16(SI), CX
MOVQ AX, R8
MOVQ BX, R9
SUBQ $0xFFFFFFFFFFFFFFFB, AX SUBQ $0xFFFFFFFFFFFFFFFB, AX
SBBQ $0xFFFFFFFFFFFFFFFF, BX SBBQ $0xFFFFFFFFFFFFFFFF, BX
SBBQ $3, R10 SBBQ $3, CX
CMOVQCS R8, AX CMOVQCS R8, AX
CMOVQCS R9, BX CMOVQCS R9, BX
MOVQ key+24(FP), R8 ADDQ 40(SI), AX
ADDQ 16(R8), AX ADCQ 48(SI), BX
ADCQ 24(R8), BX
MOVQ AX, 0(DI) MOVQ AX, 0(DI)
MOVQ BX, 8(DI) MOVQ BX, 8(DI)

172
vendor/golang.org/x/crypto/poly1305/sum_generic.go generated vendored Normal file
View File

@@ -0,0 +1,172 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package poly1305
import "encoding/binary"
const (
msgBlock = uint32(1 << 24)
finalBlock = uint32(0)
)
// sumGeneric generates an authenticator for msg using a one-time key and
// puts the 16-byte result into out. This is the generic implementation of
// Sum and should be called if no assembly implementation is available.
func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
h := newMACGeneric(key)
h.Write(msg)
h.Sum(out)
}
func newMACGeneric(key *[32]byte) (h macGeneric) {
h.r[0] = binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff
h.r[1] = (binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03
h.r[2] = (binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff
h.r[3] = (binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff
h.r[4] = (binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff
h.s[0] = binary.LittleEndian.Uint32(key[16:])
h.s[1] = binary.LittleEndian.Uint32(key[20:])
h.s[2] = binary.LittleEndian.Uint32(key[24:])
h.s[3] = binary.LittleEndian.Uint32(key[28:])
return
}
type macGeneric struct {
h, r [5]uint32
s [4]uint32
buffer [TagSize]byte
offset int
}
func (h *macGeneric) Write(p []byte) (n int, err error) {
n = len(p)
if h.offset > 0 {
remaining := TagSize - h.offset
if n < remaining {
h.offset += copy(h.buffer[h.offset:], p)
return n, nil
}
copy(h.buffer[h.offset:], p[:remaining])
p = p[remaining:]
h.offset = 0
updateGeneric(h.buffer[:], msgBlock, &(h.h), &(h.r))
}
if nn := len(p) - (len(p) % TagSize); nn > 0 {
updateGeneric(p, msgBlock, &(h.h), &(h.r))
p = p[nn:]
}
if len(p) > 0 {
h.offset += copy(h.buffer[h.offset:], p)
}
return n, nil
}
func (h *macGeneric) Sum(out *[16]byte) {
H, R := h.h, h.r
if h.offset > 0 {
var buffer [TagSize]byte
copy(buffer[:], h.buffer[:h.offset])
buffer[h.offset] = 1 // invariant: h.offset < TagSize
updateGeneric(buffer[:], finalBlock, &H, &R)
}
finalizeGeneric(out, &H, &(h.s))
}
func updateGeneric(msg []byte, flag uint32, h, r *[5]uint32) {
h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4]
r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4])
R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5
for len(msg) >= TagSize {
// h += msg
h0 += binary.LittleEndian.Uint32(msg[0:]) & 0x3ffffff
h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff
h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff
h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff
h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | flag
// h *= r
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2)
d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3)
d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4)
d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0)
// h %= p
h0 = uint32(d0) & 0x3ffffff
h1 = uint32(d1) & 0x3ffffff
h2 = uint32(d2) & 0x3ffffff
h3 = uint32(d3) & 0x3ffffff
h4 = uint32(d4) & 0x3ffffff
h0 += uint32(d4>>26) * 5
h1 += h0 >> 26
h0 = h0 & 0x3ffffff
msg = msg[TagSize:]
}
h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4
}
func finalizeGeneric(out *[TagSize]byte, h *[5]uint32, s *[4]uint32) {
h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4]
// h %= p reduction
h2 += h1 >> 26
h1 &= 0x3ffffff
h3 += h2 >> 26
h2 &= 0x3ffffff
h4 += h3 >> 26
h3 &= 0x3ffffff
h0 += 5 * (h4 >> 26)
h4 &= 0x3ffffff
h1 += h0 >> 26
h0 &= 0x3ffffff
// h - p
t0 := h0 + 5
t1 := h1 + (t0 >> 26)
t2 := h2 + (t1 >> 26)
t3 := h3 + (t2 >> 26)
t4 := h4 + (t3 >> 26) - (1 << 26)
t0 &= 0x3ffffff
t1 &= 0x3ffffff
t2 &= 0x3ffffff
t3 &= 0x3ffffff
// select h if h < p else h - p
t_mask := (t4 >> 31) - 1
h_mask := ^t_mask
h0 = (h0 & h_mask) | (t0 & t_mask)
h1 = (h1 & h_mask) | (t1 & t_mask)
h2 = (h2 & h_mask) | (t2 & t_mask)
h3 = (h3 & h_mask) | (t3 & t_mask)
h4 = (h4 & h_mask) | (t4 & t_mask)
// h %= 2^128
h0 |= h1 << 26
h1 = ((h1 >> 6) | (h2 << 20))
h2 = ((h2 >> 12) | (h3 << 14))
h3 = ((h3 >> 18) | (h4 << 8))
// s: the s part of the key
// tag = (h + s) % (2^128)
t := uint64(h0) + uint64(s[0])
h0 = uint32(t)
t = uint64(h1) + uint64(s[1]) + (t >> 32)
h1 = uint32(t)
t = uint64(h2) + uint64(s[2]) + (t >> 32)
h2 = uint32(t)
t = uint64(h3) + uint64(s[3]) + (t >> 32)
h3 = uint32(t)
binary.LittleEndian.PutUint32(out[0:], h0)
binary.LittleEndian.PutUint32(out[4:], h1)
binary.LittleEndian.PutUint32(out[8:], h2)
binary.LittleEndian.PutUint32(out[12:], h3)
}

View File

@@ -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 s390x,!go1.11 !arm,!amd64,!s390x gccgo appengine nacl // +build s390x,!go1.11 !arm,!amd64,!s390x,!ppc64le gccgo appengine nacl
package poly1305 package poly1305
@@ -10,5 +10,7 @@ package poly1305
// 16-byte result into out. Authenticating two different messages with the same // 16-byte result into out. Authenticating two different messages with the same
// key allows an attacker to forge messages at will. // key allows an attacker to forge messages at will.
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) { func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
sumGeneric(out, msg, key) h := newMAC(key)
h.Write(msg)
h.Sum(out)
} }

68
vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go generated vendored Normal file
View File

@@ -0,0 +1,68 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ppc64le,!gccgo,!appengine
package poly1305
//go:noescape
func initialize(state *[7]uint64, key *[32]byte)
//go:noescape
func update(state *[7]uint64, msg []byte)
//go:noescape
func finalize(tag *[TagSize]byte, state *[7]uint64)
// Sum generates an authenticator for m using a one-time key and puts the
// 16-byte result into out. Authenticating two different messages with the same
// key allows an attacker to forge messages at will.
func Sum(out *[16]byte, m []byte, key *[32]byte) {
h := newMAC(key)
h.Write(m)
h.Sum(out)
}
func newMAC(key *[32]byte) (h mac) {
initialize(&h.state, key)
return
}
type mac struct {
state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 }
buffer [TagSize]byte
offset int
}
func (h *mac) Write(p []byte) (n int, err error) {
n = len(p)
if h.offset > 0 {
remaining := TagSize - h.offset
if n < remaining {
h.offset += copy(h.buffer[h.offset:], p)
return n, nil
}
copy(h.buffer[h.offset:], p[:remaining])
p = p[remaining:]
h.offset = 0
update(&h.state, h.buffer[:])
}
if nn := len(p) - (len(p) % TagSize); nn > 0 {
update(&h.state, p[:nn])
p = p[nn:]
}
if len(p) > 0 {
h.offset += copy(h.buffer[h.offset:], p)
}
return n, nil
}
func (h *mac) Sum(out *[16]byte) {
state := h.state
if h.offset > 0 {
update(&state, h.buffer[:h.offset])
}
finalize(out, &state)
}

247
vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s generated vendored Normal file
View File

@@ -0,0 +1,247 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ppc64le,!gccgo,!appengine
#include "textflag.h"
// This was ported from the amd64 implementation.
#define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \
MOVD (msg), t0; \
MOVD 8(msg), t1; \
MOVD $1, t2; \
ADDC t0, h0, h0; \
ADDE t1, h1, h1; \
ADDE t2, h2; \
ADD $16, msg
#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \
MULLD r0, h0, t0; \
MULLD r0, h1, t4; \
MULHDU r0, h0, t1; \
MULHDU r0, h1, t5; \
ADDC t4, t1, t1; \
MULLD r0, h2, t2; \
ADDZE t5; \
MULHDU r1, h0, t4; \
MULLD r1, h0, h0; \
ADD t5, t2, t2; \
ADDC h0, t1, t1; \
MULLD h2, r1, t3; \
ADDZE t4, h0; \
MULHDU r1, h1, t5; \
MULLD r1, h1, t4; \
ADDC t4, t2, t2; \
ADDE t5, t3, t3; \
ADDC h0, t2, t2; \
MOVD $-4, t4; \
MOVD t0, h0; \
MOVD t1, h1; \
ADDZE t3; \
ANDCC $3, t2, h2; \
AND t2, t4, t0; \
ADDC t0, h0, h0; \
ADDE t3, h1, h1; \
SLD $62, t3, t4; \
SRD $2, t2; \
ADDZE h2; \
OR t4, t2, t2; \
SRD $2, t3; \
ADDC t2, h0, h0; \
ADDE t3, h1, h1; \
ADDZE h2
DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
GLOBL ·poly1305Mask<>(SB), RODATA, $16
// func update(state *[7]uint64, msg []byte)
TEXT ·update(SB), $0-32
MOVD state+0(FP), R3
MOVD msg_base+8(FP), R4
MOVD msg_len+16(FP), R5
MOVD 0(R3), R8 // h0
MOVD 8(R3), R9 // h1
MOVD 16(R3), R10 // h2
MOVD 24(R3), R11 // r0
MOVD 32(R3), R12 // r1
CMP R5, $16
BLT bytes_between_0_and_15
loop:
POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22)
multiply:
POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21)
ADD $-16, R5
CMP R5, $16
BGE loop
bytes_between_0_and_15:
CMP $0, R5
BEQ done
MOVD $0, R16 // h0
MOVD $0, R17 // h1
flush_buffer:
CMP R5, $8
BLE just1
MOVD $8, R21
SUB R21, R5, R21
// Greater than 8 -- load the rightmost remaining bytes in msg
// and put into R17 (h1)
MOVD (R4)(R21), R17
MOVD $16, R22
// Find the offset to those bytes
SUB R5, R22, R22
SLD $3, R22
// Shift to get only the bytes in msg
SRD R22, R17, R17
// Put 1 at high end
MOVD $1, R23
SLD $3, R21
SLD R21, R23, R23
OR R23, R17, R17
// Remainder is 8
MOVD $8, R5
just1:
CMP R5, $8
BLT less8
// Exactly 8
MOVD (R4), R16
CMP $0, R17
// Check if we've already set R17; if not
// set 1 to indicate end of msg.
BNE carry
MOVD $1, R17
BR carry
less8:
MOVD $0, R16 // h0
MOVD $0, R22 // shift count
CMP R5, $4
BLT less4
MOVWZ (R4), R16
ADD $4, R4
ADD $-4, R5
MOVD $32, R22
less4:
CMP R5, $2
BLT less2
MOVHZ (R4), R21
SLD R22, R21, R21
OR R16, R21, R16
ADD $16, R22
ADD $-2, R5
ADD $2, R4
less2:
CMP $0, R5
BEQ insert1
MOVBZ (R4), R21
SLD R22, R21, R21
OR R16, R21, R16
ADD $8, R22
insert1:
// Insert 1 at end of msg
MOVD $1, R21
SLD R22, R21, R21
OR R16, R21, R16
carry:
// Add new values to h0, h1, h2
ADDC R16, R8
ADDE R17, R9
ADDE $0, R10
MOVD $16, R5
ADD R5, R4
BR multiply
done:
// Save h0, h1, h2 in state
MOVD R8, 0(R3)
MOVD R9, 8(R3)
MOVD R10, 16(R3)
RET
// func initialize(state *[7]uint64, key *[32]byte)
TEXT ·initialize(SB), $0-16
MOVD state+0(FP), R3
MOVD key+8(FP), R4
// state[0...7] is initialized with zero
// Load key
MOVD 0(R4), R5
MOVD 8(R4), R6
MOVD 16(R4), R7
MOVD 24(R4), R8
// Address of key mask
MOVD $·poly1305Mask<>(SB), R9
// Save original key in state
MOVD R7, 40(R3)
MOVD R8, 48(R3)
// Get mask
MOVD (R9), R7
MOVD 8(R9), R8
// And with key
AND R5, R7, R5
AND R6, R8, R6
// Save masked key in state
MOVD R5, 24(R3)
MOVD R6, 32(R3)
RET
// func finalize(tag *[TagSize]byte, state *[7]uint64)
TEXT ·finalize(SB), $0-16
MOVD tag+0(FP), R3
MOVD state+8(FP), R4
// Get h0, h1, h2 from state
MOVD 0(R4), R5
MOVD 8(R4), R6
MOVD 16(R4), R7
// Save h0, h1
MOVD R5, R8
MOVD R6, R9
MOVD $3, R20
MOVD $-1, R21
SUBC $-5, R5
SUBE R21, R6
SUBE R20, R7
MOVD $0, R21
SUBZE R21
// Check for carry
CMP $0, R21
ISEL $2, R5, R8, R5
ISEL $2, R6, R9, R6
MOVD 40(R4), R8
MOVD 48(R4), R9
ADDC R8, R5
ADDE R9, R6
MOVD R5, 0(R3)
MOVD R6, 8(R3)
RET

View File

@@ -1,139 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package poly1305
import "encoding/binary"
// sumGeneric generates an authenticator for msg using a one-time key and
// puts the 16-byte result into out. This is the generic implementation of
// Sum and should be called if no assembly implementation is available.
func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
var (
h0, h1, h2, h3, h4 uint32 // the hash accumulators
r0, r1, r2, r3, r4 uint64 // the r part of the key
)
r0 = uint64(binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff)
r1 = uint64((binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03)
r2 = uint64((binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff)
r3 = uint64((binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff)
r4 = uint64((binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff)
R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5
for len(msg) >= TagSize {
// h += msg
h0 += binary.LittleEndian.Uint32(msg[0:]) & 0x3ffffff
h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff
h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff
h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff
h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | (1 << 24)
// h *= r
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2)
d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3)
d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4)
d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0)
// h %= p
h0 = uint32(d0) & 0x3ffffff
h1 = uint32(d1) & 0x3ffffff
h2 = uint32(d2) & 0x3ffffff
h3 = uint32(d3) & 0x3ffffff
h4 = uint32(d4) & 0x3ffffff
h0 += uint32(d4>>26) * 5
h1 += h0 >> 26
h0 = h0 & 0x3ffffff
msg = msg[TagSize:]
}
if len(msg) > 0 {
var block [TagSize]byte
off := copy(block[:], msg)
block[off] = 0x01
// h += msg
h0 += binary.LittleEndian.Uint32(block[0:]) & 0x3ffffff
h1 += (binary.LittleEndian.Uint32(block[3:]) >> 2) & 0x3ffffff
h2 += (binary.LittleEndian.Uint32(block[6:]) >> 4) & 0x3ffffff
h3 += (binary.LittleEndian.Uint32(block[9:]) >> 6) & 0x3ffffff
h4 += (binary.LittleEndian.Uint32(block[12:]) >> 8)
// h *= r
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2)
d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3)
d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4)
d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0)
// h %= p
h0 = uint32(d0) & 0x3ffffff
h1 = uint32(d1) & 0x3ffffff
h2 = uint32(d2) & 0x3ffffff
h3 = uint32(d3) & 0x3ffffff
h4 = uint32(d4) & 0x3ffffff
h0 += uint32(d4>>26) * 5
h1 += h0 >> 26
h0 = h0 & 0x3ffffff
}
// h %= p reduction
h2 += h1 >> 26
h1 &= 0x3ffffff
h3 += h2 >> 26
h2 &= 0x3ffffff
h4 += h3 >> 26
h3 &= 0x3ffffff
h0 += 5 * (h4 >> 26)
h4 &= 0x3ffffff
h1 += h0 >> 26
h0 &= 0x3ffffff
// h - p
t0 := h0 + 5
t1 := h1 + (t0 >> 26)
t2 := h2 + (t1 >> 26)
t3 := h3 + (t2 >> 26)
t4 := h4 + (t3 >> 26) - (1 << 26)
t0 &= 0x3ffffff
t1 &= 0x3ffffff
t2 &= 0x3ffffff
t3 &= 0x3ffffff
// select h if h < p else h - p
t_mask := (t4 >> 31) - 1
h_mask := ^t_mask
h0 = (h0 & h_mask) | (t0 & t_mask)
h1 = (h1 & h_mask) | (t1 & t_mask)
h2 = (h2 & h_mask) | (t2 & t_mask)
h3 = (h3 & h_mask) | (t3 & t_mask)
h4 = (h4 & h_mask) | (t4 & t_mask)
// h %= 2^128
h0 |= h1 << 26
h1 = ((h1 >> 6) | (h2 << 20))
h2 = ((h2 >> 12) | (h3 << 14))
h3 = ((h3 >> 18) | (h4 << 8))
// s: the s part of the key
// tag = (h + s) % (2^128)
t := uint64(h0) + uint64(binary.LittleEndian.Uint32(key[16:]))
h0 = uint32(t)
t = uint64(h1) + uint64(binary.LittleEndian.Uint32(key[20:])) + (t >> 32)
h1 = uint32(t)
t = uint64(h2) + uint64(binary.LittleEndian.Uint32(key[24:])) + (t >> 32)
h2 = uint32(t)
t = uint64(h3) + uint64(binary.LittleEndian.Uint32(key[28:])) + (t >> 32)
h3 = uint32(t)
binary.LittleEndian.PutUint32(out[0:], h0)
binary.LittleEndian.PutUint32(out[4:], h1)
binary.LittleEndian.PutUint32(out[8:], h2)
binary.LittleEndian.PutUint32(out[12:], h3)
}

View File

@@ -6,16 +6,9 @@
package poly1305 package poly1305
// hasVectorFacility reports whether the machine supports import (
// the vector facility (vx). "golang.org/x/sys/cpu"
func hasVectorFacility() bool )
// hasVMSLFacility reports whether the machine supports
// Vector Multiply Sum Logical (VMSL).
func hasVMSLFacility() bool
var hasVX = hasVectorFacility()
var hasVMSL = hasVMSLFacility()
// poly1305vx is an assembly implementation of Poly1305 that uses vector // poly1305vx is an assembly implementation of Poly1305 that uses vector
// instructions. It must only be called if the vector facility (vx) is // instructions. It must only be called if the vector facility (vx) is
@@ -33,12 +26,12 @@ func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
// 16-byte result into out. Authenticating two different messages with the same // 16-byte result into out. Authenticating two different messages with the same
// key allows an attacker to forge messages at will. // key allows an attacker to forge messages at will.
func Sum(out *[16]byte, m []byte, key *[32]byte) { func Sum(out *[16]byte, m []byte, key *[32]byte) {
if hasVX { if cpu.S390X.HasVX {
var mPtr *byte var mPtr *byte
if len(m) > 0 { if len(m) > 0 {
mPtr = &m[0] mPtr = &m[0]
} }
if hasVMSL && len(m) > 256 { if cpu.S390X.HasVXE && len(m) > 256 {
poly1305vmsl(out, mPtr, uint64(len(m)), key) poly1305vmsl(out, mPtr, uint64(len(m)), key)
} else { } else {
poly1305vx(out, mPtr, uint64(len(m)), key) poly1305vx(out, mPtr, uint64(len(m)), key)

View File

@@ -376,25 +376,3 @@ b1:
MOVD $0, R3 MOVD $0, R3
BR multiply BR multiply
TEXT ·hasVectorFacility(SB), NOSPLIT, $24-1
MOVD $x-24(SP), R1
XC $24, 0(R1), 0(R1) // clear the storage
MOVD $2, R0 // R0 is the number of double words stored -1
WORD $0xB2B01000 // STFLE 0(R1)
XOR R0, R0 // reset the value of R0
MOVBZ z-8(SP), R1
AND $0x40, R1
BEQ novector
vectorinstalled:
// check if the vector instruction has been enabled
VLEIB $0, $0xF, V16
VLGVB $0, V16, R1
CMPBNE R1, $0xF, novector
MOVB $1, ret+0(FP) // have vx
RET
novector:
MOVB $0, ret+0(FP) // no vx
RET

View File

@@ -907,25 +907,3 @@ square:
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5) REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
BR next BR next
TEXT ·hasVMSLFacility(SB), NOSPLIT, $24-1
MOVD $x-24(SP), R1
XC $24, 0(R1), 0(R1) // clear the storage
MOVD $2, R0 // R0 is the number of double words stored -1
WORD $0xB2B01000 // STFLE 0(R1)
XOR R0, R0 // reset the value of R0
MOVBZ z-8(SP), R1
AND $0x01, R1
BEQ novmsl
vectorinstalled:
// check if the vector instruction has been enabled
VLEIB $0, $0xF, V16
VLGVB $0, V16, R1
CMPBNE R1, $0xF, novmsl
MOVB $1, ret+0(FP) // have vx
RET
novmsl:
MOVB $0, ret+0(FP) // no vx
RET

View File

@@ -3,9 +3,13 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package ripemd160 implements the RIPEMD-160 hash algorithm. // Package ripemd160 implements the RIPEMD-160 hash algorithm.
//
// Deprecated: RIPEMD-160 is a legacy hash and should not be used for new
// applications. Also, this package does not and will not provide an optimized
// implementation. Instead, use a modern hash like SHA-256 (from crypto/sha256).
package ripemd160 // import "golang.org/x/crypto/ripemd160" package ripemd160 // import "golang.org/x/crypto/ripemd160"
// RIPEMD-160 is designed by by Hans Dobbertin, Antoon Bosselaers, and Bart // RIPEMD-160 is designed by Hans Dobbertin, Antoon Bosselaers, and Bart
// Preneel with specifications available at: // Preneel with specifications available at:
// http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf. // http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf.

View File

@@ -1,889 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!appengine,!gccgo
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
// func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
// This needs up to 64 bytes at 360(SP); hence the non-obvious frame size.
TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
MOVQ out+0(FP),DI
MOVQ in+8(FP),SI
MOVQ n+16(FP),DX
MOVQ nonce+24(FP),CX
MOVQ key+32(FP),R8
MOVQ SP,R12
MOVQ SP,R9
ADDQ $31, R9
ANDQ $~31, R9
MOVQ R9, SP
MOVQ DX,R9
MOVQ CX,DX
MOVQ R8,R10
CMPQ R9,$0
JBE DONE
START:
MOVL 20(R10),CX
MOVL 0(R10),R8
MOVL 0(DX),AX
MOVL 16(R10),R11
MOVL CX,0(SP)
MOVL R8, 4 (SP)
MOVL AX, 8 (SP)
MOVL R11, 12 (SP)
MOVL 8(DX),CX
MOVL 24(R10),R8
MOVL 4(R10),AX
MOVL 4(DX),R11
MOVL CX,16(SP)
MOVL R8, 20 (SP)
MOVL AX, 24 (SP)
MOVL R11, 28 (SP)
MOVL 12(DX),CX
MOVL 12(R10),DX
MOVL 28(R10),R8
MOVL 8(R10),AX
MOVL DX,32(SP)
MOVL CX, 36 (SP)
MOVL R8, 40 (SP)
MOVL AX, 44 (SP)
MOVQ $1634760805,DX
MOVQ $857760878,CX
MOVQ $2036477234,R8
MOVQ $1797285236,AX
MOVL DX,48(SP)
MOVL CX, 52 (SP)
MOVL R8, 56 (SP)
MOVL AX, 60 (SP)
CMPQ R9,$256
JB BYTESBETWEEN1AND255
MOVOA 48(SP),X0
PSHUFL $0X55,X0,X1
PSHUFL $0XAA,X0,X2
PSHUFL $0XFF,X0,X3
PSHUFL $0X00,X0,X0
MOVOA X1,64(SP)
MOVOA X2,80(SP)
MOVOA X3,96(SP)
MOVOA X0,112(SP)
MOVOA 0(SP),X0
PSHUFL $0XAA,X0,X1
PSHUFL $0XFF,X0,X2
PSHUFL $0X00,X0,X3
PSHUFL $0X55,X0,X0
MOVOA X1,128(SP)
MOVOA X2,144(SP)
MOVOA X3,160(SP)
MOVOA X0,176(SP)
MOVOA 16(SP),X0
PSHUFL $0XFF,X0,X1
PSHUFL $0X55,X0,X2
PSHUFL $0XAA,X0,X0
MOVOA X1,192(SP)
MOVOA X2,208(SP)
MOVOA X0,224(SP)
MOVOA 32(SP),X0
PSHUFL $0X00,X0,X1
PSHUFL $0XAA,X0,X2
PSHUFL $0XFF,X0,X0
MOVOA X1,240(SP)
MOVOA X2,256(SP)
MOVOA X0,272(SP)
BYTESATLEAST256:
MOVL 16(SP),DX
MOVL 36 (SP),CX
MOVL DX,288(SP)
MOVL CX,304(SP)
ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 292 (SP)
MOVL CX, 308 (SP)
ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 296 (SP)
MOVL CX, 312 (SP)
ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 300 (SP)
MOVL CX, 316 (SP)
ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX,16(SP)
MOVL CX, 36 (SP)
MOVQ R9,352(SP)
MOVQ $20,DX
MOVOA 64(SP),X0
MOVOA 80(SP),X1
MOVOA 96(SP),X2
MOVOA 256(SP),X3
MOVOA 272(SP),X4
MOVOA 128(SP),X5
MOVOA 144(SP),X6
MOVOA 176(SP),X7
MOVOA 192(SP),X8
MOVOA 208(SP),X9
MOVOA 224(SP),X10
MOVOA 304(SP),X11
MOVOA 112(SP),X12
MOVOA 160(SP),X13
MOVOA 240(SP),X14
MOVOA 288(SP),X15
MAINLOOP1:
MOVOA X1,320(SP)
MOVOA X2,336(SP)
MOVOA X13,X1
PADDL X12,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X14
PSRLL $25,X2
PXOR X2,X14
MOVOA X7,X1
PADDL X0,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X11
PSRLL $25,X2
PXOR X2,X11
MOVOA X12,X1
PADDL X14,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X15
PSRLL $23,X2
PXOR X2,X15
MOVOA X0,X1
PADDL X11,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X9
PSRLL $23,X2
PXOR X2,X9
MOVOA X14,X1
PADDL X15,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X13
PSRLL $19,X2
PXOR X2,X13
MOVOA X11,X1
PADDL X9,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X7
PSRLL $19,X2
PXOR X2,X7
MOVOA X15,X1
PADDL X13,X1
MOVOA X1,X2
PSLLL $18,X1
PXOR X1,X12
PSRLL $14,X2
PXOR X2,X12
MOVOA 320(SP),X1
MOVOA X12,320(SP)
MOVOA X9,X2
PADDL X7,X2
MOVOA X2,X12
PSLLL $18,X2
PXOR X2,X0
PSRLL $14,X12
PXOR X12,X0
MOVOA X5,X2
PADDL X1,X2
MOVOA X2,X12
PSLLL $7,X2
PXOR X2,X3
PSRLL $25,X12
PXOR X12,X3
MOVOA 336(SP),X2
MOVOA X0,336(SP)
MOVOA X6,X0
PADDL X2,X0
MOVOA X0,X12
PSLLL $7,X0
PXOR X0,X4
PSRLL $25,X12
PXOR X12,X4
MOVOA X1,X0
PADDL X3,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X10
PSRLL $23,X12
PXOR X12,X10
MOVOA X2,X0
PADDL X4,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X8
PSRLL $23,X12
PXOR X12,X8
MOVOA X3,X0
PADDL X10,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X5
PSRLL $19,X12
PXOR X12,X5
MOVOA X4,X0
PADDL X8,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X6
PSRLL $19,X12
PXOR X12,X6
MOVOA X10,X0
PADDL X5,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X1
PSRLL $14,X12
PXOR X12,X1
MOVOA 320(SP),X0
MOVOA X1,320(SP)
MOVOA X4,X1
PADDL X0,X1
MOVOA X1,X12
PSLLL $7,X1
PXOR X1,X7
PSRLL $25,X12
PXOR X12,X7
MOVOA X8,X1
PADDL X6,X1
MOVOA X1,X12
PSLLL $18,X1
PXOR X1,X2
PSRLL $14,X12
PXOR X12,X2
MOVOA 336(SP),X12
MOVOA X2,336(SP)
MOVOA X14,X1
PADDL X12,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X5
PSRLL $25,X2
PXOR X2,X5
MOVOA X0,X1
PADDL X7,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X10
PSRLL $23,X2
PXOR X2,X10
MOVOA X12,X1
PADDL X5,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X8
PSRLL $23,X2
PXOR X2,X8
MOVOA X7,X1
PADDL X10,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X4
PSRLL $19,X2
PXOR X2,X4
MOVOA X5,X1
PADDL X8,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X14
PSRLL $19,X2
PXOR X2,X14
MOVOA X10,X1
PADDL X4,X1
MOVOA X1,X2
PSLLL $18,X1
PXOR X1,X0
PSRLL $14,X2
PXOR X2,X0
MOVOA 320(SP),X1
MOVOA X0,320(SP)
MOVOA X8,X0
PADDL X14,X0
MOVOA X0,X2
PSLLL $18,X0
PXOR X0,X12
PSRLL $14,X2
PXOR X2,X12
MOVOA X11,X0
PADDL X1,X0
MOVOA X0,X2
PSLLL $7,X0
PXOR X0,X6
PSRLL $25,X2
PXOR X2,X6
MOVOA 336(SP),X2
MOVOA X12,336(SP)
MOVOA X3,X0
PADDL X2,X0
MOVOA X0,X12
PSLLL $7,X0
PXOR X0,X13
PSRLL $25,X12
PXOR X12,X13
MOVOA X1,X0
PADDL X6,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X15
PSRLL $23,X12
PXOR X12,X15
MOVOA X2,X0
PADDL X13,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X9
PSRLL $23,X12
PXOR X12,X9
MOVOA X6,X0
PADDL X15,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X11
PSRLL $19,X12
PXOR X12,X11
MOVOA X13,X0
PADDL X9,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X3
PSRLL $19,X12
PXOR X12,X3
MOVOA X15,X0
PADDL X11,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X1
PSRLL $14,X12
PXOR X12,X1
MOVOA X9,X0
PADDL X3,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X2
PSRLL $14,X12
PXOR X12,X2
MOVOA 320(SP),X12
MOVOA 336(SP),X0
SUBQ $2,DX
JA MAINLOOP1
PADDL 112(SP),X12
PADDL 176(SP),X7
PADDL 224(SP),X10
PADDL 272(SP),X4
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 0(SI),DX
XORL 4(SI),CX
XORL 8(SI),R8
XORL 12(SI),R9
MOVL DX,0(DI)
MOVL CX,4(DI)
MOVL R8,8(DI)
MOVL R9,12(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 64(SI),DX
XORL 68(SI),CX
XORL 72(SI),R8
XORL 76(SI),R9
MOVL DX,64(DI)
MOVL CX,68(DI)
MOVL R8,72(DI)
MOVL R9,76(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 128(SI),DX
XORL 132(SI),CX
XORL 136(SI),R8
XORL 140(SI),R9
MOVL DX,128(DI)
MOVL CX,132(DI)
MOVL R8,136(DI)
MOVL R9,140(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
XORL 192(SI),DX
XORL 196(SI),CX
XORL 200(SI),R8
XORL 204(SI),R9
MOVL DX,192(DI)
MOVL CX,196(DI)
MOVL R8,200(DI)
MOVL R9,204(DI)
PADDL 240(SP),X14
PADDL 64(SP),X0
PADDL 128(SP),X5
PADDL 192(SP),X8
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 16(SI),DX
XORL 20(SI),CX
XORL 24(SI),R8
XORL 28(SI),R9
MOVL DX,16(DI)
MOVL CX,20(DI)
MOVL R8,24(DI)
MOVL R9,28(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 80(SI),DX
XORL 84(SI),CX
XORL 88(SI),R8
XORL 92(SI),R9
MOVL DX,80(DI)
MOVL CX,84(DI)
MOVL R8,88(DI)
MOVL R9,92(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 144(SI),DX
XORL 148(SI),CX
XORL 152(SI),R8
XORL 156(SI),R9
MOVL DX,144(DI)
MOVL CX,148(DI)
MOVL R8,152(DI)
MOVL R9,156(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
XORL 208(SI),DX
XORL 212(SI),CX
XORL 216(SI),R8
XORL 220(SI),R9
MOVL DX,208(DI)
MOVL CX,212(DI)
MOVL R8,216(DI)
MOVL R9,220(DI)
PADDL 288(SP),X15
PADDL 304(SP),X11
PADDL 80(SP),X1
PADDL 144(SP),X6
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 32(SI),DX
XORL 36(SI),CX
XORL 40(SI),R8
XORL 44(SI),R9
MOVL DX,32(DI)
MOVL CX,36(DI)
MOVL R8,40(DI)
MOVL R9,44(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 96(SI),DX
XORL 100(SI),CX
XORL 104(SI),R8
XORL 108(SI),R9
MOVL DX,96(DI)
MOVL CX,100(DI)
MOVL R8,104(DI)
MOVL R9,108(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 160(SI),DX
XORL 164(SI),CX
XORL 168(SI),R8
XORL 172(SI),R9
MOVL DX,160(DI)
MOVL CX,164(DI)
MOVL R8,168(DI)
MOVL R9,172(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
XORL 224(SI),DX
XORL 228(SI),CX
XORL 232(SI),R8
XORL 236(SI),R9
MOVL DX,224(DI)
MOVL CX,228(DI)
MOVL R8,232(DI)
MOVL R9,236(DI)
PADDL 160(SP),X13
PADDL 208(SP),X9
PADDL 256(SP),X3
PADDL 96(SP),X2
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 48(SI),DX
XORL 52(SI),CX
XORL 56(SI),R8
XORL 60(SI),R9
MOVL DX,48(DI)
MOVL CX,52(DI)
MOVL R8,56(DI)
MOVL R9,60(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 112(SI),DX
XORL 116(SI),CX
XORL 120(SI),R8
XORL 124(SI),R9
MOVL DX,112(DI)
MOVL CX,116(DI)
MOVL R8,120(DI)
MOVL R9,124(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 176(SI),DX
XORL 180(SI),CX
XORL 184(SI),R8
XORL 188(SI),R9
MOVL DX,176(DI)
MOVL CX,180(DI)
MOVL R8,184(DI)
MOVL R9,188(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
XORL 240(SI),DX
XORL 244(SI),CX
XORL 248(SI),R8
XORL 252(SI),R9
MOVL DX,240(DI)
MOVL CX,244(DI)
MOVL R8,248(DI)
MOVL R9,252(DI)
MOVQ 352(SP),R9
SUBQ $256,R9
ADDQ $256,SI
ADDQ $256,DI
CMPQ R9,$256
JAE BYTESATLEAST256
CMPQ R9,$0
JBE DONE
BYTESBETWEEN1AND255:
CMPQ R9,$64
JAE NOCOPY
MOVQ DI,DX
LEAQ 360(SP),DI
MOVQ R9,CX
REP; MOVSB
LEAQ 360(SP),DI
LEAQ 360(SP),SI
NOCOPY:
MOVQ R9,352(SP)
MOVOA 48(SP),X0
MOVOA 0(SP),X1
MOVOA 16(SP),X2
MOVOA 32(SP),X3
MOVOA X1,X4
MOVQ $20,CX
MAINLOOP2:
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X3
PXOR X6,X3
PADDL X3,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X3,X3
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X1
PSHUFL $0X4E,X2,X2
PXOR X6,X1
PADDL X1,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X1,X1
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X1
PXOR X6,X1
PADDL X1,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X1,X1
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X3
PSHUFL $0X4E,X2,X2
PXOR X6,X3
PADDL X3,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X3,X3
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X3
PXOR X6,X3
PADDL X3,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X3,X3
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X1
PSHUFL $0X4E,X2,X2
PXOR X6,X1
PADDL X1,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X1,X1
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X1
PXOR X6,X1
PADDL X1,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X1,X1
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X3
PSHUFL $0X4E,X2,X2
PXOR X6,X3
SUBQ $4,CX
PADDL X3,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $18,X5
PXOR X7,X7
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X3,X3
PXOR X6,X0
JA MAINLOOP2
PADDL 48(SP),X0
PADDL 0(SP),X1
PADDL 16(SP),X2
PADDL 32(SP),X3
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 0(SI),CX
XORL 48(SI),R8
XORL 32(SI),R9
XORL 16(SI),AX
MOVL CX,0(DI)
MOVL R8,48(DI)
MOVL R9,32(DI)
MOVL AX,16(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 20(SI),CX
XORL 4(SI),R8
XORL 52(SI),R9
XORL 36(SI),AX
MOVL CX,20(DI)
MOVL R8,4(DI)
MOVL R9,52(DI)
MOVL AX,36(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 40(SI),CX
XORL 24(SI),R8
XORL 8(SI),R9
XORL 56(SI),AX
MOVL CX,40(DI)
MOVL R8,24(DI)
MOVL R9,8(DI)
MOVL AX,56(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
XORL 60(SI),CX
XORL 44(SI),R8
XORL 28(SI),R9
XORL 12(SI),AX
MOVL CX,60(DI)
MOVL R8,44(DI)
MOVL R9,28(DI)
MOVL AX,12(DI)
MOVQ 352(SP),R9
MOVL 16(SP),CX
MOVL 36 (SP),R8
ADDQ $1,CX
SHLQ $32,R8
ADDQ R8,CX
MOVQ CX,R8
SHRQ $32,R8
MOVL CX,16(SP)
MOVL R8, 36 (SP)
CMPQ R9,$64
JA BYTESATLEAST65
JAE BYTESATLEAST64
MOVQ DI,SI
MOVQ DX,DI
MOVQ R9,CX
REP; MOVSB
BYTESATLEAST64:
DONE:
MOVQ R12,SP
RET
BYTESATLEAST65:
SUBQ $64,R9
ADDQ $64,DI
ADDQ $64,SI
JMP BYTESBETWEEN1AND255

View File

@@ -6,10 +6,9 @@
package salsa package salsa
// This function is implemented in salsa2020_amd64.s.
//go:noescape //go:noescape
// salsa2020XORKeyStream is implemented in salsa20_amd64.s.
func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte) func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
// XORKeyStream crypts bytes from in to out using the given key and counters. // XORKeyStream crypts bytes from in to out using the given key and counters.

View File

@@ -0,0 +1,883 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!appengine,!gccgo
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
// func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
// This needs up to 64 bytes at 360(SP); hence the non-obvious frame size.
TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
MOVQ out+0(FP),DI
MOVQ in+8(FP),SI
MOVQ n+16(FP),DX
MOVQ nonce+24(FP),CX
MOVQ key+32(FP),R8
MOVQ SP,R12
MOVQ SP,R9
ADDQ $31, R9
ANDQ $~31, R9
MOVQ R9, SP
MOVQ DX,R9
MOVQ CX,DX
MOVQ R8,R10
CMPQ R9,$0
JBE DONE
START:
MOVL 20(R10),CX
MOVL 0(R10),R8
MOVL 0(DX),AX
MOVL 16(R10),R11
MOVL CX,0(SP)
MOVL R8, 4 (SP)
MOVL AX, 8 (SP)
MOVL R11, 12 (SP)
MOVL 8(DX),CX
MOVL 24(R10),R8
MOVL 4(R10),AX
MOVL 4(DX),R11
MOVL CX,16(SP)
MOVL R8, 20 (SP)
MOVL AX, 24 (SP)
MOVL R11, 28 (SP)
MOVL 12(DX),CX
MOVL 12(R10),DX
MOVL 28(R10),R8
MOVL 8(R10),AX
MOVL DX,32(SP)
MOVL CX, 36 (SP)
MOVL R8, 40 (SP)
MOVL AX, 44 (SP)
MOVQ $1634760805,DX
MOVQ $857760878,CX
MOVQ $2036477234,R8
MOVQ $1797285236,AX
MOVL DX,48(SP)
MOVL CX, 52 (SP)
MOVL R8, 56 (SP)
MOVL AX, 60 (SP)
CMPQ R9,$256
JB BYTESBETWEEN1AND255
MOVOA 48(SP),X0
PSHUFL $0X55,X0,X1
PSHUFL $0XAA,X0,X2
PSHUFL $0XFF,X0,X3
PSHUFL $0X00,X0,X0
MOVOA X1,64(SP)
MOVOA X2,80(SP)
MOVOA X3,96(SP)
MOVOA X0,112(SP)
MOVOA 0(SP),X0
PSHUFL $0XAA,X0,X1
PSHUFL $0XFF,X0,X2
PSHUFL $0X00,X0,X3
PSHUFL $0X55,X0,X0
MOVOA X1,128(SP)
MOVOA X2,144(SP)
MOVOA X3,160(SP)
MOVOA X0,176(SP)
MOVOA 16(SP),X0
PSHUFL $0XFF,X0,X1
PSHUFL $0X55,X0,X2
PSHUFL $0XAA,X0,X0
MOVOA X1,192(SP)
MOVOA X2,208(SP)
MOVOA X0,224(SP)
MOVOA 32(SP),X0
PSHUFL $0X00,X0,X1
PSHUFL $0XAA,X0,X2
PSHUFL $0XFF,X0,X0
MOVOA X1,240(SP)
MOVOA X2,256(SP)
MOVOA X0,272(SP)
BYTESATLEAST256:
MOVL 16(SP),DX
MOVL 36 (SP),CX
MOVL DX,288(SP)
MOVL CX,304(SP)
SHLQ $32,CX
ADDQ CX,DX
ADDQ $1,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 292 (SP)
MOVL CX, 308 (SP)
ADDQ $1,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 296 (SP)
MOVL CX, 312 (SP)
ADDQ $1,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 300 (SP)
MOVL CX, 316 (SP)
ADDQ $1,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX,16(SP)
MOVL CX, 36 (SP)
MOVQ R9,352(SP)
MOVQ $20,DX
MOVOA 64(SP),X0
MOVOA 80(SP),X1
MOVOA 96(SP),X2
MOVOA 256(SP),X3
MOVOA 272(SP),X4
MOVOA 128(SP),X5
MOVOA 144(SP),X6
MOVOA 176(SP),X7
MOVOA 192(SP),X8
MOVOA 208(SP),X9
MOVOA 224(SP),X10
MOVOA 304(SP),X11
MOVOA 112(SP),X12
MOVOA 160(SP),X13
MOVOA 240(SP),X14
MOVOA 288(SP),X15
MAINLOOP1:
MOVOA X1,320(SP)
MOVOA X2,336(SP)
MOVOA X13,X1
PADDL X12,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X14
PSRLL $25,X2
PXOR X2,X14
MOVOA X7,X1
PADDL X0,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X11
PSRLL $25,X2
PXOR X2,X11
MOVOA X12,X1
PADDL X14,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X15
PSRLL $23,X2
PXOR X2,X15
MOVOA X0,X1
PADDL X11,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X9
PSRLL $23,X2
PXOR X2,X9
MOVOA X14,X1
PADDL X15,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X13
PSRLL $19,X2
PXOR X2,X13
MOVOA X11,X1
PADDL X9,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X7
PSRLL $19,X2
PXOR X2,X7
MOVOA X15,X1
PADDL X13,X1
MOVOA X1,X2
PSLLL $18,X1
PXOR X1,X12
PSRLL $14,X2
PXOR X2,X12
MOVOA 320(SP),X1
MOVOA X12,320(SP)
MOVOA X9,X2
PADDL X7,X2
MOVOA X2,X12
PSLLL $18,X2
PXOR X2,X0
PSRLL $14,X12
PXOR X12,X0
MOVOA X5,X2
PADDL X1,X2
MOVOA X2,X12
PSLLL $7,X2
PXOR X2,X3
PSRLL $25,X12
PXOR X12,X3
MOVOA 336(SP),X2
MOVOA X0,336(SP)
MOVOA X6,X0
PADDL X2,X0
MOVOA X0,X12
PSLLL $7,X0
PXOR X0,X4
PSRLL $25,X12
PXOR X12,X4
MOVOA X1,X0
PADDL X3,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X10
PSRLL $23,X12
PXOR X12,X10
MOVOA X2,X0
PADDL X4,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X8
PSRLL $23,X12
PXOR X12,X8
MOVOA X3,X0
PADDL X10,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X5
PSRLL $19,X12
PXOR X12,X5
MOVOA X4,X0
PADDL X8,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X6
PSRLL $19,X12
PXOR X12,X6
MOVOA X10,X0
PADDL X5,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X1
PSRLL $14,X12
PXOR X12,X1
MOVOA 320(SP),X0
MOVOA X1,320(SP)
MOVOA X4,X1
PADDL X0,X1
MOVOA X1,X12
PSLLL $7,X1
PXOR X1,X7
PSRLL $25,X12
PXOR X12,X7
MOVOA X8,X1
PADDL X6,X1
MOVOA X1,X12
PSLLL $18,X1
PXOR X1,X2
PSRLL $14,X12
PXOR X12,X2
MOVOA 336(SP),X12
MOVOA X2,336(SP)
MOVOA X14,X1
PADDL X12,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X5
PSRLL $25,X2
PXOR X2,X5
MOVOA X0,X1
PADDL X7,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X10
PSRLL $23,X2
PXOR X2,X10
MOVOA X12,X1
PADDL X5,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X8
PSRLL $23,X2
PXOR X2,X8
MOVOA X7,X1
PADDL X10,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X4
PSRLL $19,X2
PXOR X2,X4
MOVOA X5,X1
PADDL X8,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X14
PSRLL $19,X2
PXOR X2,X14
MOVOA X10,X1
PADDL X4,X1
MOVOA X1,X2
PSLLL $18,X1
PXOR X1,X0
PSRLL $14,X2
PXOR X2,X0
MOVOA 320(SP),X1
MOVOA X0,320(SP)
MOVOA X8,X0
PADDL X14,X0
MOVOA X0,X2
PSLLL $18,X0
PXOR X0,X12
PSRLL $14,X2
PXOR X2,X12
MOVOA X11,X0
PADDL X1,X0
MOVOA X0,X2
PSLLL $7,X0
PXOR X0,X6
PSRLL $25,X2
PXOR X2,X6
MOVOA 336(SP),X2
MOVOA X12,336(SP)
MOVOA X3,X0
PADDL X2,X0
MOVOA X0,X12
PSLLL $7,X0
PXOR X0,X13
PSRLL $25,X12
PXOR X12,X13
MOVOA X1,X0
PADDL X6,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X15
PSRLL $23,X12
PXOR X12,X15
MOVOA X2,X0
PADDL X13,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X9
PSRLL $23,X12
PXOR X12,X9
MOVOA X6,X0
PADDL X15,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X11
PSRLL $19,X12
PXOR X12,X11
MOVOA X13,X0
PADDL X9,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X3
PSRLL $19,X12
PXOR X12,X3
MOVOA X15,X0
PADDL X11,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X1
PSRLL $14,X12
PXOR X12,X1
MOVOA X9,X0
PADDL X3,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X2
PSRLL $14,X12
PXOR X12,X2
MOVOA 320(SP),X12
MOVOA 336(SP),X0
SUBQ $2,DX
JA MAINLOOP1
PADDL 112(SP),X12
PADDL 176(SP),X7
PADDL 224(SP),X10
PADDL 272(SP),X4
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 0(SI),DX
XORL 4(SI),CX
XORL 8(SI),R8
XORL 12(SI),R9
MOVL DX,0(DI)
MOVL CX,4(DI)
MOVL R8,8(DI)
MOVL R9,12(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 64(SI),DX
XORL 68(SI),CX
XORL 72(SI),R8
XORL 76(SI),R9
MOVL DX,64(DI)
MOVL CX,68(DI)
MOVL R8,72(DI)
MOVL R9,76(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 128(SI),DX
XORL 132(SI),CX
XORL 136(SI),R8
XORL 140(SI),R9
MOVL DX,128(DI)
MOVL CX,132(DI)
MOVL R8,136(DI)
MOVL R9,140(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
XORL 192(SI),DX
XORL 196(SI),CX
XORL 200(SI),R8
XORL 204(SI),R9
MOVL DX,192(DI)
MOVL CX,196(DI)
MOVL R8,200(DI)
MOVL R9,204(DI)
PADDL 240(SP),X14
PADDL 64(SP),X0
PADDL 128(SP),X5
PADDL 192(SP),X8
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 16(SI),DX
XORL 20(SI),CX
XORL 24(SI),R8
XORL 28(SI),R9
MOVL DX,16(DI)
MOVL CX,20(DI)
MOVL R8,24(DI)
MOVL R9,28(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 80(SI),DX
XORL 84(SI),CX
XORL 88(SI),R8
XORL 92(SI),R9
MOVL DX,80(DI)
MOVL CX,84(DI)
MOVL R8,88(DI)
MOVL R9,92(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 144(SI),DX
XORL 148(SI),CX
XORL 152(SI),R8
XORL 156(SI),R9
MOVL DX,144(DI)
MOVL CX,148(DI)
MOVL R8,152(DI)
MOVL R9,156(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
XORL 208(SI),DX
XORL 212(SI),CX
XORL 216(SI),R8
XORL 220(SI),R9
MOVL DX,208(DI)
MOVL CX,212(DI)
MOVL R8,216(DI)
MOVL R9,220(DI)
PADDL 288(SP),X15
PADDL 304(SP),X11
PADDL 80(SP),X1
PADDL 144(SP),X6
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 32(SI),DX
XORL 36(SI),CX
XORL 40(SI),R8
XORL 44(SI),R9
MOVL DX,32(DI)
MOVL CX,36(DI)
MOVL R8,40(DI)
MOVL R9,44(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 96(SI),DX
XORL 100(SI),CX
XORL 104(SI),R8
XORL 108(SI),R9
MOVL DX,96(DI)
MOVL CX,100(DI)
MOVL R8,104(DI)
MOVL R9,108(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 160(SI),DX
XORL 164(SI),CX
XORL 168(SI),R8
XORL 172(SI),R9
MOVL DX,160(DI)
MOVL CX,164(DI)
MOVL R8,168(DI)
MOVL R9,172(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
XORL 224(SI),DX
XORL 228(SI),CX
XORL 232(SI),R8
XORL 236(SI),R9
MOVL DX,224(DI)
MOVL CX,228(DI)
MOVL R8,232(DI)
MOVL R9,236(DI)
PADDL 160(SP),X13
PADDL 208(SP),X9
PADDL 256(SP),X3
PADDL 96(SP),X2
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 48(SI),DX
XORL 52(SI),CX
XORL 56(SI),R8
XORL 60(SI),R9
MOVL DX,48(DI)
MOVL CX,52(DI)
MOVL R8,56(DI)
MOVL R9,60(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 112(SI),DX
XORL 116(SI),CX
XORL 120(SI),R8
XORL 124(SI),R9
MOVL DX,112(DI)
MOVL CX,116(DI)
MOVL R8,120(DI)
MOVL R9,124(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 176(SI),DX
XORL 180(SI),CX
XORL 184(SI),R8
XORL 188(SI),R9
MOVL DX,176(DI)
MOVL CX,180(DI)
MOVL R8,184(DI)
MOVL R9,188(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
XORL 240(SI),DX
XORL 244(SI),CX
XORL 248(SI),R8
XORL 252(SI),R9
MOVL DX,240(DI)
MOVL CX,244(DI)
MOVL R8,248(DI)
MOVL R9,252(DI)
MOVQ 352(SP),R9
SUBQ $256,R9
ADDQ $256,SI
ADDQ $256,DI
CMPQ R9,$256
JAE BYTESATLEAST256
CMPQ R9,$0
JBE DONE
BYTESBETWEEN1AND255:
CMPQ R9,$64
JAE NOCOPY
MOVQ DI,DX
LEAQ 360(SP),DI
MOVQ R9,CX
REP; MOVSB
LEAQ 360(SP),DI
LEAQ 360(SP),SI
NOCOPY:
MOVQ R9,352(SP)
MOVOA 48(SP),X0
MOVOA 0(SP),X1
MOVOA 16(SP),X2
MOVOA 32(SP),X3
MOVOA X1,X4
MOVQ $20,CX
MAINLOOP2:
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X3
PXOR X6,X3
PADDL X3,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X3,X3
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X1
PSHUFL $0X4E,X2,X2
PXOR X6,X1
PADDL X1,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X1,X1
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X1
PXOR X6,X1
PADDL X1,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X1,X1
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X3
PSHUFL $0X4E,X2,X2
PXOR X6,X3
PADDL X3,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X3,X3
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X3
PXOR X6,X3
PADDL X3,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X3,X3
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X1
PSHUFL $0X4E,X2,X2
PXOR X6,X1
PADDL X1,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X1,X1
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X1
PXOR X6,X1
PADDL X1,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X1,X1
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X3
PSHUFL $0X4E,X2,X2
PXOR X6,X3
SUBQ $4,CX
PADDL X3,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $18,X5
PXOR X7,X7
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X3,X3
PXOR X6,X0
JA MAINLOOP2
PADDL 48(SP),X0
PADDL 0(SP),X1
PADDL 16(SP),X2
PADDL 32(SP),X3
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 0(SI),CX
XORL 48(SI),R8
XORL 32(SI),R9
XORL 16(SI),AX
MOVL CX,0(DI)
MOVL R8,48(DI)
MOVL R9,32(DI)
MOVL AX,16(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 20(SI),CX
XORL 4(SI),R8
XORL 52(SI),R9
XORL 36(SI),AX
MOVL CX,20(DI)
MOVL R8,4(DI)
MOVL R9,52(DI)
MOVL AX,36(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 40(SI),CX
XORL 24(SI),R8
XORL 8(SI),R9
XORL 56(SI),AX
MOVL CX,40(DI)
MOVL R8,24(DI)
MOVL R9,8(DI)
MOVL AX,56(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
XORL 60(SI),CX
XORL 44(SI),R8
XORL 28(SI),R9
XORL 12(SI),AX
MOVL CX,60(DI)
MOVL R8,44(DI)
MOVL R9,28(DI)
MOVL AX,12(DI)
MOVQ 352(SP),R9
MOVL 16(SP),CX
MOVL 36 (SP),R8
ADDQ $1,CX
SHLQ $32,R8
ADDQ R8,CX
MOVQ CX,R8
SHRQ $32,R8
MOVL CX,16(SP)
MOVL R8, 36 (SP)
CMPQ R9,$64
JA BYTESATLEAST65
JAE BYTESATLEAST64
MOVQ DI,SI
MOVQ DX,DI
MOVQ R9,CX
REP; MOVSB
BYTESATLEAST64:
DONE:
MOVQ R12,SP
RET
BYTESATLEAST65:
SUBQ $64,R9
ADDQ $64,DI
ADDQ $64,SI
JMP BYTESBETWEEN1AND255

View File

@@ -0,0 +1,31 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!appengine,!gccgo
package salsa
import (
"bytes"
"testing"
)
func TestCounterOverflow(t *testing.T) {
in := make([]byte, 4096)
key := &[32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2}
for n, counter := range []*[16]byte{
&[16]byte{0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0}, // zero counter
&[16]byte{0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff}, // counter about to overflow 32 bits
&[16]byte{0, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 0xff, 0xff, 0xff, 0xff}, // counter above 32 bits
} {
out := make([]byte, 4096)
XORKeyStream(out, in, counter, key)
outGeneric := make([]byte, 4096)
genericXORKeyStream(outGeneric, in, counter, key)
if !bytes.Equal(out, outGeneric) {
t.Errorf("%d: assembly and go implementations disagree", n)
}
}
}

View File

@@ -0,0 +1,14 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64 appengine gccgo
package salsa
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out must overlap entirely or not at all. Counter
// contains the raw salsa20 counter bytes (both nonce and block counter).
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
genericXORKeyStream(out, in, counter, key)
}

View File

@@ -2,8 +2,6 @@
// 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 appengine gccgo
package salsa package salsa
const rounds = 20 const rounds = 20
@@ -202,10 +200,9 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
out[63] = byte(x15 >> 24) out[63] = byte(x15 >> 24)
} }
// XORKeyStream crypts bytes from in to out using the given key and counters. // genericXORKeyStream is the generic implementation of XORKeyStream to be used
// In and out must overlap entirely or not at all. Counter // when no assembly implementation is available.
// contains the raw salsa20 counter bytes (both nonce and block counter). func genericXORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
var block [64]byte var block [64]byte
var counterCopy [16]byte var counterCopy [16]byte
copy(counterCopy[:], counter[:]) copy(counterCopy[:], counter[:])

View File

@@ -10,6 +10,7 @@ package scrypt // import "golang.org/x/crypto/scrypt"
import ( import (
"crypto/sha256" "crypto/sha256"
"errors" "errors"
"math/bits"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
) )
@@ -29,7 +30,7 @@ func blockXOR(dst, src []uint32, n int) {
} }
// salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in, // salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in,
// and puts the result into both both tmp and out. // and puts the result into both tmp and out.
func salsaXOR(tmp *[16]uint32, in, out []uint32) { func salsaXOR(tmp *[16]uint32, in, out []uint32) {
w0 := tmp[0] ^ in[0] w0 := tmp[0] ^ in[0]
w1 := tmp[1] ^ in[1] w1 := tmp[1] ^ in[1]
@@ -52,77 +53,45 @@ func salsaXOR(tmp *[16]uint32, in, out []uint32) {
x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15 x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15
for i := 0; i < 8; i += 2 { for i := 0; i < 8; i += 2 {
u := x0 + x12 x4 ^= bits.RotateLeft32(x0+x12, 7)
x4 ^= u<<7 | u>>(32-7) x8 ^= bits.RotateLeft32(x4+x0, 9)
u = x4 + x0 x12 ^= bits.RotateLeft32(x8+x4, 13)
x8 ^= u<<9 | u>>(32-9) x0 ^= bits.RotateLeft32(x12+x8, 18)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
u = x5 + x1 x9 ^= bits.RotateLeft32(x5+x1, 7)
x9 ^= u<<7 | u>>(32-7) x13 ^= bits.RotateLeft32(x9+x5, 9)
u = x9 + x5 x1 ^= bits.RotateLeft32(x13+x9, 13)
x13 ^= u<<9 | u>>(32-9) x5 ^= bits.RotateLeft32(x1+x13, 18)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
u = x10 + x6 x14 ^= bits.RotateLeft32(x10+x6, 7)
x14 ^= u<<7 | u>>(32-7) x2 ^= bits.RotateLeft32(x14+x10, 9)
u = x14 + x10 x6 ^= bits.RotateLeft32(x2+x14, 13)
x2 ^= u<<9 | u>>(32-9) x10 ^= bits.RotateLeft32(x6+x2, 18)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
u = x15 + x11 x3 ^= bits.RotateLeft32(x15+x11, 7)
x3 ^= u<<7 | u>>(32-7) x7 ^= bits.RotateLeft32(x3+x15, 9)
u = x3 + x15 x11 ^= bits.RotateLeft32(x7+x3, 13)
x7 ^= u<<9 | u>>(32-9) x15 ^= bits.RotateLeft32(x11+x7, 18)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
u = x0 + x3 x1 ^= bits.RotateLeft32(x0+x3, 7)
x1 ^= u<<7 | u>>(32-7) x2 ^= bits.RotateLeft32(x1+x0, 9)
u = x1 + x0 x3 ^= bits.RotateLeft32(x2+x1, 13)
x2 ^= u<<9 | u>>(32-9) x0 ^= bits.RotateLeft32(x3+x2, 18)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
u = x5 + x4 x6 ^= bits.RotateLeft32(x5+x4, 7)
x6 ^= u<<7 | u>>(32-7) x7 ^= bits.RotateLeft32(x6+x5, 9)
u = x6 + x5 x4 ^= bits.RotateLeft32(x7+x6, 13)
x7 ^= u<<9 | u>>(32-9) x5 ^= bits.RotateLeft32(x4+x7, 18)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
u = x10 + x9 x11 ^= bits.RotateLeft32(x10+x9, 7)
x11 ^= u<<7 | u>>(32-7) x8 ^= bits.RotateLeft32(x11+x10, 9)
u = x11 + x10 x9 ^= bits.RotateLeft32(x8+x11, 13)
x8 ^= u<<9 | u>>(32-9) x10 ^= bits.RotateLeft32(x9+x8, 18)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
u = x15 + x14 x12 ^= bits.RotateLeft32(x15+x14, 7)
x12 ^= u<<7 | u>>(32-7) x13 ^= bits.RotateLeft32(x12+x15, 9)
u = x12 + x15 x14 ^= bits.RotateLeft32(x13+x12, 13)
x13 ^= u<<9 | u>>(32-9) x15 ^= bits.RotateLeft32(x14+x13, 18)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
} }
x0 += w0 x0 += w0
x1 += w1 x1 += w1

View File

@@ -43,7 +43,7 @@
// is then "full" and the permutation is applied to "empty" it. This process is // is then "full" and the permutation is applied to "empty" it. This process is
// repeated until all the input has been "absorbed". The input is then padded. // repeated until all the input has been "absorbed". The input is then padded.
// The digest is "squeezed" from the sponge in the same way, except that output // The digest is "squeezed" from the sponge in the same way, except that output
// output is copied out instead of input being XORed in. // is copied out instead of input being XORed in.
// //
// A sponge is parameterized by its generic security strength, which is equal // A sponge is parameterized by its generic security strength, which is equal
// to half its capacity; capacity + rate is equal to the permutation's width. // to half its capacity; capacity + rate is equal to the permutation's width.

View File

@@ -58,6 +58,12 @@ func New512() hash.Hash {
// that uses non-standard padding. All other users should use New256 instead. // that uses non-standard padding. All other users should use New256 instead.
func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} } func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} }
// NewLegacyKeccak512 creates a new Keccak-512 hash.
//
// Only use this function if you require compatibility with an existing cryptosystem
// that uses non-standard padding. All other users should use New512 instead.
func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x01} }
// Sum224 returns the SHA3-224 digest of the data. // Sum224 returns the SHA3-224 digest of the data.
func Sum224(data []byte) (digest [28]byte) { func Sum224(data []byte) (digest [28]byte) {
h := New224() h := New224()

Some files were not shown because too many files have changed in this diff Show More